28.5. Programa exemplo

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;
}
SourceForge.net Logo CSS válido!