PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
testlo64.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * testlo64.c
4 * test using large objects with libpq using 64-bit APIs
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/test/examples/testlo64.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include <stdio.h>
16#include <stdlib.h>
17
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <fcntl.h>
21#include <unistd.h>
22
23#include "libpq-fe.h"
24#include "libpq/libpq-fs.h"
25
26#define BUFSIZE 1024
27
28/*
29 * importFile -
30 * import file "in_filename" into database as large object "lobjOid"
31 *
32 */
33static Oid
35{
36 Oid lobjId;
37 int lobj_fd;
38 char buf[BUFSIZE];
39 int nbytes,
40 tmp;
41 int fd;
42
43 /*
44 * open the file to be read in
45 */
46 fd = open(filename, O_RDONLY, 0666);
47 if (fd < 0)
48 { /* error */
49 fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
50 }
51
52 /*
53 * create the large object
54 */
55 lobjId = lo_creat(conn, INV_READ | INV_WRITE);
56 if (lobjId == 0)
57 fprintf(stderr, "cannot create large object");
58
59 lobj_fd = lo_open(conn, lobjId, INV_WRITE);
60
61 /*
62 * read in from the Unix file and write to the inversion file
63 */
64 while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
65 {
66 tmp = lo_write(conn, lobj_fd, buf, nbytes);
67 if (tmp < nbytes)
68 fprintf(stderr, "error while reading \"%s\"", filename);
69 }
70
71 close(fd);
72 lo_close(conn, lobj_fd);
73
74 return lobjId;
75}
76
77static void
79{
80 int lobj_fd;
81 char *buf;
82 int nbytes;
83 int nread;
84
85 lobj_fd = lo_open(conn, lobjId, INV_READ);
86 if (lobj_fd < 0)
87 fprintf(stderr, "cannot open large object %u", lobjId);
88
89 if (lo_lseek64(conn, lobj_fd, start, SEEK_SET) < 0)
90 fprintf(stderr, "error in lo_lseek64: %s", PQerrorMessage(conn));
91
92 if (lo_tell64(conn, lobj_fd) != start)
93 fprintf(stderr, "error in lo_tell64: %s", PQerrorMessage(conn));
94
95 buf = malloc(len + 1);
96
97 nread = 0;
98 while (len - nread > 0)
99 {
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? */
106 }
107 free(buf);
108 fprintf(stderr, "\n");
109 lo_close(conn, lobj_fd);
110}
111
112static void
114{
115 int lobj_fd;
116 char *buf;
117 int nbytes;
118 int nwritten;
119 int i;
120
121 lobj_fd = lo_open(conn, lobjId, INV_WRITE);
122 if (lobj_fd < 0)
123 fprintf(stderr, "cannot open large object %u", lobjId);
124
125 if (lo_lseek64(conn, lobj_fd, start, SEEK_SET) < 0)
126 fprintf(stderr, "error in lo_lseek64: %s", PQerrorMessage(conn));
127
128 buf = malloc(len + 1);
129
130 for (i = 0; i < len; i++)
131 buf[i] = 'X';
132 buf[i] = '\0';
133
134 nwritten = 0;
135 while (len - nwritten > 0)
136 {
137 nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
138 nwritten += nbytes;
139 if (nbytes <= 0)
140 {
141 fprintf(stderr, "\nWRITE FAILED!\n");
142 break;
143 }
144 }
145 free(buf);
146 fprintf(stderr, "\n");
147 lo_close(conn, lobj_fd);
148}
149
150static void
152{
153 int lobj_fd;
154
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);
158
159 if (lo_truncate64(conn, lobj_fd, len) < 0)
160 fprintf(stderr, "error in lo_truncate64: %s", PQerrorMessage(conn));
161
162 lo_close(conn, lobj_fd);
163}
164
165
166/*
167 * exportFile -
168 * export large object "lobjOid" to file "out_filename"
169 *
170 */
171static void
173{
174 int lobj_fd;
175 char buf[BUFSIZE];
176 int nbytes,
177 tmp;
178 int fd;
179
180 /*
181 * open the large object
182 */
183 lobj_fd = lo_open(conn, lobjId, INV_READ);
184 if (lobj_fd < 0)
185 fprintf(stderr, "cannot open large object %u", lobjId);
186
187 /*
188 * open the file to be written to
189 */
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);
195 }
196
197 /*
198 * read in from the inversion file and write to the Unix file
199 */
200 while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
201 {
202 tmp = write(fd, buf, nbytes);
203 if (tmp < nbytes)
204 {
205 fprintf(stderr, "error while writing \"%s\"",
206 filename);
207 }
208 }
209
210 lo_close(conn, lobj_fd);
211 close(fd);
212}
213
214static void
216{
217 PQfinish(conn);
218 exit(1);
219}
220
221int
222main(int argc, char **argv)
223{
224 char *in_filename,
225 *out_filename,
226 *out_filename2;
227 char *database;
228 Oid lobjOid;
229 PGconn *conn;
230 PGresult *res;
231
232 if (argc != 5)
233 {
234 fprintf(stderr, "Usage: %s database_name in_filename out_filename out_filename2\n",
235 argv[0]);
236 exit(1);
237 }
238
239 database = argv[1];
240 in_filename = argv[2];
241 out_filename = argv[3];
242 out_filename2 = argv[4];
243
244 /*
245 * set up the connection
246 */
247 conn = PQsetdb(NULL, NULL, NULL, NULL, database);
248
249 /* check to see that the backend connection was successfully made */
251 {
252 fprintf(stderr, "%s", PQerrorMessage(conn));
254 }
255
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)");
260 {
261 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
262 PQclear(res);
264 }
265 PQclear(res);
266
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
275 {
276 printf("\tas large object %u.\n", lobjOid);
277
278 printf("picking out bytes 4294967000-4294968000 of the large object\n");
279 pickout(conn, lobjOid, 4294967000U, 1000);
280
281 printf("overwriting bytes 4294967000-4294968000 of the large object with X's\n");
282 overwrite(conn, lobjOid, 4294967000U, 1000);
283
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));
288
289 printf("truncating to 3294968000 bytes\n");
290 my_truncate(conn, lobjOid, 3294968000U);
291
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));
295 }
296
297 res = PQexec(conn, "end");
298 PQclear(res);
299 PQfinish(conn);
300 return 0;
301}
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:182
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:154
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7205
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4939
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7268
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
pg_int64 lo_tell64(PGconn *conn, int fd)
Definition: fe-lobj.c:548
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:438
pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
Definition: fe-lobj.c:385
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
Oid lo_import(PGconn *conn, const char *filename)
Definition: fe-lobj.c:626
int lo_export(PGconn *conn, Oid lobjId, const char *filename)
Definition: fe-lobj.c:748
int lo_truncate64(PGconn *conn, int fd, pg_int64 len)
Definition: fe-lobj.c:195
return str start
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
#define read(a, b, c)
Definition: win32.h:13
int i
Definition: isn.c:72
@ CONNECTION_OK
Definition: libpq-fe.h:81
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:123
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)
Definition: libpq-fe.h:327
#define INV_READ
Definition: libpq-fs.h:22
#define INV_WRITE
Definition: libpq-fs.h:21
exit(1)
const void size_t len
static char * filename
Definition: pg_dumpall.c:119
static char * buf
Definition: pg_test_fsync.c:72
#define printf(...)
Definition: port.h:244
unsigned int Oid
Definition: postgres_ext.h:32
int64_t pg_int64
Definition: postgres_ext.h:48
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PGconn * conn
Definition: streamutil.c:53
static void overwrite(PGconn *conn, Oid lobjId, pg_int64 start, int len)
Definition: testlo64.c:113
static void exit_nicely(PGconn *conn)
Definition: testlo64.c:215
int main(int argc, char **argv)
Definition: testlo64.c:222
static void pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len)
Definition: testlo64.c:78
static void exportFile(PGconn *conn, Oid lobjId, char *filename)
Definition: testlo64.c:172
static void my_truncate(PGconn *conn, Oid lobjId, pg_int64 len)
Definition: testlo64.c:151
#define BUFSIZE
Definition: testlo64.c:26
static Oid importFile(PGconn *conn, char *filename)
Definition: testlo64.c:34