mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			816 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			816 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <HTML>
 | |
| <HEAD>
 | |
| 	<TITLE>The POSTGRES95 User Manual - LIBPQ</TITLE>
 | |
| </HEAD>
 | |
| 
 | |
| <BODY>
 | |
| 
 | |
| <font size=-1>
 | |
| <A HREF="pg95user.html">[ TOC ]</A> 
 | |
| <A HREF="xindex.html">[ Previous ]</A> 
 | |
| <A HREF="lobj.html">[ Next ]</A> 
 | |
| </font>
 | |
| <HR>
 | |
| <H1>12.  <B>LIBPQ</B></H1>
 | |
| <HR>
 | |
|      <B>LIBPQ</B> is the application programming interface to POSTGRES.  
 | |
|      <B>LIBPQ</B> is a set of library routines which  allows
 | |
|      client programs to pass queries to the POSTGRES backend
 | |
|      server and to receive the results of these queries.
 | |
|      This version  of  the  documentation  describes  the  <B>C</B>
 | |
|      interface  library.   Three short programs are included
 | |
|      at the end of this section to show how  to  write  programs that use <B>LIBPQ</B>.
 | |
|      There are several examples of <B>LIBPQ</B> applications in the
 | |
|      following directories:
 | |
|      
 | |
| <pre>         ../src/test/regress
 | |
|          ../src/test/examples
 | |
|          ../src/bin/psql
 | |
| </pre>
 | |
|      Frontend programs which  use  <B>LIBPQ</B>  must  include  the
 | |
|      header  file  <CODE>libpq-fe.h</CODE>  and  must link with the <B>libpq</B>
 | |
|      library.
 | |
| 
 | |
| <H2><A NAME="control-and-initialization">12.1.  Control and Initialization</A></H2>
 | |
|      The following environment variables can be used to  set
 | |
|      up  default  environment  values  to  avoid hard-coding
 | |
|      database names into an application program:
 | |
|      
 | |
| <UL>
 | |
|      <LI><B>PGHOST</B> sets the default server name.
 | |
|      <LI><B>PGOPTIONS</B> sets additional runtime  options  for  the POSTGRES backend.
 | |
|      <LI><B>PGPORT</B>  sets the default port for communicating with the POSTGRES backend.
 | |
|      <LI><B>PGTTY</B> sets the file or tty on which  debugging  messages from the backend server are displayed.
 | |
|      <LI><B>PGDATABASE</B>  sets the default POSTGRES database name.
 | |
|      <LI><B>PGREALM</B> sets the Kerberos realm to  use  with  POSTGRES,  if  it is different from the local realm.  If
 | |
|      <LI><B>PGREALM</B> is set, POSTGRES applications  will  attempt
 | |
|         authentication  with  servers for this realm and use
 | |
|         separate ticket files to avoid conflicts with  local
 | |
|         ticket  files.   This  environment  variable is only
 | |
|         used if Kerberos authentication is enabled.
 | |
| </UL>
 | |
| 
 | |
| <H2><A NAME="database-connection-functions">12.2.  Database Connection Functions</A></H2>
 | |
|      The following routines deal with making a connection to
 | |
|      a backend from a <B>C</B> program.
 | |
|      
 | |
|      <DL>
 | |
|        <DT><B>PQsetdb</B> 
 | |
|           <DD>Makes a new connection to a backend.
 | |
| <pre>              PGconn *PQsetdb(char *pghost,
 | |
|                               char *pgport,
 | |
|                               char *pgoptions,
 | |
|                               char *pgtty,
 | |
|                               char *dbName);
 | |
| </pre>
 | |
|           <DD>If  any  argument  is NULL, then the corresponding
 | |
|           environment variable is checked. If the  environment  variable  is  also  not  set, then hardwired
 | |
|           defaults are used.
 | |
|           <DD>PQsetdb always returns  a  valid  PGconn  pointer.
 | |
|           <DD>The  PQstatus (see below) command should be called
 | |
|           to ensure that  a  connection  was  properly  made
 | |
|           before queries are sent via the connection.  <B>LIBPQ</B>
 | |
|           programmers should  be  careful  to  maintain  the
 | |
|           <DD>PGconn  abstraction.   Use  the accessor functions
 | |
|           below to get at the  contents  of  PGconn.   Avoid
 | |
|           directly  referencing  the  fields  of  the PGconn
 | |
|           structure as they are subject  to  change  in  the
 | |
|           future.<br>
 | |
|        <DT><B>PQdb</B>  
 | |
|          <DD>Returns the database name of the connection.
 | |
