Update copyright for 2022
[pgsql.git] / src / test / examples / testlo64.c
blob981e29ad783a6618a7acb19a03a9c48502053c08
1 /*-------------------------------------------------------------------------
3 * testlo64.c
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
10 * IDENTIFICATION
11 * src/test/examples/testlo64.c
13 *-------------------------------------------------------------------------
15 #include <stdio.h>
16 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
23 #include "libpq-fe.h"
24 #include "libpq/libpq-fs.h"
26 #define BUFSIZE 1024
29 * importFile -
30 * import file "in_filename" into database as large object "lobjOid"
33 static Oid
34 importFile(PGconn *conn, char *filename)
36 Oid lobjId;
37 int lobj_fd;
38 char buf[BUFSIZE];
39 int nbytes,
40 tmp;
41 int fd;
44 * open the file to be read in
46 fd = open(filename, O_RDONLY, 0666);
47 if (fd < 0)
48 { /* error */
49 fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
53 * create the large object
55 lobjId = lo_creat(conn, INV_READ | INV_WRITE);
56 if (lobjId == 0)
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);
67 if (tmp < nbytes)
68 fprintf(stderr, "error while reading \"%s\"", filename);
71 close(fd);
72 lo_close(conn, lobj_fd);
74 return lobjId;
77 static void
78 pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len)
80 int lobj_fd;
81 char *buf;
82 int nbytes;
83 int nread;
85 lobj_fd = lo_open(conn, lobjId, INV_READ);
86 if (lobj_fd < 0)
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);
97 nread = 0;
98 while (len - nread > 0)
100 nbytes = lo_read(conn, lobj_fd, buf, len - nread);
101 buf[nbytes] = '\0';
102 fprintf(stderr, ">>> %s", buf);
103 nread += nbytes;
104 if (nbytes <= 0)
105 break; /* no more data? */
107 free(buf);
108 fprintf(stderr, "\n");
109 lo_close(conn, lobj_fd);
112 static void
113 overwrite(PGconn *conn, Oid lobjId, pg_int64 start, int len)
115 int lobj_fd;
116 char *buf;
117 int nbytes;
118 int nwritten;
119 int i;
121 lobj_fd = lo_open(conn, lobjId, INV_WRITE);
122 if (lobj_fd < 0)
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++)
131 buf[i] = 'X';
132 buf[i] = '\0';
134 nwritten = 0;
135 while (len - nwritten > 0)
137 nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
138 nwritten += nbytes;
139 if (nbytes <= 0)
141 fprintf(stderr, "\nWRITE FAILED!\n");
142 break;
145 free(buf);
146 fprintf(stderr, "\n");
147 lo_close(conn, lobj_fd);
150 static void
151 my_truncate(PGconn *conn, Oid lobjId, pg_int64 len)
153 int lobj_fd;
155 lobj_fd = lo_open(conn, lobjId, INV_READ | INV_WRITE);
156 if (lobj_fd < 0)
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);
167 * exportFile -
168 * export large object "lobjOid" to file "out_filename"
171 static void
172 exportFile(PGconn *conn, Oid lobjId, char *filename)
174 int lobj_fd;
175 char buf[BUFSIZE];
176 int nbytes,
177 tmp;
178 int fd;
181 * open the large object
183 lobj_fd = lo_open(conn, lobjId, INV_READ);
184 if (lobj_fd < 0)
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);
191 if (fd < 0)
192 { /* error */
193 fprintf(stderr, "cannot open unix file\"%s\"",
194 filename);
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);
203 if (tmp < nbytes)
205 fprintf(stderr, "error while writing \"%s\"",
206 filename);
210 lo_close(conn, lobj_fd);
211 close(fd);
214 static void
215 exit_nicely(PGconn *conn)
217 PQfinish(conn);
218 exit(1);
222 main(int argc, char **argv)
224 char *in_filename,
225 *out_filename,
226 *out_filename2;
227 char *database;
228 Oid lobjOid;
229 PGconn *conn;
230 PGresult *res;
232 if (argc != 5)
234 fprintf(stderr, "Usage: %s database_name in_filename out_filename out_filename2\n",
235 argv[0]);
236 exit(1);
239 database = argv[1];
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));
253 exit_nicely(conn);
256 /* Set always-secure search path, so malicious users can't take control. */
257 res = PQexec(conn,
258 "SELECT pg_catalog.set_config('search_path', '', false)");
259 if (PQresultStatus(res) != PGRES_TUPLES_OK)
261 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
262 PQclear(res);
263 exit_nicely(conn);
265 PQclear(res);
267 res = PQexec(conn, "begin");
268 PQclear(res);
269 printf("importing file \"%s\" ...\n", in_filename);
270 /* lobjOid = importFile(conn, in_filename); */
271 lobjOid = lo_import(conn, in_filename);
272 if (lobjOid == 0)
273 fprintf(stderr, "%s\n", PQerrorMessage(conn));
274 else
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");
298 PQclear(res);
299 PQfinish(conn);
300 return 0;