PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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  */
33 static 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 
77 static void
78 pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len)
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 
112 static void
113 overwrite(PGconn *conn, Oid lobjId, pg_int64 start, int len)
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 
150 static 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  */
171 static 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  return;
214 }
215 
216 static void
218 {
219  PQfinish(conn);
220  exit(1);
221 }
222 
223 int
224 main(int argc, char **argv)
225 {
226  char *in_filename,
227  *out_filename,
228  *out_filename2;
229  char *database;
230  Oid lobjOid;
231  PGconn *conn;
232  PGresult *res;
233 
234  if (argc != 5)
235  {
236  fprintf(stderr, "Usage: %s database_name in_filename out_filename out_filename2\n",
237  argv[0]);
238  exit(1);
239  }
240 
241  database = argv[1];
242  in_filename = argv[2];
243  out_filename = argv[3];
244  out_filename2 = argv[4];
245 
246  /*
247  * set up the connection
248  */
249  conn = PQsetdb(NULL, NULL, NULL, NULL, database);
250 
251  /* check to see that the backend connection was successfully made */
252  if (PQstatus(conn) != CONNECTION_OK)
253  {
254  fprintf(stderr, "Connection to database failed: %s",
255  PQerrorMessage(conn));
256  exit_nicely(conn);
257  }
258 
259  res = PQexec(conn, "begin");
260  PQclear(res);
261  printf("importing file \"%s\" ...\n", in_filename);
262 /* lobjOid = importFile(conn, in_filename); */
263  lobjOid = lo_import(conn, in_filename);
264  if (lobjOid == 0)
265  fprintf(stderr, "%s\n", PQerrorMessage(conn));
266  else
267  {
268  printf("\tas large object %u.\n", lobjOid);
269 
270  printf("picking out bytes 4294967000-4294968000 of the large object\n");
271  pickout(conn, lobjOid, 4294967000U, 1000);
272 
273  printf("overwriting bytes 4294967000-4294968000 of the large object with X's\n");
274  overwrite(conn, lobjOid, 4294967000U, 1000);
275 
276  printf("exporting large object to file \"%s\" ...\n", out_filename);
277 /* exportFile(conn, lobjOid, out_filename); */
278  if (lo_export(conn, lobjOid, out_filename) < 0)
279  fprintf(stderr, "%s\n", PQerrorMessage(conn));
280 
281  printf("truncating to 3294968000 bytes\n");
282  my_truncate(conn, lobjOid, 3294968000U);
283 
284  printf("exporting truncated large object to file \"%s\" ...\n", out_filename2);
285  if (lo_export(conn, lobjOid, out_filename2) < 0)
286  fprintf(stderr, "%s\n", PQerrorMessage(conn));
287  }
288 
289  res = PQexec(conn, "end");
290  PQclear(res);
291  PQfinish(conn);
292  return 0;
293 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6097
pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
Definition: fe-lobj.c:409
#define write(a, b, c)
Definition: win32.h:14
int main(int argc, char **argv)
Definition: testlo64.c:224
static void overwrite(PGconn *conn, Oid lobjId, pg_int64 start, int len)
Definition: testlo64.c:113
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
unsigned int Oid
Definition: postgres_ext.h:31
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
static void exit_nicely(PGconn *conn)
Definition: testlo64.c:217
pg_int64 lo_tell64(PGconn *conn, int fd)
Definition: fe-lobj.c:584
#define malloc(a)
Definition: header.h:50
static void exportFile(PGconn *conn, Oid lobjId, char *filename)
Definition: testlo64.c:172
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
PGconn * conn
Definition: streamutil.c:46
static void pickout(PGconn *conn, Oid lobjId, pg_int64 start, int len)
Definition: testlo64.c:78
int lo_export(PGconn *conn, Oid lobjId, const char *filename)
Definition: fe-lobj.c:784
static char * buf
Definition: pg_test_fsync.c:67
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:155
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:189
#define BUFSIZE
Definition: testlo64.c:26
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)
Definition: libpq-fe.h:269
int lo_truncate64(PGconn *conn, int fd, pg_int64 len)
Definition: fe-lobj.c:205
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
static void my_truncate(PGconn *conn, Oid lobjId, pg_int64 len)
Definition: testlo64.c:151
#define INV_WRITE
Definition: libpq-fs.h:21
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:465
static char * filename
Definition: pg_dumpall.c:90
static Oid importFile(PGconn *conn, char *filename)
Definition: testlo64.c:34
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
#define close(a)
Definition: win32.h:12
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6044
Oid lo_import(PGconn *conn, const char *filename)
Definition: fe-lobj.c:668
#define read(a, b, c)
Definition: win32.h:13