O Exemplo 28-1 é um programa modelo, que mostra como a interface de objeto grande da biblioteca libpq pode ser utilizada. Partes do programa foram transformadas em comentário, mas foram deixadas no código fonte para benefício do leitor. Este programa também pode ser encontrado em src/test/examples/testlo.c na distribuição do código fonte.
Exemplo 28-1. Programa de exemplo de objeto grande com libpq
/*------------------------------------------------------------------------- * * testlo.c * teste de utilização de objetos grandes com libpq * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $PostgreSQL: pgsql/src/test/examples/testlo.c,v 1.25 2004/12/31 22:03:58 pgsql Exp $ * *------------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "libpq-fe.h" #include "libpq/libpq-fs.h" #define BUFSIZE 1024 /* * importFile - * importar o arquivo "in_filename" para o banco de dados * como o objeto grande "lobjOid" * */ static Oid importFile(PGconn *conn, char *filename) { Oid lobjId; int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * abrir o arquivo a ser lido */ fd = open(filename, O_RDONLY, 0666); if (fd < 0) { /* erro */ fprintf(stderr, "não foi possível abrir o arquivo Unix\"%s\"\n", filename); } /* * criar o objeto grande */ lobjId = lo_creat(conn, INV_READ | INV_WRITE); if (lobjId == 0) fprintf(stderr, "não foi possível criar o objeto grande"); lobj_fd = lo_open(conn, lobjId, INV_WRITE); /* * ler do arquivo Unix e escrever no arquivo de inversão */ while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { tmp = lo_write(conn, lobj_fd, buf, nbytes); if (tmp < nbytes) fprintf(stderr, "erro durante a leitura de \"%s\"", filename); } close(fd); lo_close(conn, lobj_fd); return lobjId; } static void pickout(PGconn *conn, Oid lobjId, int start, int len) { int lobj_fd; char *buf; int nbytes; int nread; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) fprintf(stderr, "não foi possível abrir o objeto grande %u", lobjId); lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len + 1); nread = 0; while (len - nread > 0) { nbytes = lo_read(conn, lobj_fd, buf, len - nread); buf[nbytes] = '\0'; fprintf(stderr, ">>> %s", buf); nread += nbytes; if (nbytes <= 0) break; /* sem mais dados? */ } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd); } static void overwrite(PGconn *conn, Oid lobjId, int start, int len) { int lobj_fd; char *buf; int nbytes; int nwritten; int i; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) fprintf(stderr, "não foi possível abrir o objeto grande %u", lobjId); lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len + 1); for (i = 0; i < len; i++) buf[i] = 'X'; buf[i] = '\0'; nwritten = 0; while (len - nwritten > 0) { nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); nwritten += nbytes; if (nbytes <= 0) { fprintf(stderr, "\nERRO DE ESCRITA!\n"); break; } } free(buf); fprintf(stderr, "\n"); lo_close(conn, lobj_fd); } /* * exportFile - * exportar o objeto grande "lobjOid" para o arquivo "out_filename" * */ static void exportFile(PGconn *conn, Oid lobjId, char *filename) { int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* * criar um "objeto" inversão */ lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) fprintf(stderr, "não foi possível abrir o objeto grande %u", lobjId); /* * abrir o arquivo a ser escrito */ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (fd < 0) { /* erro */ fprintf(stderr, "não foi possível abrir o arquivo Unix\"%s\"", filename); } /* * ler do arquivo Unix e escrever no arquivo inversão */ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp < nbytes) { fprintf(stderr, "erro ao escrever \"%s\"", filename); } } lo_close(conn, lobj_fd); close(fd); return; } static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } int main(int argc, char **argv) { char *in_filename, *out_filename; char *database; Oid lobjOid; PGconn *conn; PGresult *res; if (argc != 4) { fprintf(stderr, "Utilização: %s nome_do_banco_de_dados \ nome_do_arquivo_de_entrada nome_do_arquivo_de_saída\n", argv[0]); exit(1); } database = argv[1]; in_filename = argv[2]; out_filename = argv[3]; /* * estabelecer a conexão */ conn = PQsetdb(NULL, NULL, NULL, NULL, database); /* verificar se a conexão com o servidor foi bem-sucedida */ if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "A conexão com o banco de dados %s falhou", PQerrorMessage(conn)); exit_nicely(conn); } res = PQexec(conn, "begin"); PQclear(res); printf("importing file \"%s\" ...\n", in_filename); /* lobjOid = importFile(conn, in_filename); */ lobjOid = lo_import(conn, in_filename); if (lobjOid == 0) fprintf(stderr, "%s\n", PQerrorMessage(conn)); else { printf("\tcomo o objeto grande %u.\n", lobjOid); printf("lendo os bytes 1000-2000 do objeto grande\n"); pickout(conn, lobjOid, 1000, 1000); printf("sobrescrevendo os bytes 1000-2000 do objeto grande com X's\n"); overwrite(conn, lobjOid, 1000, 1000); printf("exportando o objeto grande para o arquivo \"%s\" ...\n", out_filename); /* exportFile(conn, lobjOid, out_filename); */ if (!lo_export(conn, lobjOid, out_filename)) fprintf(stderr, "%s\n", PQerrorMessage(conn)); } res = PQexec(conn, "end"); PQclear(res); PQfinish(conn); return 0; }