]> begriffs open source - ai-pg/blob - full-docs/txt/lo-examplesect.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / lo-examplesect.txt
1
2 33.5. Example Program #
3
4    Example 33.1 is a sample program which shows how the large object
5    interface in libpq can be used. Parts of the program are commented out
6    but are left in the source for the reader's benefit. This program can
7    also be found in src/test/examples/testlo.c in the source distribution.
8
9    Example 33.1. Large Objects with libpq Example Program
10 /*-----------------------------------------------------------------
11  *
12  * testlo.c
13  *    test using large objects with libpq
14  *
15  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
16  * Portions Copyright (c) 1994, Regents of the University of California
17  *
18  *
19  * IDENTIFICATION
20  *    src/test/examples/testlo.c
21  *
22  *-----------------------------------------------------------------
23  */
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include "libpq-fe.h"
33 #include "libpq/libpq-fs.h"
34
35 #define BUFSIZE         1024
36
37 /*
38  * importFile -
39  *    import file "in_filename" into database as large object "lobjOid"
40  *
41  */
42 static Oid
43 importFile(PGconn *conn, char *filename)
44 {
45     Oid         lobjId;
46     int         lobj_fd;
47     char        buf[BUFSIZE];
48     int         nbytes,
49                 tmp;
50     int         fd;
51
52     /*
53      * open the file to be read in
54      */
55     fd = open(filename, O_RDONLY, 0666);
56     if (fd < 0)
57     {                           /* error */
58         fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
59     }
60
61     /*
62      * create the large object
63      */
64     lobjId = lo_creat(conn, INV_READ | INV_WRITE);
65     if (lobjId == 0)
66         fprintf(stderr, "cannot create large object");
67
68     lobj_fd = lo_open(conn, lobjId, INV_WRITE);
69
70     /*
71      * read in from the Unix file and write to the inversion file
72      */
73     while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
74     {
75         tmp = lo_write(conn, lobj_fd, buf, nbytes);
76         if (tmp < nbytes)
77             fprintf(stderr, "error while reading \"%s\"", filename);
78     }
79
80     close(fd);
81     lo_close(conn, lobj_fd);
82
83     return lobjId;
84 }
85
86 static void
87 pickout(PGconn *conn, Oid lobjId, int start, int len)
88 {
89     int         lobj_fd;
90     char       *buf;
91     int         nbytes;
92     int         nread;
93
94     lobj_fd = lo_open(conn, lobjId, INV_READ);
95     if (lobj_fd < 0)
96         fprintf(stderr, "cannot open large object %u", lobjId);
97
98     lo_lseek(conn, lobj_fd, start, SEEK_SET);
99     buf = malloc(len + 1);
100
101     nread = 0;
102     while (len - nread > 0)
103     {
104         nbytes = lo_read(conn, lobj_fd, buf, len - nread);
105         buf[nbytes] = '\0';
106         fprintf(stderr, ">>> %s", buf);
107         nread += nbytes;
108         if (nbytes <= 0)
109             break;              /* no more data? */
110     }
111     free(buf);
112     fprintf(stderr, "\n");
113     lo_close(conn, lobj_fd);
114 }
115
116 static void
117 overwrite(PGconn *conn, Oid lobjId, int start, int len)
118 {
119     int         lobj_fd;
120     char       *buf;
121     int         nbytes;
122     int         nwritten;
123     int         i;
124
125     lobj_fd = lo_open(conn, lobjId, INV_WRITE);
126     if (lobj_fd < 0)
127         fprintf(stderr, "cannot open large object %u", lobjId);
128
129     lo_lseek(conn, lobj_fd, start, SEEK_SET);
130     buf = malloc(len + 1);
131
132     for (i = 0; i < len; i++)
133         buf[i] = 'X';
134     buf[i] = '\0';
135
136     nwritten = 0;
137     while (len - nwritten > 0)
138     {
139         nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
140         nwritten += nbytes;
141         if (nbytes <= 0)
142         {
143             fprintf(stderr, "\nWRITE FAILED!\n");
144             break;
145         }
146     }
147     free(buf);
148     fprintf(stderr, "\n");
149     lo_close(conn, lobj_fd);
150 }
151
152
153 /*
154  * exportFile -
155  *    export large object "lobjOid" to file "out_filename"
156  *
157  */
158 static void
159 exportFile(PGconn *conn, Oid lobjId, char *filename)
160 {
161     int         lobj_fd;
162     char        buf[BUFSIZE];
163     int         nbytes,
164                 tmp;
165     int         fd;
166
167     /*
168      * open the large object
169      */
170     lobj_fd = lo_open(conn, lobjId, INV_READ);
171     if (lobj_fd < 0)
172         fprintf(stderr, "cannot open large object %u", lobjId);
173
174     /*
175      * open the file to be written to
176      */
177     fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
178     if (fd < 0)
179     {                           /* error */
180         fprintf(stderr, "cannot open unix file\"%s\"",
181                 filename);
182     }
183
184     /*
185      * read in from the inversion file and write to the Unix file
186      */
187     while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
188     {
189         tmp = write(fd, buf, nbytes);
190         if (tmp < nbytes)
191         {
192             fprintf(stderr, "error while writing \"%s\"",
193                     filename);
194         }
195     }
196
197     lo_close(conn, lobj_fd);
198     close(fd);
199 }
200
201 static void
202 exit_nicely(PGconn *conn)
203 {
204     PQfinish(conn);
205     exit(1);
206 }
207
208 int
209 main(int argc, char **argv)
210 {
211     char       *in_filename,
212                *out_filename;
213     char       *database;
214     Oid         lobjOid;
215     PGconn     *conn;
216     PGresult   *res;
217
218     if (argc != 4)
219     {
220         fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
221                 argv[0]);
222         exit(1);
223     }
224
225     database = argv[1];
226     in_filename = argv[2];
227     out_filename = argv[3];
228
229     /*
230      * set up the connection
231      */
232     conn = PQsetdb(NULL, NULL, NULL, NULL, database);
233
234     /* check to see that the backend connection was successfully made */
235     if (PQstatus(conn) != CONNECTION_OK)
236     {
237         fprintf(stderr, "%s", PQerrorMessage(conn));
238         exit_nicely(conn);
239     }
240
241     /* Set always-secure search path, so malicious users can't take control. */
242     res = PQexec(conn,
243                  "SELECT pg_catalog.set_config('search_path', '', false)");
244     if (PQresultStatus(res) != PGRES_TUPLES_OK)
245     {
246         fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
247         PQclear(res);
248         exit_nicely(conn);
249     }
250     PQclear(res);
251
252     res = PQexec(conn, "begin");
253     PQclear(res);
254     printf("importing file \"%s\" ...\n", in_filename);
255 /*  lobjOid = importFile(conn, in_filename); */
256     lobjOid = lo_import(conn, in_filename);
257     if (lobjOid == 0)
258         fprintf(stderr, "%s\n", PQerrorMessage(conn));
259     else
260     {
261         printf("\tas large object %u.\n", lobjOid);
262
263         printf("picking out bytes 1000-2000 of the large object\n");
264         pickout(conn, lobjOid, 1000, 1000);
265
266         printf("overwriting bytes 1000-2000 of the large object with X's\n");
267         overwrite(conn, lobjOid, 1000, 1000);
268
269         printf("exporting large object to file \"%s\" ...\n", out_filename);
270 /*      exportFile(conn, lobjOid, out_filename); */
271         if (lo_export(conn, lobjOid, out_filename) < 0)
272             fprintf(stderr, "%s\n", PQerrorMessage(conn));
273     }
274
275     res = PQexec(conn, "end");
276     PQclear(res);
277     PQfinish(conn);
278     return 0;
279 }
280