public inbox for [email protected]
help / color / mirror / Atom feedFrom: Josh Kupershmidt <[email protected]>
To: Peter Eisentraut <[email protected]>
Cc: Magnus Hagander <[email protected]>
Cc: pgsql-docs <[email protected]>
Subject: Re: old testlo example code
Date: Tue, 26 Feb 2013 20:18:40 -0700
Message-ID: <CAK3UJRFJEU1bUjRrxjs2kZcOA=Q+Vu+MPcCGnko+3DS05ZhCTw@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <CAK3UJRFL8OD9Me-vPaE=ELPZ5-hFmk_Psa-cF00YfQJ7GNua-w@mail.gmail.com>
<CABUevEyQbJPA8NW_USk2WD83DaAzV3DNj=FiQmRXZXO2wtqs8g@mail.gmail.com>
<[email protected]>
List-Unsubscribe: <mailto:[email protected]?body=unsub%20pgsql-docs>
On Thu, Feb 14, 2013 at 7:30 PM, Peter Eisentraut <[email protected]> wrote:
> On Sat, 2013-01-05 at 15:14 +0100, Magnus Hagander wrote:
>> ISTM we should either remove the example programs and replace them
>> with just a reference, or find a way to include the source code into
>> the documentation with some kind of include statement instead of
>> haivng a copy of it. That should be done the same way for all the
>> example programs, not just the testlo ones of course.
>>
>> Not sure if it's possible to create such an include though - someone
>> who knows our toolchain better can hopefully comment on that?
>
> I've been looking into this. It's not easily possible with the current
> SGML setup. (XInclude with XML would probably work.) So for now it
> would be best if someone could just sync up the docs with the code until
> we figure out a better way.
OK, here's a patch to update the example code in the docs to match the
example programs in ./src/test/examples . In addition to the testlo
example discussed, I updated the libpq examples as well. There's a
fair amount of whitespace churn in the diff, though I assume that's
from a pgindent change of the test code at some point.
Josh
--
Sent via pgsql-docs mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-docs
Attachments:
[application/octet-stream] example_code_in_documentation.diff (31.0K, 2-example_code_in_documentation.diff)
download | inline diff:
*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
***************
*** 7840,7971 **** main(int argc, char **argv)
<![CDATA[
/*
* testlibpq2.c
! * Test of the asynchronous notification interface
*
* Start this program, then from psql in another window do
! * NOTIFY TBL2;
* Repeat four times to get this program to exit.
*
* Or, if you want to get fancy, try this:
* populate a database with the following commands
* (provided in src/test/examples/testlibpq2.sql):
*
! * CREATE TABLE TBL1 (i int4);
*
! * CREATE TABLE TBL2 (i int4);
*
! * CREATE RULE r1 AS ON INSERT TO TBL1 DO
! * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
*
* and do this four times:
*
! * INSERT INTO TBL1 VALUES (10);
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
! #include <libpq-fe.h>
static void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
int
main(int argc, char **argv)
{
! const char *conninfo;
! PGconn *conn;
! PGresult *res;
! PGnotify *notify;
! int nnotifies;
!
! /*
! * If the user supplies a parameter on the command line, use it as the
! * conninfo string; otherwise default to setting dbname=postgres and using
! * environment variables or defaults for all other connection parameters.
! */
! if (argc > 1)
! conninfo = argv[1];
! else
! conninfo = "dbname = postgres";
!
! /* Make a connection to the database */
! conn = PQconnectdb(conninfo);
!
! /* Check to see that the backend connection was successfully made */
! if (PQstatus(conn) != CONNECTION_OK)
! {
! fprintf(stderr, "Connection to database failed: %s",
! PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! /*
! * Issue LISTEN command to enable notifications from the rule's NOTIFY.
! */
! res = PQexec(conn, "LISTEN TBL2");
! if (PQresultStatus(res) != PGRES_COMMAND_OK)
! {
! fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! /*
! * should PQclear PGresult whenever it is no longer needed to avoid memory
! * leaks
! */
! PQclear(res);
!
! /* Quit after four notifies are received. */
! nnotifies = 0;
! while (nnotifies < 4)
! {
! /*
! * Sleep until something happens on the connection. We use select(2)
! * to wait for input, but you could also use poll() or similar
! * facilities.
! */
! int sock;
! fd_set input_mask;
!
! sock = PQsocket(conn);
!
! if (sock < 0)
! break; /* shouldn't happen */
!
! FD_ZERO(&input_mask);
! FD_SET(sock, &input_mask);
!
! if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
! {
! fprintf(stderr, "select() failed: %s\n", strerror(errno));
! exit_nicely(conn);
! }
!
! /* Now check for input */
! PQconsumeInput(conn);
! while ((notify = PQnotifies(conn)) != NULL)
! {
! fprintf(stderr,
! "ASYNC NOTIFY of '%s' received from backend PID %d\n",
! notify->relname, notify->be_pid);
! PQfreemem(notify);
! nnotifies++;
! }
! }
!
! fprintf(stderr, "Done.\n");
!
! /* close the connection to the database and cleanup */
! PQfinish(conn);
!
! return 0;
}
]]>
</programlisting>
--- 7840,7976 ----
<![CDATA[
/*
* testlibpq2.c
! * Test of the asynchronous notification interface
*
* Start this program, then from psql in another window do
! * NOTIFY TBL2;
* Repeat four times to get this program to exit.
*
* Or, if you want to get fancy, try this:
* populate a database with the following commands
* (provided in src/test/examples/testlibpq2.sql):
*
! * CREATE TABLE TBL1 (i int4);
*
! * CREATE TABLE TBL2 (i int4);
*
! * CREATE RULE r1 AS ON INSERT TO TBL1 DO
! * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
*
* and do this four times:
*
! * INSERT INTO TBL1 VALUES (10);
*/
+
+ #ifdef WIN32
+ #include <windows.h>
+ #endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
! #include <sys/types.h>
! #include "libpq-fe.h"
static void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
int
main(int argc, char **argv)
{
! const char *conninfo;
! PGconn *conn;
! PGresult *res;
! PGnotify *notify;
! int nnotifies;
!
! /*
! * If the user supplies a parameter on the command line, use it as the
! * conninfo string; otherwise default to setting dbname=postgres and using
! * environment variables or defaults for all other connection parameters.
! */
! if (argc > 1)
! conninfo = argv[1];
! else
! conninfo = "dbname = postgres";
!
! /* Make a connection to the database */
! conn = PQconnectdb(conninfo);
!
! /* Check to see that the backend connection was successfully made */
! if (PQstatus(conn) != CONNECTION_OK)
! {
! fprintf(stderr, "Connection to database failed: %s",
! PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! /*
! * Issue LISTEN command to enable notifications from the rule's NOTIFY.
! */
! res = PQexec(conn, "LISTEN TBL2");
! if (PQresultStatus(res) != PGRES_COMMAND_OK)
! {
! fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! /*
! * should PQclear PGresult whenever it is no longer needed to avoid memory
! * leaks
! */
! PQclear(res);
!
! /* Quit after four notifies are received. */
! nnotifies = 0;
! while (nnotifies < 4)
! {
! /*
! * Sleep until something happens on the connection. We use select(2)
! * to wait for input, but you could also use poll() or similar
! * facilities.
! */
! int sock;
! fd_set input_mask;
!
! sock = PQsocket(conn);
!
! if (sock < 0)
! break; /* shouldn't happen */
!
! FD_ZERO(&input_mask);
! FD_SET(sock, &input_mask);
!
! if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
! {
! fprintf(stderr, "select() failed: %s\n", strerror(errno));
! exit_nicely(conn);
! }
!
! /* Now check for input */
! PQconsumeInput(conn);
! while ((notify = PQnotifies(conn)) != NULL)
! {
! fprintf(stderr,
! "ASYNC NOTIFY of '%s' received from backend PID %d\n",
! notify->relname, notify->be_pid);
! PQfreemem(notify);
! nnotifies++;
! }
! }
!
! fprintf(stderr, "Done.\n");
!
! /* close the connection to the database and cleanup */
! PQfinish(conn);
!
! return 0;
}
]]>
</programlisting>
***************
*** 7978,7984 **** main(int argc, char **argv)
<![CDATA[
/*
* testlibpq3.c
! * Test out-of-line parameters and binary I/O.
*
* Before running this, populate a database with the following commands
* (provided in src/test/examples/testlibpq3.sql):
--- 7983,7989 ----
<![CDATA[
/*
* testlibpq3.c
! * Test out-of-line parameters and binary I/O.
*
* Before running this, populate a database with the following commands
* (provided in src/test/examples/testlibpq3.sql):
***************
*** 7991,8010 **** main(int argc, char **argv)
* The expected output is:
*
* tuple 0: got
! * i = (4 bytes) 1
! * t = (11 bytes) 'joe's place'
! * b = (5 bytes) \000\001\002\003\004
*
* tuple 0: got
! * i = (4 bytes) 2
! * t = (8 bytes) 'ho there'
! * b = (5 bytes) \004\003\002\001\000
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
! #include <libpq-fe.h>
/* for ntohl/htonl */
#include <netinet/in.h>
--- 7996,8021 ----
* The expected output is:
*
* tuple 0: got
! * i = (4 bytes) 1
! * t = (11 bytes) 'joe's place'
! * b = (5 bytes) \000\001\002\003\004
*
* tuple 0: got
! * i = (4 bytes) 2
! * t = (8 bytes) 'ho there'
! * b = (5 bytes) \004\003\002\001\000
*/
+
+ #ifdef WIN32
+ #include <windows.h>
+ #endif
+
#include <stdio.h>
#include <stdlib.h>
+ #include <stdint.h>
#include <string.h>
#include <sys/types.h>
! #include "libpq-fe.h"
/* for ntohl/htonl */
#include <netinet/in.h>
***************
*** 8014,8021 **** main(int argc, char **argv)
static void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
/*
--- 8025,8032 ----
static void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
/*
***************
*** 8026,8191 **** exit_nicely(PGconn *conn)
static void
show_binary_results(PGresult *res)
{
! int i,
! j;
! int i_fnum,
! t_fnum,
! b_fnum;
!
! /* Use PQfnumber to avoid assumptions about field order in result */
! i_fnum = PQfnumber(res, "i");
! t_fnum = PQfnumber(res, "t");
! b_fnum = PQfnumber(res, "b");
!
! for (i = 0; i < PQntuples(res); i++)
! {
! char *iptr;
! char *tptr;
! char *bptr;
! int blen;
! int ival;
!
! /* Get the field values (we ignore possibility they are null!) */
! iptr = PQgetvalue(res, i, i_fnum);
! tptr = PQgetvalue(res, i, t_fnum);
! bptr = PQgetvalue(res, i, b_fnum);
!
! /*
! * The binary representation of INT4 is in network byte order, which
! * we'd better coerce to the local byte order.
! */
! ival = ntohl(*((uint32_t *) iptr));
!
! /*
! * The binary representation of TEXT is, well, text, and since libpq
! * was nice enough to append a zero byte to it, it'll work just fine
! * as a C string.
! *
! * The binary representation of BYTEA is a bunch of bytes, which could
! * include embedded nulls so we have to pay attention to field length.
! */
! blen = PQgetlength(res, i, b_fnum);
!
! printf("tuple %d: got\n", i);
! printf(" i = (%d bytes) %d\n",
! PQgetlength(res, i, i_fnum), ival);
! printf(" t = (%d bytes) '%s'\n",
! PQgetlength(res, i, t_fnum), tptr);
! printf(" b = (%d bytes) ", blen);
! for (j = 0; j < blen; j++)
! printf("\\%03o", bptr[j]);
! printf("\n\n");
! }
}
int
main(int argc, char **argv)
{
! const char *conninfo;
! PGconn *conn;
! PGresult *res;
! const char *paramValues[1];
! int paramLengths[1];
! int paramFormats[1];
! uint32_t binaryIntVal;
!
! /*
! * If the user supplies a parameter on the command line, use it as the
! * conninfo string; otherwise default to setting dbname=postgres and using
! * environment variables or defaults for all other connection parameters.
! */
! if (argc > 1)
! conninfo = argv[1];
! else
! conninfo = "dbname = postgres";
!
! /* Make a connection to the database */
! conn = PQconnectdb(conninfo);
!
! /* Check to see that the backend connection was successfully made */
! if (PQstatus(conn) != CONNECTION_OK)
! {
! fprintf(stderr, "Connection to database failed: %s",
! PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! /*
! * The point of this program is to illustrate use of PQexecParams() with
! * out-of-line parameters, as well as binary transmission of data.
! *
! * This first example transmits the parameters as text, but receives the
! * results in binary format. By using out-of-line parameters we can
! * avoid a lot of tedious mucking about with quoting and escaping, even
! * though the data is text. Notice how we don't have to do anything
! * special with the quote mark in the parameter value.
! */
!
! /* Here is our out-of-line parameter value */
! paramValues[0] = "joe's place";
!
! res = PQexecParams(conn,
! "SELECT * FROM test1 WHERE t = $1",
! 1, /* one param */
! NULL, /* let the backend deduce param type */
! paramValues,
! NULL, /* don't need param lengths since text */
! NULL, /* default to all text params */
! 1); /* ask for binary results */
!
! if (PQresultStatus(res) != PGRES_TUPLES_OK)
! {
! fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! show_binary_results(res);
!
! PQclear(res);
!
! /*
! * In this second example we transmit an integer parameter in binary
! * form, and again retrieve the results in binary form.
! *
! * Although we tell PQexecParams we are letting the backend deduce
! * parameter type, we really force the decision by casting the parameter
! * symbol in the query text. This is a good safety measure when sending
! * binary parameters.
! */
!
! /* Convert integer value "2" to network byte order */
! binaryIntVal = htonl((uint32_t) 2);
!
! /* Set up parameter arrays for PQexecParams */
! paramValues[0] = (char *) &binaryIntVal;
! paramLengths[0] = sizeof(binaryIntVal);
! paramFormats[0] = 1; /* binary */
!
! res = PQexecParams(conn,
! "SELECT * FROM test1 WHERE i = $1::int4",
! 1, /* one param */
! NULL, /* let the backend deduce param type */
! paramValues,
! paramLengths,
! paramFormats,
! 1); /* ask for binary results */
!
! if (PQresultStatus(res) != PGRES_TUPLES_OK)
! {
! fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! show_binary_results(res);
!
! PQclear(res);
!
! /* close the connection to the database and cleanup */
! PQfinish(conn);
!
! return 0;
}
]]>
</programlisting>
--- 8037,8202 ----
static void
show_binary_results(PGresult *res)
{
! int i,
! j;
! int i_fnum,
! t_fnum,
! b_fnum;
!
! /* Use PQfnumber to avoid assumptions about field order in result */
! i_fnum = PQfnumber(res, "i");
! t_fnum = PQfnumber(res, "t");
! b_fnum = PQfnumber(res, "b");
!
! for (i = 0; i < PQntuples(res); i++)
! {
! char *iptr;
! char *tptr;
! char *bptr;
! int blen;
! int ival;
!
! /* Get the field values (we ignore possibility they are null!) */
! iptr = PQgetvalue(res, i, i_fnum);
! tptr = PQgetvalue(res, i, t_fnum);
! bptr = PQgetvalue(res, i, b_fnum);
!
! /*
! * The binary representation of INT4 is in network byte order, which
! * we'd better coerce to the local byte order.
! */
! ival = ntohl(*((uint32_t *) iptr));
!
! /*
! * The binary representation of TEXT is, well, text, and since libpq
! * was nice enough to append a zero byte to it, it'll work just fine
! * as a C string.
! *
! * The binary representation of BYTEA is a bunch of bytes, which could
! * include embedded nulls so we have to pay attention to field length.
! */
! blen = PQgetlength(res, i, b_fnum);
!
! printf("tuple %d: got\n", i);
! printf(" i = (%d bytes) %d\n",
! PQgetlength(res, i, i_fnum), ival);
! printf(" t = (%d bytes) '%s'\n",
! PQgetlength(res, i, t_fnum), tptr);
! printf(" b = (%d bytes) ", blen);
! for (j = 0; j < blen; j++)
! printf("\\%03o", bptr[j]);
! printf("\n\n");
! }
}
int
main(int argc, char **argv)
{
! const char *conninfo;
! PGconn *conn;
! PGresult *res;
! const char *paramValues[1];
! int paramLengths[1];
! int paramFormats[1];
! uint32_t binaryIntVal;
!
! /*
! * If the user supplies a parameter on the command line, use it as the
! * conninfo string; otherwise default to setting dbname=postgres and using
! * environment variables or defaults for all other connection parameters.
! */
! if (argc > 1)
! conninfo = argv[1];
! else
! conninfo = "dbname = postgres";
!
! /* Make a connection to the database */
! conn = PQconnectdb(conninfo);
!
! /* Check to see that the backend connection was successfully made */
! if (PQstatus(conn) != CONNECTION_OK)
! {
! fprintf(stderr, "Connection to database failed: %s",
! PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! /*
! * The point of this program is to illustrate use of PQexecParams() with
! * out-of-line parameters, as well as binary transmission of data.
! *
! * This first example transmits the parameters as text, but receives the
! * results in binary format. By using out-of-line parameters we can avoid
! * a lot of tedious mucking about with quoting and escaping, even though
! * the data is text. Notice how we don't have to do anything special with
! * the quote mark in the parameter value.
! */
!
! /* Here is our out-of-line parameter value */
! paramValues[0] = "joe's place";
!
! res = PQexecParams(conn,
! "SELECT * FROM test1 WHERE t = $1",
! 1, /* one param */
! NULL, /* let the backend deduce param type */
! paramValues,
! NULL, /* don't need param lengths since text */
! NULL, /* default to all text params */
! 1); /* ask for binary results */
!
! if (PQresultStatus(res) != PGRES_TUPLES_OK)
! {
! fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! show_binary_results(res);
!
! PQclear(res);
!
! /*
! * In this second example we transmit an integer parameter in binary form,
! * and again retrieve the results in binary form.
! *
! * Although we tell PQexecParams we are letting the backend deduce
! * parameter type, we really force the decision by casting the parameter
! * symbol in the query text. This is a good safety measure when sending
! * binary parameters.
! */
!
! /* Convert integer value "2" to network byte order */
! binaryIntVal = htonl((uint32_t) 2);
!
! /* Set up parameter arrays for PQexecParams */
! paramValues[0] = (char *) &binaryIntVal;
! paramLengths[0] = sizeof(binaryIntVal);
! paramFormats[0] = 1; /* binary */
!
! res = PQexecParams(conn,
! "SELECT * FROM test1 WHERE i = $1::int4",
! 1, /* one param */
! NULL, /* let the backend deduce param type */
! paramValues,
! paramLengths,
! paramFormats,
! 1); /* ask for binary results */
!
! if (PQresultStatus(res) != PGRES_TUPLES_OK)
! {
! fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
! PQclear(res);
! exit_nicely(conn);
! }
!
! show_binary_results(res);
!
! PQclear(res);
!
! /* close the connection to the database and cleanup */
! PQfinish(conn);
!
! return 0;
}
]]>
</programlisting>
*** a/doc/src/sgml/lobj.sgml
--- b/doc/src/sgml/lobj.sgml
***************
*** 589,841 **** SELECT lo_export(image.raster, '/tmp/motd') FROM image
<example id="lo-example">
<title>Large Objects with <application>libpq</application> Example Program</title>
<programlisting><![CDATA[
! /*--------------------------------------------------------------
*
! * testlo.c--
! * test using large objects with libpq
*
! * Copyright (c) 1994, Regents of the University of California
*
! *--------------------------------------------------------------
*/
#include <stdio.h>
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
! #define BUFSIZE 1024
/*
! * importFile
! * import file "in_filename" into database as large object "lobjOid"
*
*/
! Oid
importFile(PGconn *conn, char *filename)
{
! Oid lobjId;
! int lobj_fd;
! char buf[BUFSIZE];
! int nbytes,
! tmp;
! int fd;
!
! /*
! * open the file to be read in
! */
! fd = open(filename, O_RDONLY, 0666);
! if (fd < 0)
! { /* error */
! fprintf(stderr, "cannot open unix file %s\n", filename);
! }
!
! /*
! * create the large object
! */
! lobjId = lo_creat(conn, INV_READ | INV_WRITE);
! if (lobjId == 0)
! fprintf(stderr, "cannot create large object\n");
!
! lobj_fd = lo_open(conn, lobjId, INV_WRITE);
!
! /*
! * read in from the Unix file and write to the inversion file
! */
! while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
! {
! tmp = lo_write(conn, lobj_fd, buf, nbytes);
! if (tmp < nbytes)
! fprintf(stderr, "error while reading large object\n");
! }
!
! (void) close(fd);
! (void) lo_close(conn, lobj_fd);
!
! return lobjId;
}
! void
pickout(PGconn *conn, Oid lobjId, int start, int len)
{
! int lobj_fd;
! char *buf;
! int nbytes;
! int nread;
!
! lobj_fd = lo_open(conn, lobjId, INV_READ);
! if (lobj_fd < 0)
! {
! fprintf(stderr, "cannot open large object %d\n",
! lobjId);
! }
!
! lo_lseek(conn, lobj_fd, start, SEEK_SET);
! buf = malloc(len + 1);
!
! nread = 0;
! while (len - nread > 0)
! {
! nbytes = lo_read(conn, lobj_fd, buf, len - nread);
! buf[nbytes] = ' ';
! fprintf(stderr, ">>> %s", buf);
! nread += nbytes;
! }
! free(buf);
! fprintf(stderr, "\n");
! lo_close(conn, lobj_fd);
}
! void
overwrite(PGconn *conn, Oid lobjId, int start, int len)
{
! int lobj_fd;
! char *buf;
! int nbytes;
! int nwritten;
! int i;
!
! lobj_fd = lo_open(conn, lobjId, INV_WRITE);
! if (lobj_fd < 0)
! {
! fprintf(stderr, "cannot open large object %d\n",
! lobjId);
! }
!
! lo_lseek(conn, lobj_fd, start, SEEK_SET);
! buf = malloc(len + 1);
!
! for (i = 0; i < len; i++)
! buf[i] = 'X';
! buf[i] = ' ';
!
! nwritten = 0;
! while (len - nwritten > 0)
! {
! nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
! nwritten += nbytes;
! }
! free(buf);
! fprintf(stderr, "\n");
! lo_close(conn, lobj_fd);
}
/*
! * exportFile
! * export large object "lobjOid" to file "out_filename"
*
*/
! void
exportFile(PGconn *conn, Oid lobjId, char *filename)
{
! int lobj_fd;
! char buf[BUFSIZE];
! int nbytes,
! tmp;
! int fd;
!
! /*
! * open the large object
! */
! lobj_fd = lo_open(conn, lobjId, INV_READ);
! if (lobj_fd < 0)
! {
! fprintf(stderr, "cannot open large object %d\n",
! lobjId);
! }
!
! /*
! * open the file to be written to
! */
! fd = open(filename, O_CREAT | O_WRONLY, 0666);
! if (fd < 0)
! { /* error */
! fprintf(stderr, "cannot open unix file %s\n",
! filename);
! }
!
! /*
! * read in from the inversion file and write to the Unix file
! */
! while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
! {
! tmp = write(fd, buf, nbytes);
! if (tmp < nbytes)
! {
! fprintf(stderr, "error while writing %s\n",
! filename);
! }
! }
!
! (void) lo_close(conn, lobj_fd);
! (void) close(fd);
!
! return;
}
! void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
int
main(int argc, char **argv)
{
! char *in_filename,
! *out_filename;
! char *database;
! Oid lobjOid;
! PGconn *conn;
! PGresult *res;
!
! if (argc != 4)
! {
! fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
! argv[0]);
! exit(1);
! }
!
! database = argv[1];
! in_filename = argv[2];
! out_filename = argv[3];
!
! /*
! * set up the connection
! */
! conn = PQsetdb(NULL, NULL, NULL, NULL, database);
!
! /* check to see that the backend connection was successfully made */
! if (PQstatus(conn) == CONNECTION_BAD)
! {
! fprintf(stderr, "Connection to database '%s' failed.\n", database);
! fprintf(stderr, "%s", PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! res = PQexec(conn, "begin");
! PQclear(res);
!
! printf("importing file %s\n", in_filename);
! /* lobjOid = importFile(conn, in_filename); */
! lobjOid = lo_import(conn, in_filename);
! /*
! printf("as large object %d.\n", lobjOid);
!
! printf("picking out bytes 1000-2000 of the large object\n");
! pickout(conn, lobjOid, 1000, 1000);
!
! printf("overwriting bytes 1000-2000 of the large object with X's\n");
! overwrite(conn, lobjOid, 1000, 1000);
! */
!
! printf("exporting large object to file %s\n", out_filename);
! /* exportFile(conn, lobjOid, out_filename); */
! lo_export(conn, lobjOid, out_filename);
!
! res = PQexec(conn, "end");
! PQclear(res);
! PQfinish(conn);
! exit(0);
}
]]>
</programlisting>
--- 589,855 ----
<example id="lo-example">
<title>Large Objects with <application>libpq</application> Example Program</title>
<programlisting><![CDATA[
! /*-------------------------------------------------------------------------
*
! * testlo.c
! * test using large objects with libpq
*
! * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
! * Portions Copyright (c) 1994, Regents of the University of California
*
! *
! * IDENTIFICATION
! * src/test/examples/testlo.c
! *
! *-------------------------------------------------------------------------
*/
#include <stdio.h>
+ #include <stdlib.h>
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
! #define BUFSIZE 1024
/*
! * importFile -
! * import file "in_filename" into database as large object "lobjOid"
*
*/
! static Oid
importFile(PGconn *conn, char *filename)
{
! Oid lobjId;
! int lobj_fd;
! char buf[BUFSIZE];
! int nbytes,
! tmp;
! int fd;
!
! /*
! * open the file to be read in
! */
! fd = open(filename, O_RDONLY, 0666);
! if (fd < 0)
! { /* error */
! fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
! }
!
! /*
! * create the large object
! */
! lobjId = lo_creat(conn, INV_READ | INV_WRITE);
! if (lobjId == 0)
! fprintf(stderr, "cannot create large object");
!
! lobj_fd = lo_open(conn, lobjId, INV_WRITE);
!
! /*
! * read in from the Unix file and write to the inversion file
! */
! while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
! {
! tmp = lo_write(conn, lobj_fd, buf, nbytes);
! if (tmp < nbytes)
! fprintf(stderr, "error while reading \"%s\"", filename);
! }
!
! close(fd);
! lo_close(conn, lobj_fd);
!
! return lobjId;
}
! static void
pickout(PGconn *conn, Oid lobjId, int start, int len)
{
! int lobj_fd;
! char *buf;
! int nbytes;
! int nread;
!
! lobj_fd = lo_open(conn, lobjId, INV_READ);
! if (lobj_fd < 0)
! fprintf(stderr, "cannot open large object %u", lobjId);
!
! lo_lseek(conn, lobj_fd, start, SEEK_SET);
! buf = malloc(len + 1);
!
! nread = 0;
! while (len - nread > 0)
! {
! nbytes = lo_read(conn, lobj_fd, buf, len - nread);
! buf[nbytes] = '\0';
! fprintf(stderr, ">>> %s", buf);
! nread += nbytes;
! if (nbytes <= 0)
! break; /* no more data? */
! }
! free(buf);
! fprintf(stderr, "\n");
! lo_close(conn, lobj_fd);
}
! static void
overwrite(PGconn *conn, Oid lobjId, int start, int len)
{
! int lobj_fd;
! char *buf;
! int nbytes;
! int nwritten;
! int i;
!
! lobj_fd = lo_open(conn, lobjId, INV_WRITE);
! if (lobj_fd < 0)
! fprintf(stderr, "cannot open large object %u", lobjId);
!
! lo_lseek(conn, lobj_fd, start, SEEK_SET);
! buf = malloc(len + 1);
!
! for (i = 0; i < len; i++)
! buf[i] = 'X';
! buf[i] = '\0';
!
! nwritten = 0;
! while (len - nwritten > 0)
! {
! nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
! nwritten += nbytes;
! if (nbytes <= 0)
! {
! fprintf(stderr, "\nWRITE FAILED!\n");
! break;
! }
! }
! free(buf);
! fprintf(stderr, "\n");
! lo_close(conn, lobj_fd);
}
+
/*
! * exportFile -
! * export large object "lobjOid" to file "out_filename"
*
*/
! static void
exportFile(PGconn *conn, Oid lobjId, char *filename)
{
! int lobj_fd;
! char buf[BUFSIZE];
! int nbytes,
! tmp;
! int fd;
!
! /*
! * open the large object
! */
! lobj_fd = lo_open(conn, lobjId, INV_READ);
! if (lobj_fd < 0)
! fprintf(stderr, "cannot open large object %u", lobjId);
!
! /*
! * open the file to be written to
! */
! fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
! if (fd < 0)
! { /* error */
! fprintf(stderr, "cannot open unix file\"%s\"",
! filename);
! }
!
! /*
! * read in from the inversion file and write to the Unix file
! */
! while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
! {
! tmp = write(fd, buf, nbytes);
! if (tmp < nbytes)
! {
! fprintf(stderr, "error while writing \"%s\"",
! filename);
! }
! }
!
! lo_close(conn, lobj_fd);
! close(fd);
!
! return;
}
! static void
exit_nicely(PGconn *conn)
{
! PQfinish(conn);
! exit(1);
}
int
main(int argc, char **argv)
{
! char *in_filename,
! *out_filename;
! char *database;
! Oid lobjOid;
! PGconn *conn;
! PGresult *res;
!
! if (argc != 4)
! {
! fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
! argv[0]);
! exit(1);
! }
!
! database = argv[1];
! in_filename = argv[2];
! out_filename = argv[3];
!
! /*
! * set up the connection
! */
! conn = PQsetdb(NULL, NULL, NULL, NULL, database);
!
! /* check to see that the backend connection was successfully made */
! if (PQstatus(conn) != CONNECTION_OK)
! {
! fprintf(stderr, "Connection to database failed: %s",
! PQerrorMessage(conn));
! exit_nicely(conn);
! }
!
! res = PQexec(conn, "begin");
! PQclear(res);
! printf("importing file \"%s\" ...\n", in_filename);
! /* lobjOid = importFile(conn, in_filename); */
! lobjOid = lo_import(conn, in_filename);
! if (lobjOid == 0)
! fprintf(stderr, "%s\n", PQerrorMessage(conn));
! else
! {
! printf("\tas large object %u.\n", lobjOid);
!
! printf("picking out bytes 1000-2000 of the large object\n");
! pickout(conn, lobjOid, 1000, 1000);
!
! printf("overwriting bytes 1000-2000 of the large object with X's\n");
! overwrite(conn, lobjOid, 1000, 1000);
!
! printf("exporting large object to file \"%s\" ...\n", out_filename);
! /* exportFile(conn, lobjOid, out_filename); */
! if (lo_export(conn, lobjOid, out_filename) < 0)
! fprintf(stderr, "%s\n", PQerrorMessage(conn));
! }
!
! res = PQexec(conn, "end");
! PQclear(res);
! PQfinish(conn);
! return 0;
}
]]>
</programlisting>
view thread (7+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: old testlo example code
In-Reply-To: <CAK3UJRFJEU1bUjRrxjs2kZcOA=Q+Vu+MPcCGnko+3DS05ZhCTw@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox