Header And Logo

PostgreSQL
| The world's most advanced open source database.

testlo64.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * testlo64.c
00004  *    test using large objects with libpq using 64-bit APIs
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/test/examples/testlo64.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <fcntl.h>
00021 #include <unistd.h>
00022 
00023 #include "libpq-fe.h"
00024 #include "libpq/libpq-fs.h"
00025 
00026 #define BUFSIZE         1024
00027 
00028 /*
00029  * importFile -
00030  *    import file "in_filename" into database as large object "lobjOid"
00031  *
00032  */
00033 static Oid
00034 importFile(PGconn *conn, char *filename)
00035 {
00036     Oid         lobjId;
00037     int         lobj_fd;
00038     char        buf[BUFSIZE];
00039     int         nbytes,
00040                 tmp;
00041     int         fd;
00042 
00043     /*
00044      * open the file to be read in
00045      */
00046     fd = open(filename, O_RDONLY, 0666);
00047     if (fd < 0)
00048     {                           /* error */
00049         fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
00050     }
00051 
00052     /*
00053      * create the large object
00054      */
00055     lobjId = lo_creat(conn, INV_READ | INV_WRITE);
00056     if (lobjId == 0)
00057         fprintf(stderr, "cannot create large object");
00058 
00059     lobj_fd = lo_open(conn, lobjId, INV_WRITE);
00060 
00061     /*
00062      * read in from the Unix file and write to the inversion file
00063      */
00064     while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
00065     {
00066         tmp = lo_write(conn, lobj_fd, buf, nbytes);
00067         if (tmp < nbytes)
00068             fprintf(stderr, "error while reading \"%s\"", filename);
00069     }
00070 
00071     close(fd);
00072     lo_close(conn, lobj_fd);
00073 
00074     return lobjId;
00075 }
00076 
00077 static void
00078 pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len)
00079 {
00080     int         lobj_fd;
00081     char       *buf;
00082     int         nbytes;
00083     int         nread;
00084 
00085     lobj_fd = lo_open(conn, lobjId, INV_READ);
00086     if (lobj_fd < 0)
00087         fprintf(stderr, "cannot open large object %u", lobjId);
00088 
00089     if (lo_lseek64(conn, lobj_fd, start, SEEK_SET) < 0)
00090         fprintf(stderr, "error in lo_lseek64: %s", PQerrorMessage(conn));
00091 
00092     if (lo_tell64(conn, lobj_fd) != start)
00093         fprintf(stderr, "error in lo_tell64: %s", PQerrorMessage(conn));
00094 
00095     buf = malloc(len + 1);
00096 
00097     nread = 0;
00098     while (len - nread > 0)
00099     {
00100         nbytes = lo_read(conn, lobj_fd, buf, len - nread);
00101         buf[nbytes] = '\0';
00102         fprintf(stderr, ">>> %s", buf);
00103         nread += nbytes;
00104         if (nbytes <= 0)
00105             break;              /* no more data? */
00106     }
00107     free(buf);
00108     fprintf(stderr, "\n");
00109     lo_close(conn, lobj_fd);
00110 }
00111 
00112 static void
00113 overwrite(PGconn *conn, Oid lobjId, pg_int64 start, int len)
00114 {
00115     int         lobj_fd;
00116     char       *buf;
00117     int         nbytes;
00118     int         nwritten;
00119     int         i;
00120 
00121     lobj_fd = lo_open(conn, lobjId, INV_WRITE);
00122     if (lobj_fd < 0)
00123         fprintf(stderr, "cannot open large object %u", lobjId);
00124 
00125     if (lo_lseek64(conn, lobj_fd, start, SEEK_SET) < 0)
00126         fprintf(stderr, "error in lo_lseek64: %s", PQerrorMessage(conn));
00127 
00128     buf = malloc(len + 1);
00129 
00130     for (i = 0; i < len; i++)
00131         buf[i] = 'X';
00132     buf[i] = '\0';
00133 
00134     nwritten = 0;
00135     while (len - nwritten > 0)
00136     {
00137         nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
00138         nwritten += nbytes;
00139         if (nbytes <= 0)
00140         {
00141             fprintf(stderr, "\nWRITE FAILED!\n");
00142             break;
00143         }
00144     }
00145     free(buf);
00146     fprintf(stderr, "\n");
00147     lo_close(conn, lobj_fd);
00148 }
00149 
00150 static void
00151 my_truncate(PGconn *conn, Oid lobjId, pg_int64 len)
00152 {
00153     int         lobj_fd;
00154 
00155     lobj_fd = lo_open(conn, lobjId, INV_READ | INV_WRITE);
00156     if (lobj_fd < 0)
00157         fprintf(stderr, "cannot open large object %u", lobjId);
00158 
00159     if (lo_truncate64(conn, lobj_fd, len) < 0)
00160         fprintf(stderr, "error in lo_truncate64: %s", PQerrorMessage(conn));
00161 
00162     lo_close(conn, lobj_fd);
00163 }
00164 
00165 
00166 /*
00167  * exportFile -
00168  *    export large object "lobjOid" to file "out_filename"
00169  *
00170  */
00171 static void
00172 exportFile(PGconn *conn, Oid lobjId, char *filename)
00173 {
00174     int         lobj_fd;
00175     char        buf[BUFSIZE];
00176     int         nbytes,
00177                 tmp;
00178     int         fd;
00179 
00180     /*
00181      * open the large object
00182      */
00183     lobj_fd = lo_open(conn, lobjId, INV_READ);
00184     if (lobj_fd < 0)
00185         fprintf(stderr, "cannot open large object %u", lobjId);
00186 
00187     /*
00188      * open the file to be written to
00189      */
00190     fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
00191     if (fd < 0)
00192     {                           /* error */
00193         fprintf(stderr, "cannot open unix file\"%s\"",
00194                 filename);
00195     }
00196 
00197     /*
00198      * read in from the inversion file and write to the Unix file
00199      */
00200     while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
00201     {
00202         tmp = write(fd, buf, nbytes);
00203         if (tmp < nbytes)
00204         {
00205             fprintf(stderr, "error while writing \"%s\"",
00206                     filename);
00207         }
00208     }
00209 
00210     lo_close(conn, lobj_fd);
00211     close(fd);
00212 
00213     return;
00214 }
00215 
00216 static void
00217 exit_nicely(PGconn *conn)
00218 {
00219     PQfinish(conn);
00220     exit(1);
00221 }
00222 
00223 int
00224 main(int argc, char **argv)
00225 {
00226     char       *in_filename,
00227                *out_filename,
00228                *out_filename2;
00229     char       *database;
00230     Oid         lobjOid;
00231     PGconn     *conn;
00232     PGresult   *res;
00233 
00234     if (argc != 5)
00235     {
00236         fprintf(stderr, "Usage: %s database_name in_filename out_filename out_filename2\n",
00237                 argv[0]);
00238         exit(1);
00239     }
00240 
00241     database = argv[1];
00242     in_filename = argv[2];
00243     out_filename = argv[3];
00244     out_filename2 = argv[4];
00245 
00246     /*
00247      * set up the connection
00248      */
00249     conn = PQsetdb(NULL, NULL, NULL, NULL, database);
00250 
00251     /* check to see that the backend connection was successfully made */
00252     if (PQstatus(conn) != CONNECTION_OK)
00253     {
00254         fprintf(stderr, "Connection to database failed: %s",
00255                 PQerrorMessage(conn));
00256         exit_nicely(conn);
00257     }
00258 
00259     res = PQexec(conn, "begin");
00260     PQclear(res);
00261     printf("importing file \"%s\" ...\n", in_filename);
00262 /*  lobjOid = importFile(conn, in_filename); */
00263     lobjOid = lo_import(conn, in_filename);
00264     if (lobjOid == 0)
00265         fprintf(stderr, "%s\n", PQerrorMessage(conn));
00266     else
00267     {
00268         printf("\tas large object %u.\n", lobjOid);
00269 
00270         printf("picking out bytes 4294967000-4294968000 of the large object\n");
00271         pickout(conn, lobjOid, 4294967000U, 1000);
00272 
00273         printf("overwriting bytes 4294967000-4294968000 of the large object with X's\n");
00274         overwrite(conn, lobjOid, 4294967000U, 1000);
00275 
00276         printf("exporting large object to file \"%s\" ...\n", out_filename);
00277 /*      exportFile(conn, lobjOid, out_filename); */
00278         if (lo_export(conn, lobjOid, out_filename) < 0)
00279             fprintf(stderr, "%s\n", PQerrorMessage(conn));
00280 
00281         printf("truncating to 3294968000 bytes\n");
00282         my_truncate(conn, lobjOid, 3294968000U);
00283 
00284         printf("exporting truncated large object to file \"%s\" ...\n", out_filename2);
00285         if (lo_export(conn, lobjOid, out_filename2) < 0)
00286             fprintf(stderr, "%s\n", PQerrorMessage(conn));
00287     }
00288 
00289     res = PQexec(conn, "end");
00290     PQclear(res);
00291     PQfinish(conn);
00292     return 0;
00293 }