| <pre>              char *PQdb(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQhost</B>
 | |
|          <DD>Returns the host name of the connection.
 | |
| <pre>              char *PQhost(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQoptions</B>
 | |
|        <DD>Returns the pgoptions used in  the  connection.
 | |
| <pre>              char *PQoptions(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQport</B>
 | |
|          <DD>Returns the pgport of the connection.
 | |
| <pre>              char *PQport(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQtty</B>
 | |
|          <DD>Returns the pgtty of the connection.
 | |
| <pre>              char *PQtty(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQstatus</B>
 | |
|          <DD>Returns the status of the connection. 
 | |
|          <DD>The status can be CONNECTION_OK or CONNECTION_BAD.
 | |
| <pre>              ConnStatusType *PQstatus(PGconn *conn)
 | |
| </pre><br>
 | |
|        <DT><B>PQerrorMessage</B>
 | |
|          <DD>Returns the error  message  associated with the connection
 | |
| <pre>              char *PQerrorMessage(PGconn* conn);
 | |
| </pre><br>
 | |
| 
 | |
|        <DT><B>PQfinish</B>
 | |
|           <DD>Close  the  connection to the backend.  Also frees
 | |
|           memory used by the PGconn structure.   The  PGconn
 | |
|           pointer should not be used after PQfinish has been
 | |
|           called.
 | |
| <pre>              void PQfinish(PGconn *conn)
 | |
| </pre><br>
 | |
|      <DT><B>PQreset</B>
 | |
|           <DD>Reset the communication  port  with  the  backend.
 | |
|           This function will close the IPC socket connection
 | |
|           to the backend and attempt to  reestablish  a  new
 | |
|           connection to the same backend.
 | |
| <pre>              void PQreset(PGconn *conn)
 | |
| </pre><br>
 | |
|      <DT><B>PQtrace</B>
 | |
|           <DD>Enables  tracing  of  messages  passed between the
 | |
|           frontend and the backend.  The messages are echoed
 | |
|           to the debug_port file stream.
 | |
| <pre>              void PQtrace(PGconn *conn,
 | |
|                            FILE* debug_port);
 | |
| </pre><br>
 | |
|      <DT><B>PQuntrace</B>
 | |
|           <DD>Disables  tracing  of  messages passed between the
 | |
|           frontend and the backend.
 | |
| <pre>              void PQuntrace(PGconn *conn);
 | |
| </pre><br>
 | |
| </DL>
 | |
| <H2><A NAME="query-execution-functions">12.3.  Query Execution Functions</A></H2>
 | |
| <DL>
 | |
|      <DT><B>PQexec</B>
 | |
|           <DD>Submit a query to POSTGRES.   Returns  a  PGresult
 | |
|           pointer if the query was successful or a NULL otherwise.  If a NULL is returned, PQerrorMessage can
 | |
|           be used to get more information about the error.
 | |
| <pre>              PGresult *PQexec(PGconn *conn,
 | |
|                                char *query);
 | |
| </pre>
 | |
|           <DD>The  <B>PGresult</B>  structure  encapsulates  the  query
 | |
|           result returned by the backend.  <B>LIBPQ</B> programmers
 | |
|           should   be   careful  to  maintain  the  PGresult
 | |
|           abstraction. Use the accessor functions  described
 | |
|           below to retrieve the results of the query.  Avoid
 | |
|           directly referencing the fields  of  the  PGresult
 | |
|           structure  as  they  are  subject to change in the
 | |
|           future.<br>
 | |
|      <DT><B>PQresultStatus</B>
 | |
|           <DD>Returns the result status of the query.  PQresultStatus can return one of the following values:
 | |
| <pre>              PGRES_EMPTY_QUERY,
 | |
|               PGRES_COMMAND_OK,  /* the query was a command */
 | |
|               PGRES_TUPLES_OK,  /* the query successfully returned tuples */
 | |
|               PGRES_COPY_OUT,
 | |
|               PGRES_COPY_IN,
 | |
|               PGRES_BAD_RESPONSE, /* an unexpected response was received */
 | |
|               PGRES_NONFATAL_ERROR,
 | |
|               PGRES_FATAL_ERROR
 | |
| </pre>
 | |
|           <DD>If  the result status is PGRES_TUPLES_OK, then the
 | |
|           following routines can be  used  to  retrieve  the
 | |
|           tuples returned by the query.<br>
 | |
|           <DT><B>PQntuples</B> returns the number of tuples (instances)
 | |
|           in the query result.
 | |
|           
 | |
| <pre>              int PQntuples(PGresult *res);
 | |
| </pre><br>
 | |
|           <DT><B>PQnfields</B>
 | |
|           <DD>Returns   the   number    of    fields
 | |
|           (attributes) in the query result.
 | |
|           
 | |
| <pre>              int PQnfields(PGresult *res);
 | |
| </pre><br>
 | |
|           <DT><B>PQfname</B>
 | |
|             <DD>Returns the field (attribute) name associated with the given field  index.   Field  indices
 | |
|           start at 0.
 | |
|           
 | |
| <pre>              char *PQfname(PGresult *res,
 | |
|                            int field_index);
 | |
| </pre><br>
 | |
|           <DT><B>PQfnumber</B>
 | |
|             <DD>Returns  the  field  (attribute)  index
 | |
|           associated with the given field name.
 | |
|           
 | |
| <pre>              int PQfnumber(PGresult *res,
 | |
|                            char* field_name);
 | |
| </pre><br>
 | |
|           <DT><B>PQftype</B>
 | |
|             <DD>Returns the field type associated with the
 | |
|           given  field  index.  The  integer  returned is an
 | |
|           internal coding of the type.  Field indices  start
 | |
|           at 0.
 | |
|           
 | |
| <pre>              Oid PQftype(PGresult *res,
 | |
|                           int field_num);
 | |
| </pre><br>
 | |
|           <DT><B>PQfsize</B>
 | |
|             <DD>Returns  the  size  in bytes of the field
 | |
|           associated with the given field index. If the size
 | |
|           returned  is  -1,  the  field is a variable length
 | |
|           field.  Field indices start at 0.
 | |
|           
 | |
| <pre>              int2 PQfsize(PGresult *res,
 | |
|                            int field_index);
 | |
| </pre><br>
 | |
|           <DT><B>PQgetvalue</B>
 | |
|             <DD>Returns the  field  (attribute)  value.
 | |
|           For most queries, the value returned by PQgetvalue
 | |
|           is a null-terminated ASCII  string  representation
 | |
|           of the attribute value.  If the query was a result
 | |
|           of a <B>BINARY</B> cursor, then  the  value  returned  by
 | |
|           PQgetvalue  is  the  binary  representation of the
 | |
|           type in the internal format of the backend server.
 | |
|           It  is the programmer's responsibility to cast and
 | |
|           convert the data to the correct C type.  The value
 | |
|           returned  by  PQgetvalue points to storage that is
 | |
|           part of the PGresult structure.  One must  explicitly 
 | |
|           copy the value into other storage if it is to
 | |
|           be used past the lifetime of the  PGresult  structure itself.
 | |
|           
 | |
| <pre>              char* PQgetvalue(PGresult *res,
 | |
|                                int tup_num,
 | |
|                                int field_num);
 | |
| </pre><br>
 | |
|           <DT><B>PQgetlength</B>
 | |
|             <DD>Returns   the   length  of  a  field
 | |
|           (attribute) in bytes.  If the field  is  a  struct
 | |
|           varlena, the length returned here does not include
 | |
|           the size field of the varlena, i.e., it is 4 bytes
 | |
|           less.
 | |
| <pre>              int PQgetlength(PGresult *res,
 | |
|                               int tup_num,
 | |
|                               int field_num);
 | |
| </pre><br>
 | |
|      <DT><B>PQcmdStatus</B>
 | |
|           Returns  the  command  status  associated with the
 | |
|           last query command.
 | |
| <pre>
 | |
|               char *PQcmdStatus(PGresult *res);
 | |
| </pre><br>
 | |
|      <DT><B>PQoidStatus</B>
 | |
|           Returns a string with the object id of  the  tuple
 | |
|           inserted  if  the last query is an INSERT command.
 | |
|           Otherwise, returns an empty string.
 | |
| <pre>              char* PQoidStatus(PGresult *res);
 | |
| </pre><br>
 | |
|      <DT><B>PQprintTuples</B>
 | |
|           Prints out all the  tuples  and,  optionally,  the
 | |
|           attribute  names  to  the specified output stream.
 | |
|           The programs psql and monitor  both  use  PQprintTuples for output.
 | |
|           
 | |
| <pre>              void PQprintTuples(
 | |
|                      PGresult* res,
 | |
|                      FILE* fout,      /* output stream */
 | |
|                      int printAttName,/* print attribute names or not*/
 | |
|                      int terseOutput, /* delimiter bars or not?*/
 | |
|                      int width        /* width of column, variable width if 0*/
 | |
|                      );
 | |
| </pre><br>
 | |
| 
 | |
|      <DT><B>PQclear</B>
 | |
|           Frees  the  storage  associated with the PGresult.
 | |
|           Every query result should be properly  freed  when
 | |
|           it  is  no  longer  used.  Failure to do this will
 | |
|           result in memory leaks in  the  frontend  application.
 | |
| <pre>              void PQclear(PQresult *res);
 | |
| </pre><br>
 | |
| </DL>
 | |
| <H2><A NAME="fast-path">12.4.  Fast Path</A></H2>
 | |
|      POSTGRES  provides  a fast path interface to send function calls to the backend.  This  is  a  trapdoor  into
 | |
|      system  internals and can be a potential security hole.
 | |
|      Most users will not need this feature.
 | |
|      
 | |
| <pre>         PGresult* PQfn(PGconn* conn,
 | |
|                      int fnid,
 | |
|                      int *result_buf,
 | |
|                      int *result_len,
 | |
|                      int result_is_int,
 | |
|                      PQArgBlock *args,
 | |
|                      int nargs);
 | |
| </pre><br>
 | |
| 
 | |
|      The fnid argument is the object identifier of the function to be executed.  result_buf is the buffer in which
 | |
|      to load the return value.  The caller must  have  allocated  sufficient space to store the return value.  The
 | |
|      result length will be returned in the  storage  pointed
 | |
|      to  by  result_len.   If the result is to be an integer
 | |
|      value, than result_is_int should be set to 1; otherwise
 | |
|      it  should  be  set  to  0.  args and nargs specify the
 | |
|      arguments to the function.
 | |
| <pre>         typedef struct {
 | |
|              int len;
 | |
|              int isint;
 | |
|              union {
 | |
|                  int *ptr;
 | |
|               int integer;
 | |
|              } u;
 | |
|          } PQArgBlock;
 | |
| </pre>
 | |
|      PQfn always returns a valid PGresult*.  The  resultStatus  should be checked before the result is used.   The
 | |
|      caller is responsible for  freeing  the  PGresult  with
 | |
|      PQclear when it is not longer needed.
 | |
| <H2><A NAME="asynchronous-notification">12.5.  Asynchronous Notification</A></H2>
 | |
|      POSTGRES  supports  asynchronous  notification  via the
 | |
|      LISTEN and NOTIFY commands.  A  backend  registers  its
 | |
|      interest  in a particular relation with the LISTEN command.  All backends listening on a particular  relation
 | |
|      will  be  notified asynchronously when a NOTIFY of that
 | |
|      relation name  is  executed  by  another  backend.   No
 | |
|      additional  information  is passed from the notifier to
 | |
|      the listener.  Thus, typically, any  actual  data  that
 | |
|      needs  to  be  communicated  is transferred through the
 | |
|      relation.
 | |
|      <B>LIBPQ</B> applications are notified  whenever  a  connected
 | |
|      backend  has  received  an  asynchronous  notification.
 | |
|      However, the communication  from  the  backend  to  the
 | |
|      frontend   is  not  asynchronous.   Notification  comes
 | |
|      piggy-backed on other query results.  Thus, an application  must submit queries, even empty ones, in order to
 | |
|      receive notice of backend notification.  In effect, the
 | |
|      <B>LIBPQ</B> application must poll the backend to see if there
 | |
|      is any pending  notification  information.   After  the
 | |
|      execution of a query, a frontend may call PQNotifies to
 | |
|      see if any notification  data  is  available  from  the
 | |
|      backend.
 | |
| <DL>
 | |
|      <DT><B>PQNotifies</B>
 | |
|           <DD>returns  the notification from a list of unhandled
 | |
|           notifications from the backend.  Returns  NULL  if
 | |
|           there  are no pending notifications from the backend.  PQNotifies behaves like  the  popping  of  a
 | |
|           stack.  Once a notification is returned from PQnotifies, it  is  considered  handled  and  will  be
 | |
|           removed from the list of notifications.
 | |
| <pre>              PGnotify* PQNotifies(PGconn *conn);
 | |
| </pre><br>
 | |
| </DL>
 | |
|      The  second  sample program gives an example of the use
 | |
|      of asynchronous notification.
 | |
| <H2><A NAME="functions-associated-with-the-copy-command">12.6.  Functions Associated with the COPY Command</A></H2>
 | |
|      The copy command in POSTGRES has options to  read  from
 | |
|      or  write  to  the  network  connection  used by <B>LIBPQ</B>.
 | |
|      Therefore, functions are necessary to access this  network  connection directly so applications may take full
 | |
|      advantage of this capability.
 | |
| <DL>
 | |
|      <DT><B>PQgetline</B>
 | |
|           <DD>Reads  a  newline-terminated  line  of  characters
 | |
|           (transmitted  by the backend server) into a buffer
 | |
|           string of size length.  Like fgets(3),  this  routine copies up to length-1 characters into string.
 | |
|           It is like gets(3), however, in that  it  converts
 | |
|           the terminating newline into a null character.
 | |
|           PQgetline returns EOF at EOF, 0 if the entire line
 | |
|           has been read, and 1 if the buffer is full but the
 | |
|           terminating newline has not yet been read.
 | |
|           Notice that the application must check to see if a
 | |
|           new line consists of  the  single  character  ".",
 | |
|           which  indicates  that the backend server has finished sending the results  of  the  copy  command.
 | |
|           Therefore,  if  the  application  ever  expects to
 | |
|           receive lines that are more than length-1  characters  long,  the application must be sure to check
 | |
|           the return value of PQgetline very carefully.
 | |
|           The code in
 | |
|           
 | |
| <pre>              ../src/bin/psql/psql.c
 | |
| </pre>
 | |
|           contains routines that correctly handle  the  copy
 | |
|           protocol.
 | |
| <pre>              int PQgetline(PGconn *conn,
 | |
|                             char *string,
 | |
|                             int length)
 | |
| </pre><br>
 | |
|      <DT><B>PQputline</B>
 | |
|           <DD>Sends  a  null-terminated  string  to  the backend
 | |
|           server.
 | |
|           The application must explicitly  send  the  single
 | |
|           character  "."  to indicate to the backend that it
 | |
|           has finished sending its data.
 | |
|           
 | |
| <pre>              void PQputline(PGconn *conn,
 | |
|                              char *string);
 | |
| </pre><br>
 | |
|      <DT><B>PQendcopy</B>
 | |
|           <DD>Syncs with the backend.  This function waits until
 | |
|           the  backend  has  finished  the  copy.  It should
 | |
|           either be issued when the  last  string  has  been
 | |
|           sent  to  the  backend using PQputline or when the
 | |
|           last string has been  received  from  the  backend
 | |
|           using PGgetline.  It must be issued or the backend
 | |
|           may get "out of sync"  with  the  frontend.   Upon
 | |
|           return from this function, the backend is ready to
 | |
|           receive the next query.
 | |
|           The return value is 0  on  successful  completion,
 | |
|           nonzero otherwise.
 | |
| <pre>              int PQendcopy(PGconn *conn);
 | |
| </pre><br>
 | |
|           As an example:
 | |
| <pre>              PQexec(conn, "create table foo (a int4, b char16, d float8)");
 | |
|               PQexec(conn, "copy foo from stdin");
 | |
|               PQputline(conn, "3<TAB>hello world<TAB>4.5\n");
 | |
|               PQputline(conn,"4<TAB>goodbye world<TAB>7.11\n");
 | |
|               ...
 | |
|               PQputline(conn,".\n");
 | |
|               PQendcopy(conn);
 | |
| </pre><br>
 | |
| </DL>
 | |
| <H2><A NAME="tracing-functions">12.7.  <B>LIBPQ</B> Tracing Functions</A></H2>
 | |
| <DL>
 | |
|      <DT><B>PQtrace</B>
 | |
|           <DD>Enable  tracing of the frontend/backend communication to a debugging file stream.
 | |
| <pre>              void PQtrace(PGconn *conn
 | |
|                            FILE *debug_port)
 | |
| </pre><br>
 | |
| 
 | |
|      <DT><B>PQuntrace</B>
 | |
|           <DD>Disable tracing started by PQtrace
 | |
| <pre>              void PQuntrace(PGconn *conn)
 | |
| </pre><br>
 | |
| </DL>
 | |
| <H2><A NAME="authentication-functions">12.8.  User Authentication Functions</A></H2>
 | |
|      If the user has generated the  appropriate  authentication  credentials  (e.g.,  obtaining <B>Kerberos</B> tickets),
 | |
|      the frontend/backend authentication process is  handled
 | |
|      by  <B>PQexec</B>  without any further intervention.  The following routines may be called by <B>LIBPQ</B> programs to tailor the behavior of the authentication process.
 | |
| <DL>
 | |
|      <DT><B>fe_getauthname</B>
 | |
|           <DD>Returns a pointer to static space containing whatever name the user has authenticated.  Use of this
 | |
|           routine  in  place  of calls to getenv(3) or getpwuid(3) by applications is highly recommended,  as
 | |
|           it  is  entirely  possible  that the authenticated
 | |
|           user name is not the same as  value  of  the  <B>USER</B>
 | |
|           environment   variable  or  the  user's  entry  in
 | |
|           <CODE>/etc/passwd</CODE>.
 | |
|           
 | |
| <pre>              char *fe_getauthname(char* errorMessage)
 | |
| </pre><br>
 | |
|      <DT><B>fe_setauthsvc</B>
 | |
|           <DD>Specifies that  <B>LIBPQ</B>  should  use  authentication
 | |
|           service  name rather than its compiled-in default.
 | |
|           <DD>This value is typically taken from a  command-line
 | |
|           switch.
 | |
| <pre>              void fe_setauthsvc(char *name,
 | |
|                                  char* errorMessage)
 | |
| </pre>
 | |
|           <DD>Any   error   messages   from  the  authentication
 | |
|           attempts are returned in  the  errorMessage  argument.
 | |
| </DL>          
 | |
| 
 | |
| <H2><A NAME="bugs">12.9.  BUGS</A></H2>
 | |
|      The  query  buffer is 8192 bytes long, and queries over
 | |
|      that length will be silently truncated.
 | |
| <H2><A NAME="sample-programs">12.10.  Sample Programs</H2>
 | |
| <p>
 | |
| <H3><A NAME="sample-program-1">12.10.1.  Sample Program 1</A></H3>
 | |
| <pre>
 | |
|          /*
 | |
|           * testlibpq.c
 | |
|           *   Test the C version of LIBPQ, the POSTGRES frontend library.
 | |
|           *
 | |
|           *
 | |
|           */
 | |
|          #include <stdio.h>
 | |
|          #include "libpq-fe.h"
 | |
| <p>
 | |
|          void
 | |
|          exit_nicely(PGconn* conn)
 | |
|          {
 | |
|            PQfinish(conn);
 | |
|            exit(1);
 | |
|          }
 | |
| <p>
 | |
|          main()
 | |
|          {
 | |
|            char *pghost, *pgport, *pgoptions, *pgtty;
 | |
|            char* dbName;
 | |
|            int nFields;
 | |
|            int i,j;
 | |
| <p>
 | |
|          /*  FILE *debug; */
 | |
| <p>
 | |
|            PGconn* conn;
 | |
|            PGresult* res;
 | |
| <p>
 | |
|            /* begin, by setting the parameters for a backend connection
 | |
|               if the parameters are null, then the system will try to use
 | |
|               reasonable defaults by looking up environment variables
 | |
|               or, failing that, using hardwired constants */
 | |
|            pghost = NULL;  /* host name of the backend server */
 | |
|            pgport = NULL;  /* port of the backend server */
 | |
|            pgoptions = NULL; /* special options to start up the backend server */
 | |
|            pgtty = NULL;     /* debugging tty for the backend server */
 | |
|            dbName = "template1";
 | |
| <p>
 | |
|            /* make a connection to the database */
 | |
|            conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
 | |
| <p>
 | |
|            /* check to see that the backend connection was successfully made */
 | |
|            if (PQstatus(conn) == CONNECTION_BAD) {
 | |
|              fprintf(stderr,"Connection to database '%s' failed.0, dbName);
 | |
|              fprintf(stderr,"%s",PQerrorMessage(conn));
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
| <p>
 | |
|          /*  debug = fopen("/tmp/trace.out","w");  */
 | |
|          /*   PQtrace(conn, debug);  */
 | |
| <p>
 | |
|            /* start a transaction block */
 | |
| 
 | |
|            res = PQexec(conn,"BEGIN");
 | |
|            if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 | |
|              fprintf(stderr,"BEGIN command failed0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
|            /* should PQclear PGresult whenever it is no longer needed to avoid
 | |
|               memory leaks */
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* fetch instances from the pg_database, the system catalog of databases*/
 | |
|            res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database");
 | |
|            if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 | |
|              fprintf(stderr,"DECLARE CURSOR command failed0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            res = PQexec(conn,"FETCH ALL in myportal");
 | |
|            if (PQresultStatus(res) != PGRES_TUPLES_OK) {
 | |
|              fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
| <p>
 | |
|            /* first, print out the attribute names */
 | |
|            nFields = PQnfields(res);
 | |
|            for (i=0; i < nFields; i++) {
 | |
|              printf("%-15s",PQfname(res,i));
 | |
|            }
 | |
|            printf("0);
 | |
| <p>
 | |
|            /* next, print out the instances */
 | |
|            for (i=0; i < PQntuples(res); i++) {
 | |
|              for (j=0  ; j < nFields; j++) {
 | |
|                printf("%-15s", PQgetvalue(res,i,j));
 | |
|              }
 | |
|              printf("0);
 | |
|            }
 | |
| <p>
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* close the portal */
 | |
|            res = PQexec(conn, "CLOSE myportal");
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* end the transaction */
 | |
|            res = PQexec(conn, "END");
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* close the connection to the database and cleanup */
 | |
|            PQfinish(conn);
 | |
| 
 | |
|          /*   fclose(debug); */
 | |
|          }
 | |
| </pre>
 | |
| <p>
 | |
| <H3><A NAME="sample-program-2">12.10.2.  Sample Program 2</A></H3>
 | |
| <pre>
 | |
|          /*
 | |
|           * testlibpq2.c
 | |
|           *   Test of the asynchronous notification interface
 | |
|           *
 | |
|             populate a database with the following:
 | |
| <p>
 | |
|          CREATE TABLE TBL1 (i int4);
 | |
| <p>
 | |
|          CREATE TABLE TBL2 (i int4);
 | |
| <p>
 | |
|          CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
 | |
| <p>
 | |
|           * Then start up this program
 | |
|           * After the program has begun, do
 | |
| <p>
 | |
|          INSERT INTO TBL1 values (10);
 | |
| <p>
 | |
|           *
 | |
|           *
 | |
|           */
 | |
|          #include <stdio.h>
 | |
|          #include "libpq-fe.h"
 | |
| <p>
 | |
|          void exit_nicely(PGconn* conn)
 | |
|          {
 | |
|            PQfinish(conn);
 | |
|            exit(1);
 | |
|          }
 | |
| <p>
 | |
|          main()
 | |
|          {
 | |
|            char *pghost, *pgport, *pgoptions, *pgtty;
 | |
|            char* dbName;
 | |
|            int nFields;
 | |
|            int i,j;
 | |
| <p>
 | |
|            PGconn* conn;
 | |
|            PGresult* res;
 | |
|            PGnotify* notify;
 | |
| <p>
 | |
|            /* begin, by setting the parameters for a backend connection
 | |
|               if the parameters are null, then the system will try to use
 | |
|               reasonable defaults by looking up environment variables
 | |
|               or, failing that, using hardwired constants */
 | |
|            pghost = NULL;  /* host name of the backend server */
 | |
|            pgport = NULL;  /* port of the backend server */
 | |
|            pgoptions = NULL; /* special options to start up the backend server */
 | |
|            pgtty = NULL;     /* debugging tty for the backend server */
 | |
|            dbName = getenv("USER"); /* change this to the name of your test database*/
 | |
| <p>
 | |
|            /* make a connection to the database */
 | |
|            conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
 | |
| 
 | |
|            /* check to see that the backend connection was successfully made */
 | |
|            if (PQstatus(conn) == CONNECTION_BAD) {
 | |
|              fprintf(stderr,"Connection to database '%s' failed.0, dbName);
 | |
|              fprintf(stderr,"%s",PQerrorMessage(conn));
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
| <p>
 | |
|            res = PQexec(conn, "LISTEN TBL2");
 | |
|            if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 | |
|              fprintf(stderr,"LISTEN command failed0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
|            /* should PQclear PGresult whenever it is no longer needed to avoid
 | |
|               memory leaks */
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            while (1) {
 | |
|                /* async notification only come back as a result of a query*/
 | |
|                /* we can send empty queries */
 | |
|                res = PQexec(conn, " ");
 | |
|          /*      printf("res->status = %s0, pgresStatus[PQresultStatus(res)]); */
 | |
|                /* check for asynchronous returns */
 | |
|                notify = PQnotifies(conn);
 | |
|                if (notify) {
 | |
|                 fprintf(stderr,
 | |
|                      "ASYNC NOTIFY of '%s' from backend pid '%d' received0,
 | |
|                      notify->relname, notify->be_pid);
 | |
|                 free(notify);
 | |
|                 break;
 | |
|                }
 | |
|                PQclear(res);
 | |
|            }
 | |
| <p>
 | |
|            /* close the connection to the database and cleanup */
 | |
|            PQfinish(conn);
 | |
| <p>
 | |
|          }
 | |
| </pre>
 | |
| <p>
 | |
| <H3><A NAME="sample-program-3">12.10.3.  Sample Program 3</A></H3>
 | |
| <pre>
 | |
|          /*
 | |
|           * testlibpq3.c
 | |
|           *   Test the C version of LIBPQ, the POSTGRES frontend library.
 | |
|           *   tests the binary cursor interface
 | |
|           *
 | |
|           *
 | |
|           *
 | |
|           populate a database by doing the following:
 | |
| <p>
 | |
|          CREATE TABLE test1 (i int4, d float4, p polygon);
 | |
| <p>
 | |
|          INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
 | |
| <p>
 | |
|          INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
 | |
| <p>
 | |
|           the expected output is:
 | |
| <p>
 | |
|          tuple 0: got
 | |
|           i = (4 bytes) 1,
 | |
|           d = (4 bytes) 3.567000,
 | |
|           p = (4 bytes) 2 points         boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
 | |
|          tuple 1: got
 | |
|           i = (4 bytes) 2,
 | |
|           d = (4 bytes) 89.050003,
 | |
|           p = (4 bytes) 2 points         boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
 | |
| <p>
 | |
|           *
 | |
|           */
 | |
|          #include <stdio.h>
 | |
|          #include "libpq-fe.h"
 | |
|          #include "utils/geo-decls.h" /* for the POLYGON type */
 | |
| <p>
 | |
|          void exit_nicely(PGconn* conn)
 | |
|          {
 | |
|            PQfinish(conn);
 | |
|            exit(1);
 | |
|          }
 | |
| <p>
 | |
|          main()
 | |
|          {
 | |
|            char *pghost, *pgport, *pgoptions, *pgtty;
 | |
|            char* dbName;
 | |
|            int nFields;
 | |
|            int i,j;
 | |
|            int i_fnum, d_fnum, p_fnum;
 | |
| <p>
 | |
|            PGconn* conn;
 | |
|            PGresult* res;
 | |
| <p>
 | |
|            /* begin, by setting the parameters for a backend connection
 | |
|               if the parameters are null, then the system will try to use
 | |
|               reasonable defaults by looking up environment variables
 | |
|               or, failing that, using hardwired constants */
 | |
|            pghost = NULL;  /* host name of the backend server */
 | |
|            pgport = NULL;  /* port of the backend server */
 | |
|            pgoptions = NULL; /* special options to start up the backend server */
 | |
|            pgtty = NULL;     /* debugging tty for the backend server */
 | |
| <p>
 | |
|            dbName = getenv("USER");  /* change this to the name of your test database*/
 | |
| <p>
 | |
|            /* make a connection to the database */
 | |
|            conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
 | |
| <p>
 | |
|            /* check to see that the backend connection was successfully made */
 | |
|            if (PQstatus(conn) == CONNECTION_BAD) {
 | |
|              fprintf(stderr,"Connection to database '%s' failed.0, dbName);
 | |
|              fprintf(stderr,"%s",PQerrorMessage(conn));
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
| <p>
 | |
|            /* start a transaction block */
 | |
|            res = PQexec(conn,"BEGIN");
 | |
|            if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 | |
|              fprintf(stderr,"BEGIN command failed0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
|            /* should PQclear PGresult whenever it is no longer needed to avoid
 | |
|               memory leaks */
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* fetch instances from the pg_database, the system catalog of databases*/
 | |
|            res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * from test1");
 | |
|            if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 | |
|              fprintf(stderr,"DECLARE CURSOR command failed0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            res = PQexec(conn,"FETCH ALL in mycursor");
 | |
|            if (PQresultStatus(res) != PGRES_TUPLES_OK) {
 | |
|              fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
 | |
|              PQclear(res);
 | |
|              exit_nicely(conn);
 | |
|            }
 | |
| <p>
 | |
|            i_fnum = PQfnumber(res,"i");
 | |
|            d_fnum = PQfnumber(res,"d");
 | |
|            p_fnum = PQfnumber(res,"p");
 | |
| <p>
 | |
|            for (i=0;i<3;i++) {
 | |
|                printf("type[%d] = %d, size[%d] = %d0,
 | |
|                    i, PQftype(res,i),
 | |
|                    i, PQfsize(res,i));
 | |
|            }
 | |
|            for (i=0; i < PQntuples(res); i++) {
 | |
|              int *ival;
 | |
|              float *dval;
 | |
|              int plen;
 | |
|              POLYGON* pval;
 | |
|              /* we hard-wire this to the 3 fields we know about */
 | |
|              ival =  (int*)PQgetvalue(res,i,i_fnum);
 | |
|              dval =  (float*)PQgetvalue(res,i,d_fnum);
 | |
|              plen = PQgetlength(res,i,p_fnum);
 | |
| <p>
 | |
|              /* plen doesn't include the length field so need to increment by VARHDSZ*/
 | |
|              pval = (POLYGON*) malloc(plen + VARHDRSZ);
 | |
|              pval->size = plen;
 | |
|              memmove((char*)&pval->npts, PQgetvalue(res,i,p_fnum), plen);
 | |
|              printf("tuple %d: got0, i);
 | |
|              printf(" i = (%d bytes) %d,0,
 | |
|                  PQgetlength(res,i,i_fnum), *ival);
 | |
|              printf(" d = (%d bytes) %f,0,
 | |
|                  PQgetlength(res,i,d_fnum), *dval);
 | |
|              printf(" p = (%d bytes) %d points boundbox = (hi=%f/%f, lo = %f,%f)0,
 | |
|                  PQgetlength(res,i,d_fnum),
 | |
|                  pval->npts,
 | |
|                  pval->boundbox.xh,
 | |
|                  pval->boundbox.yh,
 | |
|                  pval->boundbox.xl,
 | |
|                  pval->boundbox.yl);
 | |
|            }
 | |
| <p>
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* close the portal */
 | |
|            res = PQexec(conn, "CLOSE mycursor");
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* end the transaction */
 | |
|            res = PQexec(conn, "END");
 | |
|            PQclear(res);
 | |
| <p>
 | |
|            /* close the connection to the database and cleanup */
 | |
|            PQfinish(conn);
 | |
| <p>
 | |
|          }
 | |
| </pre>
 | |
| <HR>
 | |
| <font size=-1>
 | |
| <A HREF="pg95user.html">[ TOC ]</A> 
 | |
| <A HREF="xindex.html">[ Previous ]</A> 
 | |
| <A HREF="lobj.html">[ Next ]</A> 
 | |
| </font>
 | |
| </BODY>
 | |
| </HTML>
 |