This is pgin.tcl/REFERENCE, programmer's reference to pgin.tcl.
Last updated for pgin.tcl-1.5.0 on 2003-06-29
-----------------------------------------------------------------------------

For more information on the details of the commands, refer to the libpgtcl
documentation. Pgin.tcl attempts to emulate libpgtcl's command usage and
behavior wherever possible.

(Note: The syntax ?...? refers to optional values, per the Tcl documentation.)


CORE COMMANDS:

     pg_conndefaults
         Returns the connection parameter defaults as a list of elements
         of the following form:
         { OptionName Display-label display-flag display-length default-value }

     pg_connect -conninfo "option=value..."
         Connects to the database. Returns a connection handle conn_handle.
         Commonly used connection option names are:
                 dbname host port user password
         Values need to be in single quotes if they contain spaces.
         Within single quoted values, use \\ for \ and \' for '.

         Note that the older form pg_connect dbname ?-host name ...? is not
         supported. Use the new style instead.
         Parameter values default to environment variables or built-in defaults.

         Host defaults to the environment variable PGHOST, or to "localhost"
         if no PGHOST. (Real libpgtcl defaults to using a Unix Domain Socket
         in that case, but pgin.tcl cannot support UDS.)

     pg_disconnect $conn_handle
         Disconnect from database. Also destroys any left-over result
         structures associated with this connection.

     pg_select $conn_handle "query" arrayName { proc... }
         Execute a query and iterate proc with arrayName set to each tuple.

     pg_exec $conn_handle "query"
         Execute SQL and return a result_handle (which caller must free).

     pg_execute ?-oid oidName? ?-array arrayName? $conn_handle "query" ?proc?
         Execute SQL and return the number of tuples queried or affected.
         This was added to libpgtcl in PostgreSQL 7.1, and can replace both
         pg_exec and pg_select in many cases.
         If -array is not given on a Select, a variable is created for
         each field in the query result.
         If no proc is supplied, only the first query result row is saved.

     pg_result $result_handle option ?args?
         Get information about a result_handle with these options:
         -status          Returns the result status (see notes)
         -error           Returns the error message if status=PGRES_FATAL_ERROR
         -conn            Returns the connection handle for this result
         -oid             Returns the OID of an inserted tuple
         -numTuples       Returns the number of tuples in the result
         -numAttrs        Returns the number of attributes
         -assign A        Assign the query result data to A(tuple,attribName)
         -assignbyidx A s Assign results to an array (see the libpgtcl docs)
         -getTuple N      Return a list of values for tuple N
         -tupleArray A N  Store the Nth tuple in array A as A(attribName)
         -attributes      Return a list of attributes
         -lAttributes     Return a list of attributes as {{name type size}...}
         -cmdTuples       Return number of tuples INSERTed, DELETEd, UPDATEd
         -list            Return result set as a list of values.
         -llist           Return result set as a list of tuple data, each
                          of which is a list of values.
       When finished with a result structure, you must clear it with:
         -clear           Deallocate the result structure
       Notes:
         Result status is one of these string values:
             PGRES_TUPLES_OK PGRES_COMMAND_OK PGRES_FATAL_ERROR
             PGRES_COPY_OUT PGRES_COPY_IN PGRES_EMPTY_QUERY
         -oid returns 0 if the query was not an INSERT.
         -cmdTuples is an extension, expected to be in a future libpgtcl.
             It returns an empty string if the query was not INSERT, UPDATE,
             or DELETE. This is the expected future behavior of libpgtcl.
         -list and -llist are extensions to libpgtcl which were added
             after PostgreSQL-7.2.3 to libpgtcl-1.4.

     pg_listen $conn_handle "name" ?proc?
         Listen for notifications and call procedure proc, or unlisten.

     pg_escape_string $str
         Returns the string str properly escaped for including in SQL
         strings. That is, returns str with single quotes and backslashes
         doubled up.
         Note: This command was added to libpgtcl in CVS after 1.4b release.

-----------------------------------------------------------------------------
EXTENSIONS:

