1 /*-------------------------------------------------------------------------
4 * test using large objects with libpq using 64-bit APIs
6 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/test/examples/testlo64.c
13 *-------------------------------------------------------------------------
18 #include <sys/types.h>
24 #include "libpq/libpq-fs.h"
30 * import file "in_filename" into database as large object "lobjOid"
34 importFile(PGconn
*conn
, char *filename
)
44 * open the file to be read in
46 fd
= open(filename
, O_RDONLY
, 0666);
49 fprintf(stderr
, "cannot open unix file\"%s\"\n", filename
);
53 * create the large object
55 lobjId
= lo_creat(conn
, INV_READ
| INV_WRITE
);
57 fprintf(stderr
, "cannot create large object");
59 lobj_fd
= lo_open(conn
, lobjId
, INV_WRITE
);
62 * read in from the Unix file and write to the inversion file
64 while ((nbytes
= read(fd
, buf
, BUFSIZE
)) > 0)
66 tmp
= lo_write(conn
, lobj_fd
, buf
, nbytes
);
68 fprintf(stderr
, "error while reading \"%s\"", filename
);
72 lo_close(conn
, lobj_fd
);
78 pickout(PGconn
*conn
, Oid lobjId
, pg_int64 start
, int len
)
85 lobj_fd
= lo_open(conn
, lobjId
, INV_READ
);
87 fprintf(stderr
, "cannot open large object %u", lobjId
);
89 if (lo_lseek64(conn
, lobj_fd
, start
, SEEK_SET
) < 0)
90 fprintf(stderr
, "error in lo_lseek64: %s", PQerrorMessage(conn
));
92 if (lo_tell64(conn
, lobj_fd
) != start
)
93 fprintf(stderr
, "error in lo_tell64: %s", PQerrorMessage(conn
));
95 buf
= malloc(len
+ 1);
98 while (len
- nread
> 0)
100 nbytes
= lo_read(conn
, lobj_fd
, buf
, len
- nread
);
102 fprintf(stderr
, ">>> %s", buf
);
105 break; /* no more data? */
108 fprintf(stderr
, "\n");
109 lo_close(conn
, lobj_fd
);
113 overwrite(PGconn
*conn
, Oid lobjId
, pg_int64 start
, int len
)
121 lobj_fd
= lo_open(conn
, lobjId
, INV_WRITE
);
123 fprintf(stderr
, "cannot open large object %u", lobjId
);
125 if (lo_lseek64(conn
, lobj_fd
, start
, SEEK_SET
) < 0)
126 fprintf(stderr
, "error in lo_lseek64: %s", PQerrorMessage(conn
));
128 buf
= malloc(len
+ 1);
130 for (i
= 0; i
< len
; i
++)
135 while (len
- nwritten
> 0)
137 nbytes
= lo_write(conn
, lobj_fd
, buf
+ nwritten
, len
- nwritten
);
141 fprintf(stderr
, "\nWRITE FAILED!\n");
146 fprintf(stderr
, "\n");
147 lo_close(conn
, lobj_fd
);
151 my_truncate(PGconn
*conn
, Oid lobjId
, pg_int64 len
)
155 lobj_fd
= lo_open(conn
, lobjId
, INV_READ
| INV_WRITE
);
157 fprintf(stderr
, "cannot open large object %u", lobjId
);
159 if (lo_truncate64(conn
, lobj_fd
, len
) < 0)
160 fprintf(stderr
, "error in lo_truncate64: %s", PQerrorMessage(conn
));
162 lo_close(conn
, lobj_fd
);
168 * export large object "lobjOid" to file "out_filename"
172 exportFile(PGconn
*conn
, Oid lobjId
, char *filename
)
181 * open the large object
183 lobj_fd
= lo_open(conn
, lobjId
, INV_READ
);
185 fprintf(stderr
, "cannot open large object %u", lobjId
);
188 * open the file to be written to
190 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
, 0666);
193 fprintf(stderr
, "cannot open unix file\"%s\"",
198 * read in from the inversion file and write to the Unix file
200 while ((nbytes
= lo_read(conn
, lobj_fd
, buf
, BUFSIZE
)) > 0)
202 tmp
= write(fd
, buf
, nbytes
);
205 fprintf(stderr
, "error while writing \"%s\"",
210 lo_close(conn
, lobj_fd
);
215 exit_nicely(PGconn
*conn
)
222 main(int argc
, char **argv
)
234 fprintf(stderr
, "Usage: %s database_name in_filename out_filename out_filename2\n",
240 in_filename
= argv
[2];
241 out_filename
= argv
[3];
242 out_filename2
= argv
[4];
245 * set up the connection
247 conn
= PQsetdb(NULL
, NULL
, NULL
, NULL
, database
);
249 /* check to see that the backend connection was successfully made */
250 if (PQstatus(conn
) != CONNECTION_OK
)
252 fprintf(stderr
, "%s", PQerrorMessage(conn
));
256 /* Set always-secure search path, so malicious users can't take control. */
258 "SELECT pg_catalog.set_config('search_path', '', false)");
259 if (PQresultStatus(res
) != PGRES_TUPLES_OK
)
261 fprintf(stderr
, "SET failed: %s", PQerrorMessage(conn
));
267 res
= PQexec(conn
, "begin");
269 printf("importing file \"%s\" ...\n", in_filename
);
270 /* lobjOid = importFile(conn, in_filename); */
271 lobjOid
= lo_import(conn
, in_filename
);
273 fprintf(stderr
, "%s\n", PQerrorMessage(conn
));
276 printf("\tas large object %u.\n", lobjOid
);
278 printf("picking out bytes 4294967000-4294968000 of the large object\n");
279 pickout(conn
, lobjOid
, 4294967000U, 1000);
281 printf("overwriting bytes 4294967000-4294968000 of the large object with X's\n");
282 overwrite(conn
, lobjOid
, 4294967000U, 1000);
284 printf("exporting large object to file \"%s\" ...\n", out_filename
);
285 /* exportFile(conn, lobjOid, out_filename); */
286 if (lo_export(conn
, lobjOid
, out_filename
) < 0)
287 fprintf(stderr
, "%s\n", PQerrorMessage(conn
));
289 printf("truncating to 3294968000 bytes\n");
290 my_truncate(conn
, lobjOid
, 3294968000U);
292 printf("exporting truncated large object to file \"%s\" ...\n", out_filename2
);
293 if (lo_export(conn
, lobjOid
, out_filename2
) < 0)
294 fprintf(stderr
, "%s\n", PQerrorMessage(conn
));
297 res
= PQexec(conn
, "end");