pgin.tcl has some extended commands and variables.

     pg_configure $conn_handle option ?value?
         Query or set an interface option. The $conn_handle names
         the database connection, but is currently ignored: All
         options are global to all connections. If the value is
         supplied, sets the option to that value, and returns the
         previous value. If the value is not supplied, returns the
         current value.

         The following options are available:

               nulls       A string to use for NULL database values.
                           Default value is "", an empty string.

               notice      A command to use when a notice message
                           arrives. See NOTICES below.
                           Default is a procedure which just prints
                           the message to stderr.

               debug       Debug print flag. Default is 0 for off.

     pg_endcopy $result_handle
         This must be called after SQL COPY FROM or COPY TO completes.
         See COPY FROM/TO below.

     pg_copy_read $result_handle
         Read the next line (record) for SQL COPY TO STDOUT.
         Returns the line read, or an empty string when COPY is done.
         Use of this routine is currently optional - you can just use
         "gets" from the connection handle - but see COPY FROM/TO below.

     pg_copy_write $result_handle $line
         Write one line (record) $line for SQL COPY FROM STDIN.
         Use of this routine is currently optional - you can just use
         "puts" to the connection handle - but see COPY FROM/TO below.

     $pgtcl::version
         This variable has the pgin.tcl version number. The existence of
         this variable can also be used to determine if pgin.tcl has been
         loaded.

     pg_callfn $db "fname" result "arginfo" arg...
     pg_callfn_int $db "fname" "arginfo" arg...
         These two calls allow access to the PostgreSQL back-end
         "fast-path" function call interface. This is not intended
         for routine use. See the INTERNALS document for more information.

-----------------------------------------------------------------------------
LARGE OBJECTS:

pgin.tcl implements the Large Object commands of libpgtcl.

Remember that these routines must be used inside transactions. Also note
that these routines do not deal with your own database tables, and in
general PostgreSQL does not attempt to synchronize actual large object
storage with their OID fields in your tables. So for example you will
generally have to pair a database INSERT with a pg_lo_creat, and a database
DELETE with a pg_lo_unlink.

     pg_lo_creat $conn_handle "mode"
         Create a large object. Mode should be one of the strings INV_READ,
         INV_WRITE, or INV_READ|INV_WRITE, although to be honest I do not
         know what the difference is. As an extension, to be compatible with
         pg_lo_open, this command also accepts mode of "r", "w", or "rw".
         Returns a large object OID, which you should promptly insert into
         a table.

     pg_lo_open $conn_handle $loid "mode"
         Open the large object with id $loid in mode "mode". Mode can be "r",
         "w", or "rw" specifying read and/or write. As an extension, to be
         compatible with pg_lo_creat and libPQ, this command also accepts mode
         of INV_READ, INV_WRITE, or "INV_READ|INV_WRITE".
         The $loid usually comes from the return value of pg_lo_creat directly
         or indirectly as an oid-type field in a table.
         Returns a large object file descriptor (a lofd) for use with the
         commands below.

     pg_lo_close $conn_handle $lofd
         Close a large object opened with pg_lo_open.

     pg_lo_unlink $conn_handle $loid
         Delete the large object identified by ID $loid.

     pg_lo_read $conn_handle $lofd buf_name $maxlen
         Read up to $maxlen bytes from the large object $lofd into the
         buffer variable named by buf_name. Returns the number of bytes
         actually read. Returns 0 at the end of the large object.

     pg_lo_write $conn_handle $lofd $buf $len
         Write at most $len bytes from $buf to the open large object $lofd.
         (If $buf has fewer than $len bytes, just write all of $buf.)

     pg_lo_lseek $conn_handle $lofd $offset "whence"
         Reposition the (virtual) file position pointer in the open large
         object identified by $lofd to the position $offset modified by
         "whence", which is one of SEEK_SET, SEEK_CUR, or SEEK_END specifying
         positions relative to start of file, current position, or end of file.

     pg_lo_tell $conn_handle $lofd
         Return the integer (virtual) file offset of the current file position
         pointer in the open large object identified by $lofd.

     pg_lo_import $conn_handle "filename"
         Create a new large object, import the contents of the specified
         file into it, and return the Large Object ID. You should probably
         insert the returned loid into a table promptly.

     pg_lo_export $conn_handle $loid "filename"
         Export the large object identified by ID $loid into the named file.

-----------------------------------------------------------------------------
NOTICES:

If the backend sends a notice, the notice handler will be called with the
text of the notice as the final parameter. The default procedure just
prints the message to stderr (like libPQ does). You may replace this
by defining your own procedure and calling
      pg_configure $conn_handle "notice_command ..."
The actual notice message will be appended as an additional argument to
your command.
(libpgtcl does not provide this capability.)

Note: Don't confuse Notice with Notification. A Notice is from the backend
telling you about something, like index creation as a result of making a
primary key. Notification is a message sent by another database client.

-----------------------------------------------------------------------------
NOTIFICATIONS:

Support for backend notifications differs from libpgtcl. With libpgtcl, the
notification will be received as soon as Tcl enters the idle loop, e.g. if
you use "update". libpgtcl does not need to be reading from the backend to
get a notification. With pgin.tcl, the notification from the backend will
only be seen while something is being read from the backend; that is,
during pg_exec, pg_select, or pg_execute processing. After a notification
is read, it will be delivered the next time Tcl enters the idle loop.

-----------------------------------------------------------------------------
COPY FROM/TO:

Front-end copy is a bulk import or export operation where multiple rows
are sent between the PostgreSQL back-end and client front-end with minimal
formatting. This is implemented in PostgreSQL with the following SQL:
         COPY tablename TO STDOUT;   -- Export table
         COPY tablename FROM STDIN;  -- Import table
Each row is transmitted as one line, with columns separated by a delimiter
which defaults to tab, backslash (\) escaping of control characters, and
\N used for NULL.

(Note: You never have to use COPY FROM/TO. You can always use the standard
SQL SELECT and INSERT instead. COPY FROM/TO is said to be more efficient
for large amounts of data.)

Pgin.tcl provides support for front-end copy, but it is not 100% compatible
with libpgtcl. This is because there is no way for a Tcl script to create
and control an "artificial" I/O channel the way libpgtcl, a C library, does.
To use front-end copy with pgin.tcl, your application needs to take some
extra steps. Described below is a method to make an application compatible
with both libpgtcl and pgin.tcl.

For COPY FROM STDIN, your application must call "pg_endcopy $result_handle"
after writing the special terminator "\\.\n". This allows pgin.tcl to
finish the COPY operation and re-synchronize with the backend.

For COPY TO STDOUT, your application must read until seeing the special
terminator "\\.\n", instead of EOF, then call "pg_endcopy $result_handle".

The following examples illustrates doing COPY FROM and COPY TO in a way
which works with both libpgtcl and pgin.tcl. Error handling during the copy
has been omitted for brevity. (But an error during COPY FROM/TO is likely
to be difficult to recover from without disconnecting and reconnecting.)

Example 1: COPY TO STDOUT:
  1     set result_handle [pg_exec $conn_handle "COPY $table TO STDOUT"]
  2     if {[pg_result $result_handle -status] != "PGRES_COPY_OUT"} {
  3       ... handle error ...
  4     }
  5     while {[gets $conn_handle line] >= 0 && $line != "\\."} {
  6        ... Process data in $line ...
  7     }
  8     if {[info procs pg_endcopy] != ""} {
  9       pg_endcopy $result_handle
 10     }
 11     pg_result $result_handle -clear

Notes on Example 1:
   At line 5, terminate the loop either on EOF (libpgtcl behavior) or on
reading the end of data marker (pgin.tcl behavior).
   At lines 8-10, call pg_endcopy if it exists as needed by the pgin.tcl.

Example 2: COPY FROM STDIN:
  1     set result_handle [pg_exec $conn_handle "COPY $table FROM STDIN"]
  2     if {[pg_result $result_handle -status] != "PGRES_COPY_IN"} {
  3       ... handle error ...
  4     }
  5     while {... more data to send ...} {
  6       puts $conn_handle $tab_separated_data_line
  7     }
  8     puts $conn_handle "\\."
  9     if {[info procs pg_endcopy] != ""} {
 10       pg_endcopy $result_handle
 11     }
 12     pg_result $result_handle -clear

Notes on Example 2:
   At line 8, send the end of data marker (both libpgtcl and pgin.tcl do it
this way).
   At lines 9-11, call pg_endcopy if it exists as needed by the pgin.tcl.


Compatibility Routines for Future PostgreSQL FE/BE Protocol v3 Support:

A future version of PostgreSQL (most likely 7.4) will introduce a new
Front-End/Back-End (FE/BE) Protocol called version 3. This protocol
structures all messages, and makes it impractical for a client application
to simply read lines from, or write lines to the backend during a COPY
operation. To support COPY operations with the v3 protocol, a future version
of pgin.tcl will require client applications to use new input/output
procedures during copy. These routines are pg_copy_read and pg_copy_write
as documented above. Usage is as follows:

During COPY TO STDOUT, process the line returned by pg_copy_read until it
returns an empty string, then call pg_endcopy.
        while {[set line [pg_copy_read $result_handle]] != ""} {
           ... Process record in $line ...
        }
        pg_endcopy $result_handle

During COPY FROM STDIN, write record lines with pg_copy_write until done.
Do not include newlines in your lines.  Do not write a terminator
line "\\.". When done, call pg_endcopy.
        while {... more data to send ...} {
          pg_copy_write $result_handle $tab_separated_data_line
        }
        pg_endcopy $result_handle

These routines are available in the current version of pgin.tcl, but their
use is optional. Do not mix direct read/write of the connection handle with
these routines during any one COPY operation. (Pg_endcopy needs to know
if you used pg_copy_write so it can write the terminator line needed by
the v2 protocol. This also means you must always write at least one record
when using pg_copy_write.)

-----------------------------------------------------------------------------
