091f1f473c951250e2f091d1a4c303a8a387d3ee
[sxemacs] / src / database / postgresql.c
1 /** postgresql.c -- elisp binding to libpq.so
2  *
3  * Copyright (C) 2000 Electrotechnical Laboratory, JAPAN.
4  * Copyright (C) 2005-2008 Sebastian Freundt <hroptatyr@sxemacs.org>
5  *
6  * Original author:  SL Baur <steve@beopen.com>
7  *
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * 3. Neither the name of the author nor the names of any contributors
21  *    may be used to endorse or promote products derived from this
22  *    software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  *
37  * This file is part of SXEmacs.
38  */
39 /*
40
41 Implementation notes (written by Steve Baur):
42 0. Supported PostgreSQL versions
43    This code was developed against libpq-8.0.1 and libpq-8.1.0-CVS.  Earlier
44    versions do work.  V7 support is more complete than V6.5 support.
45    V8 support is currently experimental.
46 1. Mule
47    Non-ASCII databases have been tested on 6.5, 7.3, 7.4 and 8.0.
48 2. Asynchronous Operation
49    Starting with libpq-7.0, an asynchronous interface is offered.  This
50    binding supports the asynchronous calls to a limited extent.  Since the
51    SXEmacs 22.1 core does not support a sensible interface to add managed but
52    unreadable (by SXEmacs) file descriptors to the main select code, polling
53    is required to drive the asynchronous calls.  XtAppAddInput would work
54    fine, but we want to be able to use the database when running strictly in
55    tty mode.
56 3. Completeness
57    Various calls have been deliberately not exported to Lisp.  The
58    unexported calls are either left-over backwards compatibility code that
59    aren't needed, calls that cannot be implemented sensibly, or calls that
60    cannot be implemented safely.  A list of all global functions in libpq
61    but not exported to Lisp is below.
62 4. Policy
63    This interface tries very hard to not set any policy towards how database
64    code in Emacs Lisp will be written.
65 5. Documentation
66    For full lisp programming documentation, see the SXEmacs Lisp Reference
67    Manual.  For PostgreSQL documentation, see the PostgreSQL distribution.
68
69 TODO (in rough order of priority):
70 1. The large object interface needs work with Emacs buffers in addition
71    to files.  Need two functions buffer->large_object, and large_object->
72    buffer.
73 - PQexecParams
74 - PQprepare, PQexecPrepared
75 - PQresultErrorField
76
77 - PQftable, PQftablecol, PQfformat
78
79 - PQsendQueryParams
80 - PQsendPrepare, PQsendQueryPrepared
81 - PQgetCancel, PQfreeCancel, PQcancel, PQrequestCancel
82
83 - PQputCopyData, PQputCopyEnd, PQgetCopyData
84
85 - notice receivers
86 */
87
88 /*
89   Unimplemented functions: [TODO]
90   PQsetNoticeProcessor - done 2005/05/03 hroptatyr
91
92   Unsupported functions:
93   PQsetdbLogin -- This function is deprecated, has a subset of the
94    functionality of PQconnectdb, and is better done in Lisp.
95    -- and I say, no it is not! I hate the single string interface!
96   PQsetdb -- Same as for PQsetdbLogin
97    -- same as my comment there :)
98   PQsocket -- Abstraction error, file descriptors should not be leaked
99    into Lisp code
100   PQprint -- print to a file descriptor, deprecated, better done in Lisp
101   PQdisplayTuples -- deprecated
102   PQprintTuples -- really, really deprecated
103   PQmblen -- Returns the length in bytes of multibyte character encoded
104    string.
105   PQtrace -- controls debug print tracing to a tty.
106   PQuntrace -- Ditto.  I don't see any way to do this sensibly.
107   PQoidStatus -- deprecated and nearly identical to PQoidValue
108   PQfn -- "Fast path" interface; This is a trapdoor into system internals
109     and can be a potential security hole.
110     Most users will not need this feature.
111
112   lo_open (large object) [*]
113   lo_close (large object) [*]
114   lo_read (large object) [*]
115   lo_write (large object) [*]
116   lo_lseek (large object) [*]
117   lo_creat (large object) [*]
118   lo_tell (large object) [*]
119   lo_unlink (large object) [*]
120 */
121
122 #include <config.h>
123 #include "lisp.h"
124 #include "sysdep.h"
125 #include "buffer.h"
126 #include "postgresql.h"
127
128 #ifdef HAVE_OPENSSL
129 #include "openssl.h"
130 #endif
131
132 #ifdef MULE
133 #define PG_OS_CODING Fget_coding_system(Vpg_coding_system)
134 #else
135 #define PG_OS_CODING Qnative
136 #endif
137 Lisp_Object Vpg_coding_system;
138
139 #define CHECK_CONNECTION_ALIVE(P)                               \
140         if (P == NULL ||                                        \
141             PQstatus(P) != CONNECTION_OK) {                     \
142                 char *e = "bad value";                          \
143                 if (P) {                                        \
144                         e = PQerrorMessage(P);                  \
145                 }                                               \
146                 error("dead connection [%s]", e);               \
147         }
148 #define CHECK_CONNECTION_ELIGIBLE(P)                            \
149         if (P == NULL ||                                        \
150             PQstatus(P) == CONNECTION_BAD) {                    \
151                 char *e = "bad value";                          \
152                 if (P) {                                        \
153                         e = PQerrorMessage(P);                  \
154                 }                                               \
155                 error("dead connection [%s]", e);               \
156         }
157 #define PUKE_IF_NULL(p)                         \
158         if (p == NULL) {                        \
159                 error ("bad value");            \
160         }
161
162 static Lisp_Object VXPGHOST;
163 static Lisp_Object VXPGUSER;
164 static Lisp_Object VXPGOPTIONS;
165 static Lisp_Object VXPGPORT;
166 static Lisp_Object VXPGTTY;     /* This needs to be blanked! */
167 static Lisp_Object VXPGDATABASE;
168 static Lisp_Object VXPGREALM;
169 #ifdef MULE
170 static Lisp_Object VXPGCLIENTENCODING;
171 #endif                          /* MULE */
172
173 /* Other variables:
174    PGAUTHTYPE -- not used after PostgreSQL 6.5
175    PGGEQO
176    PGCOSTINDEX
177    PGCOSTHEAP
178    PGTZ
179    PGDATESTYLE
180 */
181 #ifndef HAVE_POSTGRESQLV7
182 static Lisp_Object VXPGAUTHTYPE;
183 #endif
184 static Lisp_Object VXPGGEQO, VXPGCOSTINDEX, VXPGCOSTHEAP, VXPGTZ, VXPGDATESTYLE;
185
186 static Lisp_Object Qpostgresql;
187 static Lisp_Object Q_pg_connection_ok, Q_pg_connection_bad;
188 static Lisp_Object Q_pg_connection_started, Q_pg_connection_made;
189 static Lisp_Object Q_pg_connection_awaiting_response, Q_pg_connection_auth_ok;
190 static Lisp_Object Q_pg_connection_setenv;
191
192 /* trans statuses */
193 static Lisp_Object Q_pg_trans_idle, Q_pg_trans_active, Q_pg_trans_intrans;
194 static Lisp_Object Q_pg_trans_inerror, Q_pg_trans_unknown;
195
196 static Lisp_Object Q_pq_db, Q_pq_user, Q_pq_pass, Q_pq_host, Q_pq_port;
197 static Lisp_Object Q_pq_tty;
198 static Lisp_Object Q_pq_options, Q_pq_error_message, Q_pq_backend_pid;
199 static Lisp_Object Q_pq_status, Q_pq_transaction_status, Q_pq_parameter_status;
200 static Lisp_Object Q_pq_protocol_version, Q_pq_server_version;
201 #ifdef HAVE_OPENSSL
202 static Lisp_Object Q_pq_getssl;
203 #endif
204
205 static Lisp_Object Q_pgres_empty_query, Q_pgres_command_ok, Q_pgres_tuples_ok;
206 static Lisp_Object Q_pgres_copy_out, Q_pgres_copy_in, Q_pgres_bad_response;
207 static Lisp_Object Q_pgres_nonfatal_error, Q_pgres_fatal_error;
208
209 static Lisp_Object Q_pgres_polling_failed, Q_pgres_polling_reading;
210 static Lisp_Object Q_pgres_polling_writing, Q_pgres_polling_ok;
211 static Lisp_Object Q_pgres_polling_active;
212 /****/
213
214 /* PGconn is an opaque object and we need to be able to store them in
215    Lisp code because libpq supports multiple connections.
216 */
217 Lisp_Object Qpgconnp;
218
219 static Lisp_Object make_pgconn(Lisp_PGconn * pgconn)
220 {
221         Lisp_Object lisp_pgconn;
222         XSETPGCONN(lisp_pgconn, pgconn);
223         return lisp_pgconn;
224 }
225
226 static Lisp_Object
227 mark_pgconn(Lisp_Object obj)
228 {
229         return Qnil;
230 }
231
232 static void
233 print_pgconn(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
234 {
235         char buf[256];
236         PGconn *P;
237         ConnStatusType cst;
238         char *host = "", *db = "", *user = "", *port = "";
239
240         P = (XPGCONN(obj))->pgconn;
241
242         if (P == NULL) {
243                 /* this may happen since we allow PQfinish() to be called */
244                 strncpy(buf, "#<PGconn DEAD>", countof(buf));
245         } else if ((cst = PQstatus(P)) == CONNECTION_OK) {
246                 if (!(host = PQhost(P)))
247                         host = "";
248                 port = PQport(P);
249                 db = PQdb(P);
250                 if (!(user = PQuser(P))) {
251                         user = "";
252                 }
253                 snprintf(buf, sizeof(buf), "#<PGconn %s:%s %s/%s>",     /* evil! */
254                         !strlen(host) ? "localhost" : host, port, user, db);
255         } else if (cst == CONNECTION_BAD) {
256                 strncpy(buf, "#<PGconn BAD>", countof(buf));
257         } else {
258                 strncpy(buf, "#<PGconn connecting>", countof(buf));
259         }
260         write_c_string(buf, printcharfun);
261         return;
262 }
263
264 static Lisp_PGconn*
265 allocate_pgconn(void)
266 {
267         Lisp_PGconn *pgconn =
268                 alloc_lcrecord_type(Lisp_PGconn, &lrecord_pgconn);
269         pgconn->pgconn = (PGconn *) NULL;
270         return pgconn;
271 }
272
273 static void
274 finalize_pgconn(void *header, int for_disksave)
275 {
276         Lisp_PGconn *pgconn = (Lisp_PGconn *) header;
277
278         if (for_disksave) {
279                 signal_simple_error
280                         ("Can't dump an emacs containing PGconn objects",
281                          make_pgconn(pgconn));
282         }
283
284         if (pgconn->pgconn) {
285                 PQfinish(pgconn->pgconn);
286                 pgconn->pgconn = (PGconn *) NULL;
287         }
288 }
289
290 DEFINE_LRECORD_IMPLEMENTATION("pgconn", pgconn,
291                               mark_pgconn, print_pgconn, finalize_pgconn,
292                               NULL, NULL, 0, Lisp_PGconn);
293
294
295 /* PGresult is an opaque object and we need to be able to store them in
296    Lisp code.
297 */
298 Lisp_Object Qpgresultp;
299
300 static Lisp_Object
301 make_pgresult(Lisp_PGresult * pgresult)
302 {
303         Lisp_Object lisp_pgresult;
304         XSETPGRESULT(lisp_pgresult, pgresult);
305         return lisp_pgresult;
306 }
307
308 static Lisp_Object
309 mark_pgresult(Lisp_Object obj)
310 {
311         return Qnil;
312 }
313
314 #define RESULT_TUPLES_FMT "#<PGresult %s[%d] - %s>"
315 #define RESULT_CMD_TUPLES_FMT "#<PGresult %s[%s] - %s>"
316 #define RESULT_DEFAULT_FMT "#<PGresult %s - %s>"
317
318 static void
319 print_pgresult(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
320 {
321         char buf[1024];
322         PGresult *res;
323
324         res = (XPGRESULT(obj))->pgresult;
325
326         if (res) {
327                 switch (PQresultStatus(res)) {
328                 case PGRES_TUPLES_OK:
329                         /* Add number of tuples of result to output */
330                         snprintf(buf, countof(buf), RESULT_TUPLES_FMT,
331                                  PQresStatus(PQresultStatus(res)),
332                                  PQntuples(res), PQcmdStatus(res));
333                         break;
334                 case PGRES_COMMAND_OK:
335                         /* Add number of tuples affected by output-less
336                            command */
337                         if (!strlen(PQcmdTuples(res)))
338                                 goto notuples;
339                         snprintf(buf, countof(buf), RESULT_CMD_TUPLES_FMT,
340                                  PQresStatus(PQresultStatus(res)),
341                                  PQcmdTuples(res), PQcmdStatus(res));
342                         break;
343                 default:
344                 notuples:
345                         /* No counts to print */
346                         snprintf(buf, countof(buf), RESULT_DEFAULT_FMT,
347                                  PQresStatus(PQresultStatus(res)),
348                                  PQcmdStatus(res));
349                         break;
350                 }
351         } else {
352                 strncpy(buf, "#<PGresult DEAD>", countof(buf));
353         }
354
355         write_c_string(buf, printcharfun);
356         return;
357 }
358
359 #undef RESULT_TUPLES_FMT
360 #undef RESULT_CMD_TUPLES_FMT
361 #undef RESULT_DEFAULT_FMT
362
363 static Lisp_PGresult*
364 allocate_pgresult(void)
365 {
366         Lisp_PGresult *pgresult = alloc_lcrecord_type(
367                 Lisp_PGresult, &lrecord_pgresult);
368         pgresult->pgresult = (PGresult *) NULL;
369         return pgresult;
370 }
371
372 static void
373 finalize_pgresult(void *header, int for_disksave)
374 {
375         Lisp_PGresult *pgresult = (Lisp_PGresult *) header;
376
377         if (for_disksave) {
378                 signal_simple_error
379                     ("Can't dump an emacs containing PGresult objects",
380                      make_pgresult(pgresult));
381         }
382
383         if (pgresult->pgresult) {
384                 PQclear(pgresult->pgresult);
385                 pgresult->pgresult = (PGresult *) NULL;
386         }
387 }
388
389 DEFINE_LRECORD_IMPLEMENTATION("pgresult", pgresult,
390                               mark_pgresult, print_pgresult, finalize_pgresult,
391                               NULL, NULL, 0, Lisp_PGresult);
392
393 /***********************/
394
395 /* Notice Processor Stuff */
396 /* Okay, let's imagine how such a notice processor wants to look like.
397  * The only sensible thing I can imagine is a defun (like a sentinel for
398  * processes)
399  */
400 static void
401 sxemacs_notice_processor(Lisp_PGconn *conn, const char *msg)
402 {
403         /* (Lisp_PGconn *)conn; */
404
405         /* void *arg is my sentinel function */
406         Lisp_Object sentinel = conn->notice_processor;
407
408         if (NILP(sentinel))
409                 warn_when_safe(Qpostgresql, Qnotice, "%s", msg);
410         else {
411                 running_asynch_code = 1;
412                 call2_trapping_errors("Error in notice processor",
413                           sentinel, make_pgconn(conn),
414                           build_string(msg));
415                 running_asynch_code = 0;
416         }
417 }
418
419 /* HOWTO evoke notices:
420  *   (let ((res (pq-exec <conn> "SELECT * FROM <sometable> LIMIT 0")))
421  *     (pq-get-is-null res 0 0))
422  * should result in:
423  * msg <- `row number 0 is out of range 0..-1'
424  */
425 DEFUN("pq-set-notice-processor", Fpq_set_notice_processor, 2, 2, 0, /*
426 Give CONN the notice processor SENTINEL; nil for none.
427 The notice processor is called as a function whenever the pq backend
428 has notices.
429 It gets two arguments: the connection, and a message string.
430 */
431       (conn, sentinel))
432 {
433         CHECK_PGCONN(conn);
434
435         XPGCONN(conn)->notice_processor = sentinel;
436
437         return sentinel;
438 }
439
440
441 /* There are four ways (as of PostgreSQL v7) to connect to a database.
442    Two of them, PQsetdb and PQsetdbLogin, are deprecated.  Both of those
443    routines take a number of positional parameters and are better done in Lisp.
444    Note that PQconnectStart does not exist prior to v7.
445 */
446
447 DEFUN("pq-conn-defaults", Fpq_conn_defaults, 0, 0, 0,   /*
448 Return a connection default structure.
449 */
450       ())
451 {
452         /* This function can GC */
453         PQconninfoOption *pcio;
454         Lisp_Object temp, temp1;
455         int i;
456
457         /* WHAT A FOOKING MESS! */
458         pcio = PQconndefaults();
459         if (!pcio)
460                 return Qnil;    /* can never happen in libpq-7.0 */
461         temp = list1(Fcons(build_ext_string(pcio[0].keyword, PG_OS_CODING),
462                            Fcons(build_ext_string(pcio[0].envvar, PG_OS_CODING),
463                                  Fcons(build_ext_string
464                                        (pcio[0].compiled, PG_OS_CODING),
465                                        Fcons(build_ext_string
466                                              (pcio[0].val, PG_OS_CODING),
467                                              Fcons(build_ext_string
468                                                    (pcio[0].label,
469                                                     PG_OS_CODING),
470                                                    Fcons(build_ext_string
471                                                          (pcio[0].dispchar,
472                                                           PG_OS_CODING),
473                                                          Fcons(make_int
474                                                                (pcio[0].
475                                                                 dispsize),
476                                                                Qnil))))))));
477
478         for (i = 1; pcio[i].keyword; i++) {
479                 temp1 =
480                     list1(Fcons
481                           (build_ext_string(pcio[i].keyword, PG_OS_CODING),
482                            Fcons(build_ext_string(pcio[i].envvar, PG_OS_CODING),
483                                  Fcons(build_ext_string
484                                        (pcio[i].compiled, PG_OS_CODING),
485                                        Fcons(build_ext_string
486                                              (pcio[i].val, PG_OS_CODING),
487                                              Fcons(build_ext_string
488                                                    (pcio[i].label,
489                                                     PG_OS_CODING),
490                                                    Fcons(build_ext_string
491                                                          (pcio[i].dispchar,
492                                                           PG_OS_CODING),
493                                                          Fcons(make_int
494                                                                (pcio[i].
495                                                                 dispsize),
496                                                                Qnil))))))));
497                 {
498                         Lisp_Object args[2];
499                         args[0] = temp;
500                         args[1] = temp1;
501                         /* Fappend GCPROs its arguments */
502                         temp = Fappend(2, args);
503                 }
504         }
505
506         return temp;
507 }
508
509 /* PQconnectdb Makes a new connection to a backend.
510 PGconn *PQconnectdb(const char *conninfo)
511 */
512
513 DEFUN("pq-connectdb", Fpq_connectdb, 1, 1, 0,   /*
514 Open and return a new database connection using the parameters from the
515 string CONNINFO.
516
517 Unlike `pq-set-db-login' below, the parameter set can be extended without
518 changing the function signature, so use of this function (or its nonblocking
519 analogues `pq-connect-start' and `pq-connect-poll') is preferred for new
520 application programming.
521
522 The passed string can be empty to use all default parameters, or it can
523 contain one or more parameter settings separated by whitespace.  Each
524 parameter setting is in the form `keyword = value'.  Spaces around the equal
525 sign are optional.  To write an empty value or a value containing spaces,
526 surround it with single quotes, e.g., `keyword = \'a value\''.  Single
527 quotes and backslashes within the value must be escaped with a backslash,
528 i.e., \\\' and \\\\.
529
530 The currently recognized parameter key words are: 
531
532 - host
533
534 Name of host to connect to.  If this begins with a slash, it specifies
535 Unix-domain communication rather than TCP/IP communication; the value is the
536 name of the directory in which the socket file is stored.
537
538 The default behaviour when `host' is not specified is to connect to a
539 Unix-domain socket in /tmp (or whatever socket directory was specified when
540 PostgreSQL was built).
541
542 On machines without Unix-domain sockets, the default is to connect to
543 localhost.
544
545
546 - hostaddr
547
548 Numeric IP address of host to connect to.  This should be in the standard
549 IPv4 address format, e.g., 172.28.40.9.
550
551 If your machine supports IPv6, you can also use those addresses.
552
553 TCP/IP communication is always used when a nonempty string is specified for
554 this parameter.
555
556 Using `hostaddr' instead of `host' allows the application to avoid a host
557 name look-up, which may be important in applications with time constraints.
558 However, Kerberos authentication requires the host name.
559
560 The following therefore applies:
561   - If `host' is specified without `hostaddr' a host name lookup occurs.
562   - If `hostaddr' is specified without `host' the value for `hostaddr' gives
563     the remote address.
564   - When Kerberos is used, a reverse name query occurs to obtain the host
565     name for Kerberos.
566   - If both `host' and `hostaddr' are specified, the value for `hostaddr'
567     gives the remote address; the value for `host' is ignored, unless
568     Kerberos is used, in which case that value is used for Kerberos
569     authentication.
570
571 Note: Authentication is likely to fail if libpq is passed a host name that
572 is not the name of the machine at `hostaddr'.
573 Also, `host' rather than `hostaddr' is used to identify the connection in
574 ~/.pgpass.
575
576
577 Without either a host name or host address, libpq will connect using a local
578 Unix-domain socket; or on machines without Unix-domain sockets, it will
579 attempt to connect to localhost.
580
581
582 - port
583
584 Port number to connect to at the server host, or socket file name extension
585 for Unix-domain connections.
586
587
588 - dbname
589
590 The database name.
591 Defaults to be the same as the user name.
592
593
594 - user
595
596 PostgreSQL user name to connect as.
597 Defaults to be the same as the operating system name of the user running the
598 application.
599
600
601 - password
602
603 Password to be used if the server demands password authentication.
604
605
606 - connect_timeout
607
608 Maximum wait for connection, in seconds (write as a decimal integer string).
609 Zero or not specified means wait indefinitely.
610 It is not recommended to use a timeout of less than 2 seconds.
611
612
613 - options
614
615 Command-line options to be sent to the server.
616
617
618 - tty
619
620 Ignored (formerly, this specified where to send server debug output).
621
622
623 - sslmode
624
625 This option determines whether or with what priority an SSL connection will
626 be negotiated with the server.
627 There are four modes: 
628   - `disable' will attempt only an unencrypted SSL connection;
629   - `allow' will negotiate, trying first a non-SSL connection, then if that
630     fails, trying an SSL connection;
631   - `prefer' (the default) will negotiate, trying first an SSL connection,
632     then if that fails, trying a regular non-SSL connection;
633   - `require' will try only an SSL connection.
634
635 Note: If PostgreSQL is compiled without SSL support, using option require
636 will cause an error, while options allow and prefer will be accepted but
637 libpq will not in fact attempt an SSL connection.
638
639 - requiressl
640
641 This option is deprecated in favour of the sslmode setting.
642
643 If set to 1, an SSL connection to the server is required (this is equivalent
644 to sslmode require). libpq will then refuse to connect if the server does
645 not accept an SSL connection. 
646 If set to 0 (default), libpq will negotiate the connection type with the
647 server (equivalent to sslmode prefer).
648
649 This option is only available if PostgreSQL is compiled with SSL support.
650
651
652 - service
653
654 Service name to use for additional parameters.
655 It specifies a service name in pg_service.conf that holds additional
656 connection parameters. This allows applications to specify only a service
657 name so connection parameters can be centrally maintained.
658 See share/pg_service.conf.sample in the installation directory for
659 information on how to set up the file.
660
661 General note:
662 If any parameter is unspecified, then the corresponding environment variable
663 is checked. If the environment variable is not set either, then the
664 indicated built-in defaults are used.
665 */
666       (conninfo))
667 {
668         PGconn *P;
669         Lisp_PGconn *lisp_pgconn;
670         char *error_message = "Out of Memory?";
671         char *c_conninfo;
672         /* the result */
673         Lisp_Object conn;
674
675         CHECK_STRING(conninfo);
676
677         TO_EXTERNAL_FORMAT(LISP_STRING, conninfo,
678                            C_STRING_ALLOCA, c_conninfo, Qnative);
679         P = PQconnectdb(c_conninfo);
680         if (P && (PQstatus(P) == CONNECTION_OK)) {
681                 lisp_pgconn = allocate_pgconn();
682                 lisp_pgconn->pgconn = P;
683                 lisp_pgconn->notice_processor = Qnil;
684                 conn = make_pgconn(lisp_pgconn);
685                 PQsetNoticeProcessor
686                         (P,
687                          (PQnoticeProcessor)sxemacs_notice_processor,
688                          /* this is stupid, but libpq wants a void pointer */
689                          (Lisp_PGconn *)lisp_pgconn);
690                 return conn;
691         } else {
692                 /* Connection failed.  Destroy the connection and signal an
693                  * error. */
694                 char buf[BLCKSZ];
695                 strncpy(buf, error_message, sizeof(buf)-1);
696                 buf[sizeof(buf) - 1] = '\0';
697                 if (P) {
698                         /* storage for the error message gets erased when
699                          * call PQfinish */
700                         /* so we must temporarily stash it somewhere */
701                         strncpy(buf, PQerrorMessage(P), sizeof(buf)-1);
702                         buf[sizeof(buf) - 1] = '\0';
703                         PQfinish(P);
704                 }
705                 error("libpq: %s", buf);
706         }
707 }
708
709 /* PQconnectStart Makes a new asynchronous connection to a backend.
710 PGconn *PQconnectStart(const char *conninfo)
711 */
712
713 #ifdef HAVE_POSTGRESQLV7
714 DEFUN("pq-connect-start", Fpq_connect_start, 1, 1, 0,   /*
715 Make a new asynchronous connection to a PostgreSQL backend.
716
717 See `pq-connectdb' for a complete description of conninfo.
718 */
719       (conninfo))
720 {
721         PGconn *P;
722         Lisp_PGconn *lisp_pgconn;
723         char *error_message = "Out of Memory?";
724         char *c_conninfo;
725         /* the result */
726         Lisp_Object conn;
727
728         CHECK_STRING(conninfo);
729         TO_EXTERNAL_FORMAT(LISP_STRING, conninfo,
730                            C_STRING_ALLOCA, c_conninfo, Qnative);
731         P = PQconnectStart(c_conninfo);
732
733         if (P && (PQstatus(P) != CONNECTION_BAD)) {
734                 lisp_pgconn = allocate_pgconn();
735                 lisp_pgconn->pgconn = P;
736                 lisp_pgconn->notice_processor = Qnil;
737                 conn = make_pgconn(lisp_pgconn);
738                 PQsetNoticeProcessor
739                         (P,
740                          (PQnoticeProcessor)sxemacs_notice_processor,
741                          (void *)&conn);
742                 return conn;
743         } else {
744                 /* capture the error message before destroying the object */
745                 char buf[BLCKSZ];
746                 strncpy(buf, error_message, sizeof(buf)-1);
747                 buf[sizeof(buf) - 1] = '\0';
748                 if (P) {
749                         strncpy(buf, PQerrorMessage(P), sizeof(buf)-1);
750                         buf[sizeof(buf) - 1] = '\0';
751                         PQfinish(P);
752                 }
753                 error("libpq: %s", buf);
754         }
755         return Qnil;
756 }
757
758 DEFUN("pq-connect-poll", Fpq_connect_poll, 1, 1, 0,     /*
759 Poll an asynchronous connection for completion
760 */
761       (conn))
762 {
763         PGconn *P;
764         PostgresPollingStatusType polling_status;
765
766         CHECK_PGCONN(conn);
767
768         P = (XPGCONN(conn))->pgconn;
769         CHECK_CONNECTION_ELIGIBLE(P);
770
771         polling_status = PQconnectPoll(P);
772         switch (polling_status) {
773         case PGRES_POLLING_FAILED:
774                 /* Something Bad has happened */
775                 {
776                         char *e = PQerrorMessage(P);
777                         error("libpq: %s", e);
778                 }
779         case PGRES_POLLING_OK:
780                 return Q_pgres_polling_ok;
781         case PGRES_POLLING_READING:
782                 return Q_pgres_polling_reading;
783         case PGRES_POLLING_WRITING:
784                 return Q_pgres_polling_writing;
785         case PGRES_POLLING_ACTIVE:
786                 return Q_pgres_polling_active;
787         default:
788                 /* they've added a new field we don't know about */
789                 error("Help!  Unknown status code %08x from backend!",
790                       polling_status);
791         }
792 }
793
794 #ifdef MULE
795 DEFUN("pq-client-encoding", Fpq_client_encoding, 1, 1, 0,       /*
796 Return client coding system.
797 */
798       (conn))
799 {
800         PGconn *P;
801
802         CHECK_PGCONN(conn);
803         P = (XPGCONN(conn))->pgconn;
804         CHECK_CONNECTION_ALIVE(P);
805
806         return make_int(PQclientEncoding(P));
807 }
808
809 DEFUN("pq-set-client-encoding", Fpq_set_client_encoding, 2, 2, 0,       /*
810 Set client coding system.
811 */
812       (conn, encoding))
813 {
814         PGconn *P;
815         int rc;
816         char *c_encoding;
817
818         CHECK_PGCONN(conn);
819         CHECK_STRING(encoding);
820
821         P = (XPGCONN(conn))->pgconn;
822         CHECK_CONNECTION_ALIVE(P);
823
824         TO_EXTERNAL_FORMAT(LISP_STRING, encoding,
825                            C_STRING_ALLOCA, c_encoding, Qnative);
826
827         if ((rc = PQsetClientEncoding(P, c_encoding)) < 0)
828                 error("bad encoding");
829         else
830                 return make_int(rc);
831 }
832
833 #endif
834 #endif                          /* HAVE_POSTGRESQLV7 */
835
836 /* PQfinish Close the connection to the backend. Also frees memory
837        used by the PGconn object.
838 void PQfinish(PGconn *conn)
839 */
840 DEFUN("pq-finish", Fpq_finish, 1, 1, 0, /*
841 Close the connection to the backend.
842 */
843       (conn))
844 {
845         PGconn *P;
846
847         CHECK_PGCONN(conn);
848         P = (XPGCONN(conn))->pgconn;
849         PUKE_IF_NULL(P);
850
851         PQfinish(P);
852         /* #### PQfinish deallocates the PGconn structure, so we now have a
853            dangling pointer. */
854         /* Genocided all @'s ... */
855         (XPGCONN(conn))->pgconn = (PGconn *) NULL;      /* You feel DEAD inside */
856         return Qnil;
857 }
858
859 DEFUN("pq-clear", Fpq_clear, 1, 1, 0,   /*
860 Forcibly erase a PGresult object.
861 */
862       (res))
863 {
864         PGresult *R;
865
866         CHECK_PGRESULT(res);
867         R = (XPGRESULT(res))->pgresult;
868         PUKE_IF_NULL(R);
869
870         PQclear(R);
871         /* Genocided all @'s ... */
872         (XPGRESULT(res))->pgresult = (PGresult *) NULL; /* You feel DEAD inside */
873
874         return Qnil;
875 }
876
877 DEFUN("pq-is-busy", Fpq_is_busy, 1, 1, 0,       /*
878 Return t if PQgetResult would block waiting for input.
879 */
880       (conn))
881 {
882         PGconn *P;
883
884         CHECK_PGCONN(conn);
885         P = (XPGCONN(conn))->pgconn;
886         CHECK_CONNECTION_ALIVE(P);
887
888         return PQisBusy(P) ? Qt : Qnil;
889 }
890
891 DEFUN("pq-consume-input", Fpq_consume_input, 1, 1, 0,   /*
892 Consume any available input from the backend.
893 Returns nil if something bad happened.
894 */
895       (conn))
896 {
897         PGconn *P;
898
899         CHECK_PGCONN(conn);
900         P = (XPGCONN(conn))->pgconn;
901         CHECK_CONNECTION_ALIVE(P);
902
903         return PQconsumeInput(P) ? Qt : Qnil;
904 }
905
906 /* PQreset Reset the communication port with the backend.
907 void PQreset(PGconn *conn)
908 */
909 DEFUN("pq-reset", Fpq_reset, 1, 1, 0,   /*
910 Reset the connection to the backend.
911 This function will close the connection to the backend and attempt to
912 reestablish a new connection to the same postmaster, using all the same
913 parameters previously used.  This may be useful for error recovery if a
914 working connection is lost.
915 */
916       (conn))
917 {
918         PGconn *P;
919
920         CHECK_PGCONN(conn);
921         P = (XPGCONN(conn))->pgconn;
922         PUKE_IF_NULL(P);
923         /* we can resurrect a BAD connection, but not a dead one. */
924
925         PQreset(P);
926
927         return Qnil;
928 }
929
930 #ifdef HAVE_POSTGRESQLV7
931 DEFUN("pq-reset-start", Fpq_reset_start, 1, 1, 0,       /*
932 Reset connection to the backend asynchronously.
933 */
934       (conn))
935 {
936         PGconn *P;
937
938         CHECK_PGCONN(conn);
939         P = (XPGCONN(conn))->pgconn;
940         CHECK_CONNECTION_ALIVE(P);
941
942         if (PQresetStart(P))
943                 return Qt;
944         {
945                 char *e = PQerrorMessage(P);
946                 error("libpq: %s", e);
947         }
948 }
949
950 DEFUN("pq-reset-poll", Fpq_reset_poll, 1, 1, 0, /*
951 Poll an asynchronous reset for completion.
952 */
953       (conn))
954 {
955         PGconn *P;
956         PostgresPollingStatusType polling_status;
957
958         CHECK_PGCONN(conn);
959
960         P = (XPGCONN(conn))->pgconn;
961         CHECK_CONNECTION_ELIGIBLE(P);
962
963         polling_status = PQresetPoll(P);
964         switch (polling_status) {
965         case PGRES_POLLING_FAILED:
966                 /* Something Bad has happened */
967                 {
968                         char *e = PQerrorMessage(P);
969                         error("libpq: %s", e);
970                 }
971         case PGRES_POLLING_OK:
972                 return Q_pgres_polling_ok;
973         case PGRES_POLLING_READING:
974                 return Q_pgres_polling_reading;
975         case PGRES_POLLING_WRITING:
976                 return Q_pgres_polling_writing;
977         case PGRES_POLLING_ACTIVE:
978                 return Q_pgres_polling_active;
979         default:
980                 /* they've added a new field we don't know about */
981                 error("Help!  Unknown status code %08x from backend!",
982                       polling_status);
983         }
984 }
985 #endif
986
987 DEFUN("pq-request-cancel", Fpq_request_cancel, 1, 1, 0, /*
988 Attempt to request cancellation of the current operation.
989
990 The return value is t if the cancel request was successfully
991 dispatched, nil if not (in which case conn->errorMessage is set).
992 Note: successful dispatch is no guarantee that there will be any effect at
993 the backend.  The application must read the operation result as usual.
994 */
995       (conn))
996 {
997         PGconn *P;
998
999         CHECK_PGCONN(conn);
1000         P = (XPGCONN(conn))->pgconn;
1001         CHECK_CONNECTION_ALIVE(P);
1002
1003         return PQrequestCancel(P) ? Qt : Qnil;
1004 }
1005
1006 /* accessor function for the PGconn object */
1007 DEFUN("pq-connection-status", Fpq_connection_status, 2, 2, 0,   /*
1008 Accessor function for the PGconn object.
1009 Currently recognized symbols for the field:
1010 :pq-db                  Database name
1011 :pq-user                Database user name
1012 :pq-pass                Database user's password
1013 :pq-host                Hostname of PostgreSQL backend connected to
1014 :pq-port                TCP port number of connection
1015 :pq-tty                 Debugging TTY (not used in Emacs)
1016 :pq-options             Additional backend options
1017 :pq-status              Connection status (either OK or BAD)
1018 :pq-transaction-status  Current in-transaction status of the server
1019 :pq-parameter-status    Current parameter setting of the server
1020 :pq-protocol-version    Frontend/Backend protocol
1021 :pq-server-version      Integer representing the backend version
1022 :pq-error-message       Last error message from the backend
1023 :pq-backend-pid         Process ID of backend process
1024 :pq-getssl              SSL session used in the connection
1025 */
1026       (conn, field))
1027 {
1028         PGconn *P;
1029
1030         CHECK_PGCONN(conn);
1031         P = (XPGCONN(conn))->pgconn;
1032         PUKE_IF_NULL(P);        /* BAD connections still have state to query */
1033
1034         if (EQ(field, Q_pq_db)) {
1035                 /* PQdb Returns the database name of the connection.
1036                    char *PQdb(PGconn *conn)
1037                  */
1038                 return build_ext_string(PQdb(P), PG_OS_CODING);
1039         } else if (EQ(field, Q_pq_user)) {
1040                 /* PQuser Returns the user name of the connection.
1041                    char *PQuser(PGconn *conn)
1042                  */
1043                 return build_ext_string(PQuser(P), PG_OS_CODING);
1044         } else if (EQ(field, Q_pq_pass)) {
1045                 /* PQpass Returns the password of the connection.
1046                    char *PQpass(PGconn *conn)
1047                  */
1048                 return build_ext_string(PQpass(P), PG_OS_CODING);
1049         } else if (EQ(field, Q_pq_host)) {
1050                 /* PQhost Returns the server host name of the connection.
1051                    char *PQhost(PGconn *conn)
1052                  */
1053                 return build_ext_string(PQhost(P), PG_OS_CODING);
1054         } else if (EQ(field, Q_pq_port)) {
1055                 char *p;
1056                 /* PQport Returns the port of the connection.
1057                    char *PQport(PGconn *conn)
1058                  */
1059                 if ((p = PQport(P)))
1060                         return make_int(atoi(p));
1061                 else
1062                         return make_int(-1);
1063         } else if (EQ(field, Q_pq_tty)) {
1064                 /* PQtty Returns the debug tty of the connection.
1065                    char *PQtty(PGconn *conn)
1066                  */
1067                 return build_ext_string(PQtty(P), PG_OS_CODING);
1068         } else if (EQ(field, Q_pq_options)) {
1069                 /* PQoptions Returns the backend options used in the connection.
1070                    char *PQoptions(PGconn *conn)
1071                  */
1072                 return build_ext_string(PQoptions(P), PG_OS_CODING);
1073         } else if (EQ(field, Q_pq_status)) {
1074                 ConnStatusType cst;
1075                 /* PQstatus Returns the status of the connection. The status can be
1076                    CONNECTION_OK or CONNECTION_BAD.
1077                    ConnStatusType PQstatus(PGconn *conn)
1078                  */
1079                 switch ((cst = PQstatus(P))) {
1080                 case CONNECTION_OK:
1081                         return Q_pg_connection_ok;
1082                 case CONNECTION_BAD:
1083                         return Q_pg_connection_bad;
1084 #ifdef HAVE_POSTGRESQLV7
1085                 case CONNECTION_STARTED:
1086                         return Q_pg_connection_started;
1087                 case CONNECTION_MADE:
1088                         return Q_pg_connection_made;
1089                 case CONNECTION_AWAITING_RESPONSE:
1090                         return Q_pg_connection_awaiting_response;
1091                 case CONNECTION_AUTH_OK:
1092                         return Q_pg_connection_auth_ok;
1093                 case CONNECTION_SETENV:
1094                         return Q_pg_connection_setenv;
1095 #endif                          /* HAVE_POSTGRESQLV7 */
1096                 default:
1097                         /* they've added a new field we don't know about */
1098                         error("Help!  Unknown connection status code %08x "
1099                               "from backend!",
1100                               cst);
1101                 }
1102         } else if (EQ(field, Q_pq_transaction_status)) {
1103                 PGTransactionStatusType ts;
1104                 switch ((ts = PQtransactionStatus(P))) {
1105                 case PQTRANS_IDLE:
1106                         return Q_pg_trans_idle;
1107                 case PQTRANS_ACTIVE:
1108                         return Q_pg_trans_active;
1109                 case PQTRANS_INTRANS:
1110                         return Q_pg_trans_intrans;
1111                 case PQTRANS_INERROR:
1112                         return Q_pg_trans_inerror;
1113                 case PQTRANS_UNKNOWN:
1114                         return Q_pg_trans_unknown;
1115                 default:
1116                         /* they've added a new field we don't know about */
1117                         error("Help!  Unknown transaction status code %08x "
1118                               "from backend!",
1119                               ts);
1120                 }
1121         } else if (EQ(field, Q_pq_parameter_status)) {
1122                 return Qnil;
1123         } else if (EQ(field, Q_pq_protocol_version)) {
1124                 return make_int(PQprotocolVersion(P));
1125 #if HAVE_PQSERVERVERSION
1126         } else if (EQ(field, Q_pq_server_version)) {
1127                 return make_int(PQserverVersion(P));
1128 #else
1129         } else if (EQ(field, Q_pq_server_version)) {
1130                 char *vstr = xstrdup(PQparameterStatus(P,"server_version"));
1131                 char *tmp, previous;
1132                 int major, minor, patch;
1133
1134                 if ( vstr == NULL )
1135                         return Qnil;
1136                 tmp = strtok(vstr,".");
1137                 major = atoi(tmp);
1138                 tmp = strtok(NULL,".");
1139                 minor = atoi(tmp);
1140                 tmp = strtok(NULL,".");
1141                 patch = atoi(tmp);
1142                 xfree(vstr);
1143                 return make_int(major*10000+minor*100+patch);
1144 #endif
1145         } else if (EQ(field, Q_pq_error_message)) {
1146                 /* PQerrorMessage Returns the error message most recently
1147                  * generated by an operation on the connection.
1148                  * char *PQerrorMessage(PGconn* conn);
1149                  */
1150                 return build_ext_string(PQerrorMessage(P), PG_OS_CODING);
1151         } else if (EQ(field, Q_pq_backend_pid)) {
1152                 /* PQbackendPID Returns the process ID of the backend server
1153                  * handling this connection.
1154                  * int PQbackendPID(PGconn *conn);
1155                  */
1156                 return make_int(PQbackendPID(P));
1157 #ifdef HAVE_OPENSSL
1158         } else if (EQ(field, Q_pq_getssl)) {
1159                 /* PQgetssl Returns the SSL structure used in the connection,
1160                  * or NULL if SSL is not in use.
1161                  * SSL *PQgetssl(PGconn *conn);
1162                  */
1163                 SSL *ssl_conn;
1164                 ssl_conn = (SSL*)PQgetssl(P);
1165                 if (ssl_conn == NULL)
1166                         return Qnil; /* meaning: no SSL in use */
1167                 else {
1168                         Lisp_SSL_CONN *pqssl = allocate_ssl_conn();
1169                         pqssl->ssl_conn = ssl_conn;
1170                         pqssl->parent = conn;
1171                         pqssl->protected_p = 1;
1172                         return make_ssl_conn(pqssl);
1173                         /* Should we use a copy of the SSL session here?
1174                          * Otherwise it's safe to obtain a nice segfault by:
1175                          *   (setq m (pq-pgconn foo \'pq::getssl))
1176                          *   (setq m \'something-else)
1177                          *   M-x garbage-collect RET
1178                          *   (pq-send-query foo ...)
1179                          * You will see SXE dump in ssl*_write or the like
1180                          * since the _original_ session handle has been gc'd
1181                          *
1182                          * Nah, _for the moment_ I assume our users to be
1183                          * smart enough to rethink twice before they do
1184                          * something like this.
1185                          */
1186                 }
1187 #endif
1188         }
1189
1190         /* else */
1191         message("bad PGconn accessor");
1192         return Qnil;
1193 }
1194
1195 DEFUN("pq-connection-alive-p", Fpq_connection_alive_p, 1, 1, 0, /*
1196 Return non-nil when CONN is considered alive.
1197
1198 This is roughly the same as calling (pq-connection-status CONN :status)
1199 */
1200       (conn))
1201 {
1202         PGconn *P;
1203
1204         CHECK_PGCONN(conn);
1205
1206         P = (XPGCONN(conn))->pgconn;
1207
1208         if (PQstatus(P) == CONNECTION_OK) {
1209                 return Qt;
1210         }
1211         return Qnil;
1212 }
1213
1214 DEFUN("pq-connection-p", Fpq_connection_p, 1, 1, 0, /*
1215 Return non-nil if OBJECT is a pq connection object.
1216 */
1217       (object))
1218 {
1219         return PGCONNP(object) ? Qt : Qnil;
1220 }
1221
1222 /* Query functions */
1223 DEFUN("pq-exec", Fpq_exec, 2, 2, 0,     /*
1224 Submit a query to Postgres and wait for the result.
1225 */
1226       (conn, query))
1227 {
1228         PGconn *P;
1229         Lisp_PGresult *lisp_pgresult;
1230         PGresult *R;
1231         char *c_query;
1232
1233         CHECK_PGCONN(conn);
1234         CHECK_STRING(query);
1235
1236         P = (XPGCONN(conn))->pgconn;
1237         CHECK_CONNECTION_ALIVE(P);
1238
1239         TO_EXTERNAL_FORMAT(LISP_STRING, query,
1240                            C_STRING_ALLOCA, c_query, Qnative);
1241
1242         R = PQexec(P, c_query);
1243         {
1244                 char *tag, buf[BLCKSZ];
1245
1246                 if (!R)
1247                         error("query: out of memory");
1248                 else
1249                         switch (PQresultStatus(R)) {
1250                         case PGRES_BAD_RESPONSE:
1251                                 tag = "bad response [%s]";
1252                                 goto err;
1253                         case PGRES_NONFATAL_ERROR:
1254                                 tag = "non-fatal error [%s]";
1255                                 goto err;
1256                         case PGRES_FATAL_ERROR:
1257                                 tag = "fatal error [%s]";
1258                               err:
1259                                 strncpy(buf, PQresultErrorMessage(R),
1260                                         sizeof(buf));
1261                                 buf[sizeof(buf) - 1] = '\0';
1262                                 PQclear(R);
1263                                 error(tag, buf);
1264                          /*NOTREACHED*/ default:
1265                                 break;
1266                         }
1267         }
1268
1269         lisp_pgresult = allocate_pgresult();
1270         lisp_pgresult->pgresult = R;
1271
1272         return make_pgresult(lisp_pgresult);
1273 }
1274
1275 DEFUN("pq-send-query", Fpq_send_query, 2, 2, 0, /*
1276 Submit a query to Postgres and don't wait for the result.
1277 Returns: t if successfully submitted
1278 nil if error (conn->errorMessage is set)
1279 */
1280       (conn, query))
1281 {
1282         PGconn *P;
1283         char *c_query;
1284
1285         CHECK_PGCONN(conn);
1286         CHECK_STRING(query);
1287
1288         P = (XPGCONN(conn))->pgconn;
1289         CHECK_CONNECTION_ALIVE(P);
1290
1291         TO_EXTERNAL_FORMAT(LISP_STRING, query,
1292                            C_STRING_ALLOCA, c_query, Qnative);
1293
1294         if (PQsendQuery(P, c_query))
1295                 return Qt;
1296         else
1297                 error("async query: %s", PQerrorMessage(P));
1298 }
1299
1300 DEFUN("pq-result-p", Fpq_result_p, 1, 1, 0, /*
1301 Return non-nil if OBJECT is a pq query result object.
1302 */
1303       (object))
1304 {
1305         return PGRESULTP(object) ? Qt : Qnil;
1306 }
1307
1308 DEFUN("pq-get-result", Fpq_get_result, 1, 1, 0, /*
1309 Retrieve an asynchronous result from a query.
1310 NIL is returned when no more query work remains.
1311 */
1312       (conn))
1313 {
1314         PGconn *P;
1315         Lisp_PGresult *lisp_pgresult;
1316         PGresult *R;
1317
1318         CHECK_PGCONN(conn);
1319
1320         P = (XPGCONN(conn))->pgconn;
1321         CHECK_CONNECTION_ALIVE(P);
1322
1323         R = PQgetResult(P);
1324         if (!R)
1325                 return Qnil;    /* not an error, there's no more data to get */
1326
1327         {
1328                 char *tag, buf[BLCKSZ];
1329
1330                 switch (PQresultStatus(R)) {
1331                 case PGRES_BAD_RESPONSE:
1332                         tag = "bad response [%s]";
1333                         goto err;
1334                 case PGRES_NONFATAL_ERROR:
1335                         tag = "non-fatal error [%s]";
1336                         goto err;
1337                 case PGRES_FATAL_ERROR:
1338                         tag = "fatal error [%s]";
1339                       err:
1340                         strncpy(buf, PQresultErrorMessage(R), sizeof(buf));
1341                         buf[sizeof(buf) - 1] = '\0';
1342                         PQclear(R);
1343                         error(tag, buf);
1344                  /*NOTREACHED*/ default:
1345                         break;
1346                 }
1347         }
1348
1349         lisp_pgresult = allocate_pgresult();
1350         lisp_pgresult->pgresult = R;
1351
1352         return make_pgresult(lisp_pgresult);
1353 }
1354
1355 DEFUN("pq-result-status", Fpq_result_status, 1, 1, 0,   /*
1356 Return result status of the query.
1357 */
1358       (result))
1359 {
1360         PGresult *R;
1361         ExecStatusType est;
1362
1363         CHECK_PGRESULT(result);
1364         R = (XPGRESULT(result))->pgresult;
1365         PUKE_IF_NULL(R);
1366
1367         switch ((est = PQresultStatus(R))) {
1368         case PGRES_EMPTY_QUERY:
1369                 return Q_pgres_empty_query;
1370         case PGRES_COMMAND_OK:
1371                 return Q_pgres_command_ok;
1372         case PGRES_TUPLES_OK:
1373                 return Q_pgres_tuples_ok;
1374         case PGRES_COPY_OUT:
1375                 return Q_pgres_copy_out;
1376         case PGRES_COPY_IN:
1377                 return Q_pgres_copy_in;
1378         case PGRES_BAD_RESPONSE:
1379                 return Q_pgres_bad_response;
1380         case PGRES_NONFATAL_ERROR:
1381                 return Q_pgres_nonfatal_error;
1382         case PGRES_FATAL_ERROR:
1383                 return Q_pgres_fatal_error;
1384         default:
1385                 /* they've added a new field we don't know about */
1386                 error("Help!  Unknown exec status code %08x from backend!",
1387                       est);
1388         }
1389 }
1390
1391 DEFUN("pq-result-status-string", Fpq_result_status_string, 1, 1, 0,     /*
1392 Return stringified result status of the query.
1393 */
1394       (result))
1395 {
1396         PGresult *R;
1397
1398         CHECK_PGRESULT(result);
1399         R = (XPGRESULT(result))->pgresult;
1400         PUKE_IF_NULL(R);
1401
1402         return build_ext_string(PQresStatus(PQresultStatus(R)), PG_OS_CODING);
1403 }
1404
1405 /* Sundry PGresult accessor functions */
1406 DEFUN("pq-result-error-message", Fpq_result_error_message, 1, 1, 0,     /*
1407 Return last message associated with the query.
1408 */
1409       (result))
1410 {
1411         PGresult *R;
1412
1413         CHECK_PGRESULT(result);
1414         R = (XPGRESULT(result))->pgresult;
1415         PUKE_IF_NULL(R);
1416
1417         return build_ext_string(PQresultErrorMessage(R), PG_OS_CODING);
1418 }
1419
1420 DEFUN("pq-ntuples", Fpq_ntuples, 1, 1, 0,       /*
1421 Return the number of tuples (instances) in the query result.
1422 */
1423       (result))
1424 {
1425         PGresult *R;
1426
1427         CHECK_PGRESULT(result);
1428         R = (XPGRESULT(result))->pgresult;
1429         PUKE_IF_NULL(R);
1430
1431         return make_int(PQntuples(R));
1432 }
1433
1434 DEFUN("pq-nfields", Fpq_nfields, 1, 1, 0,       /*
1435 Return the number of fields (attributes) in each tuple of the query result.
1436 */
1437       (result))
1438 {
1439         PGresult *R;
1440
1441         CHECK_PGRESULT(result);
1442         R = (XPGRESULT(result))->pgresult;
1443         PUKE_IF_NULL(R);
1444
1445         return make_int(PQnfields(R));
1446 }
1447
1448 DEFUN("pq-binary-tuples", Fpq_binary_tuples, 1, 1, 0,   /*
1449 Return t if the query result contains binary data, nil otherwise.
1450 */
1451       (result))
1452 {
1453         PGresult *R;
1454
1455         CHECK_PGRESULT(result);
1456         R = (XPGRESULT(result))->pgresult;
1457         PUKE_IF_NULL(R);
1458
1459         return (PQbinaryTuples(R)) ? Qt : Qnil;
1460 }
1461
1462 DEFUN("pq-fname", Fpq_fname, 2, 2, 0,   /*
1463 Return the field (attribute) name associated with the given field index.
1464 Field indices start at 0.
1465 */
1466       (result, field_index))
1467 {
1468         PGresult *R;
1469
1470         CHECK_PGRESULT(result);
1471         CHECK_INT(field_index);
1472         R = (XPGRESULT(result))->pgresult;
1473         PUKE_IF_NULL(R);
1474
1475         return build_ext_string(PQfname(R, XINT(field_index)), PG_OS_CODING);
1476 }
1477
1478 DEFUN("pq-fnumber", Fpq_fnumber, 2, 2, 0,       /*
1479 Return the number of fields (attributes) in each tuple of the query result.
1480 */
1481       (result, field_name))
1482 {
1483         PGresult *R;
1484         char *c_field_name;
1485
1486         CHECK_PGRESULT(result);
1487         CHECK_STRING(field_name);
1488         R = (XPGRESULT(result))->pgresult;
1489         PUKE_IF_NULL(R);
1490
1491         TO_EXTERNAL_FORMAT(LISP_STRING, field_name,
1492                            C_STRING_ALLOCA, c_field_name, Qnative);
1493
1494         return make_int(PQfnumber(R, c_field_name));
1495 }
1496
1497 DEFUN("pq-ftype", Fpq_ftype, 2, 2, 0,   /*
1498 Return the field type associated with the given field index.
1499 The integer returned is the internal coding of the type.  Field indices
1500 start at 0.
1501 */
1502       (result, field_num))
1503 {
1504         PGresult *R;
1505
1506         CHECK_PGRESULT(result);
1507         CHECK_INT(field_num);
1508         R = (XPGRESULT(result))->pgresult;
1509         PUKE_IF_NULL(R);
1510
1511         return make_int(PQftype(R, XINT(field_num)));
1512 }
1513
1514 DEFUN("pq-fsize", Fpq_fsize, 2, 2, 0,   /*
1515 Return the field size in bytes associated with the given field index.
1516 Field indices start at 0.
1517 */
1518       (result, field_index))
1519 {
1520         PGresult *R;
1521
1522         CHECK_PGRESULT(result);
1523         CHECK_INT(field_index);
1524         R = (XPGRESULT(result))->pgresult;
1525         PUKE_IF_NULL(R);
1526
1527         return make_int(PQftype(R, XINT(field_index)));
1528 }
1529
1530 DEFUN("pq-fmod", Fpq_fmod, 2, 2, 0,     /*
1531 Return the type modifier associated with a field.
1532 Field indices start at 0.
1533 */
1534       (result, field_index))
1535 {
1536         PGresult *R;
1537
1538         CHECK_PGRESULT(result);
1539         CHECK_INT(field_index);
1540         R = (XPGRESULT(result))->pgresult;
1541         PUKE_IF_NULL(R);
1542
1543         return make_int(PQfmod(R, XINT(field_index)));
1544 }
1545
1546 DEFUN("pq-get-value", Fpq_get_value, 3, 3, 0,   /*
1547 Return a single field (attribute) value of one tuple of a PGresult.
1548 Tuple and field indices start at 0.
1549 */
1550       (result, tup_num, field_num))
1551 {
1552         PGresult *R;
1553
1554         CHECK_PGRESULT(result);
1555         CHECK_INT(tup_num);
1556         CHECK_INT(field_num);
1557         R = (XPGRESULT(result))->pgresult;
1558         PUKE_IF_NULL(R);
1559
1560         return build_ext_string(PQgetvalue(R, XINT(tup_num), XINT(field_num)),
1561                                 PG_OS_CODING);
1562 }
1563
1564 DEFUN("pq-get-length", Fpq_get_length, 3, 3, 0, /*
1565 Returns the length of a field value in bytes.
1566 If result is binary, i.e. a result of a binary portal, then the
1567 length returned does NOT include the size field of the varlena.  (The
1568 data returned by PQgetvalue doesn't either.)
1569 */
1570       (result, tup_num, field_num))
1571 {
1572         PGresult *R;
1573
1574         CHECK_PGRESULT(result);
1575         CHECK_INT(tup_num);
1576         CHECK_INT(field_num);
1577         R = (XPGRESULT(result))->pgresult;
1578         PUKE_IF_NULL(R);
1579
1580         return make_int(PQgetlength(R, XINT(tup_num), XINT(field_num)));
1581 }
1582
1583 DEFUN("pq-get-is-null", Fpq_get_is_null, 3, 3, 0,       /*
1584 Returns the null status of a field value.
1585 */
1586       (result, tup_num, field_num))
1587 {
1588         PGresult *R;
1589
1590         CHECK_PGRESULT(result);
1591         CHECK_INT(tup_num);
1592         CHECK_INT(field_num);
1593         R = (XPGRESULT(result))->pgresult;
1594         PUKE_IF_NULL(R);
1595
1596         return PQgetisnull(R, XINT(tup_num), XINT(field_num)) ? Qt : Qnil;
1597 }
1598
1599 DEFUN("pq-cmd-status", Fpq_cmd_status, 1, 1, 0, /*
1600 Returns the command status string from the SQL command that generated the result.
1601 */
1602       (result))
1603 {
1604         PGresult *R;
1605
1606         CHECK_PGRESULT(result);
1607         R = (XPGRESULT(result))->pgresult;
1608         PUKE_IF_NULL(R);
1609
1610         return build_ext_string(PQcmdStatus(R), PG_OS_CODING);
1611 }
1612
1613 DEFUN("pq-cmd-tuples", Fpq_cmd_tuples, 1, 1, 0, /*
1614 Returns the number of rows affected by the SQL command.
1615 */
1616       (result))
1617 {
1618         PGresult *R;
1619
1620         CHECK_PGRESULT(result);
1621         R = (XPGRESULT(result))->pgresult;
1622         PUKE_IF_NULL(R);
1623
1624         return build_ext_string(PQcmdTuples(R), PG_OS_CODING);
1625 }
1626
1627 DEFUN("pq-oid-value", Fpq_oid_value, 1, 1, 0,   /*
1628 Returns the object id of the tuple inserted.
1629 */
1630       (result))
1631 {
1632         PGresult *R;
1633
1634         CHECK_PGRESULT(result);
1635         R = (XPGRESULT(result))->pgresult;
1636         PUKE_IF_NULL(R);
1637
1638 #ifdef HAVE_POSTGRESQLV7
1639         return make_int(PQoidValue(R));
1640 #else
1641         /* Use the old interface */
1642         return make_int(atoi(PQoidStatus(R)));
1643 #endif
1644 }
1645
1646 #ifdef HAVE_POSTGRESQLV7
1647 DEFUN("pq-set-nonblocking", Fpq_set_nonblocking, 2, 2, 0,       /*
1648 Sets the PGconn's database connection non-blocking if the arg is TRUE
1649 or makes it non-blocking if the arg is FALSE, this will not protect
1650 you from PQexec(), you'll only be safe when using the non-blocking API.
1651
1652 Needs to be called only on a connected database connection.
1653 */
1654       (conn, arg))
1655 {
1656         PGconn *P;
1657
1658         CHECK_PGCONN(conn);
1659         P = (XPGCONN(conn))->pgconn;
1660         CHECK_CONNECTION_ALIVE(P);
1661
1662         return make_int(PQsetnonblocking(P, !NILP(arg)));
1663 }
1664
1665 DEFUN("pq-is-nonblocking", Fpq_is_nonblocking, 1, 1, 0, /*
1666 Return the blocking status of the database connection.
1667 */
1668       (conn))
1669 {
1670         PGconn *P;
1671
1672         CHECK_PGCONN(conn);
1673         P = (XPGCONN(conn))->pgconn;
1674         CHECK_CONNECTION_ALIVE(P);
1675
1676         return PQisnonblocking(P) ? Qt : Qnil;
1677 }
1678
1679 DEFUN("pq-flush", Fpq_flush, 1, 1, 0,   /*
1680 Force the write buffer to be written (or at least try).
1681 */
1682       (conn))
1683 {
1684         PGconn *P;
1685
1686         CHECK_PGCONN(conn);
1687         P = (XPGCONN(conn))->pgconn;
1688         CHECK_CONNECTION_ALIVE(P);
1689
1690         return make_int(PQflush(P));
1691 }
1692 #endif
1693
1694 DEFUN("pq-notifies", Fpq_notifies, 1, 1, 0,     /*
1695 Return the latest async notification that has not yet been handled.
1696 If there has been a notification, then a list of two elements will be returned.
1697 The first element contains the relation name being notified, the second
1698 element contains the backend process ID number.  nil is returned if there
1699 aren't any notifications to process.
1700 */
1701       (conn))
1702 {
1703         /* This function cannot GC */
1704         PGconn *P;
1705         PGnotify *PGN;
1706
1707         CHECK_PGCONN(conn);
1708         P = (XPGCONN(conn))->pgconn;
1709         CHECK_CONNECTION_ALIVE(P);
1710
1711         PGN = PQnotifies(P);
1712         if (!PGN)
1713                 return Qnil;
1714         else {
1715                 Lisp_Object temp;
1716
1717                 temp = list2(build_ext_string(PGN->relname, PG_OS_CODING),
1718                              make_int(PGN->be_pid));
1719                 xfree(PGN);
1720                 return temp;
1721         }
1722 }
1723
1724 #if defined (HAVE_POSTGRESQLV7) && defined(MULE)
1725 DEFUN("pq-env-2-encoding", Fpq_env_2_encoding, 0, 0, 0, /*
1726 Get encoding id from environment variable PGCLIENTENCODING.
1727 */
1728       ())
1729 {
1730         return make_int(PQenv2encoding());
1731 }
1732 #endif                          /* MULE */
1733
1734 DEFUN("pq-lo-import", Fpq_lo_import, 2, 2, 0,   /*
1735 */
1736       (conn, filename))
1737 {
1738         PGconn *P;
1739         char *c_filename;
1740
1741         CHECK_PGCONN(conn);
1742         CHECK_STRING(filename);
1743
1744         P = (XPGCONN(conn))->pgconn;
1745         CHECK_CONNECTION_ALIVE(P);
1746
1747         TO_EXTERNAL_FORMAT(LISP_STRING, filename,
1748                            C_STRING_ALLOCA, c_filename, Qfile_name);
1749
1750         return make_int((int)lo_import(P, c_filename));
1751 }
1752
1753 DEFUN("pq-lo-export", Fpq_lo_export, 3, 3, 0,   /*
1754 */
1755       (conn, oid, filename))
1756 {
1757         PGconn *P;
1758         char *c_filename;
1759
1760         CHECK_PGCONN(conn);
1761         CHECK_INT(oid);
1762         CHECK_STRING(filename);
1763
1764         P = (XPGCONN(conn))->pgconn;
1765         CHECK_CONNECTION_ALIVE(P);
1766
1767         TO_EXTERNAL_FORMAT(LISP_STRING, filename,
1768                            C_STRING_ALLOCA, c_filename, Qfile_name);
1769
1770         return make_int((int)lo_export(P, XINT(oid), c_filename));
1771 }
1772
1773 DEFUN("pq-make-empty-pgresult", Fpq_make_empty_pgresult, 2, 2, 0,       /*
1774 Make an empty PGresult object with the given status.
1775 */
1776       (conn, status))
1777 {
1778         PGconn *P;
1779         Lisp_PGresult *lpgr;
1780         PGresult *R;
1781         ExecStatusType est;
1782
1783         CHECK_PGCONN(conn);
1784         P = (XPGCONN(conn))->pgconn;
1785         CHECK_CONNECTION_ALIVE(P);      /* needed here? */
1786
1787         if (EQ(status, Q_pgres_empty_query))
1788                 est = PGRES_EMPTY_QUERY;
1789         else if (EQ(status, Q_pgres_command_ok))
1790                 est = PGRES_COMMAND_OK;
1791         else if (EQ(status, Q_pgres_tuples_ok))
1792                 est = PGRES_TUPLES_OK;
1793         else if (EQ(status, Q_pgres_copy_out))
1794                 est = PGRES_COPY_OUT;
1795         else if (EQ(status, Q_pgres_copy_in))
1796                 est = PGRES_COPY_IN;
1797         else if (EQ(status, Q_pgres_bad_response))
1798                 est = PGRES_BAD_RESPONSE;
1799         else if (EQ(status, Q_pgres_nonfatal_error))
1800                 est = PGRES_NONFATAL_ERROR;
1801         else if (EQ(status, Q_pgres_fatal_error))
1802                 est = PGRES_FATAL_ERROR;
1803         else
1804                 signal_simple_error("bad status symbol", status);
1805
1806         R = PQmakeEmptyPGresult(P, est);
1807         if (!R)
1808                 error("out of memory?");
1809
1810         lpgr = allocate_pgresult();
1811         lpgr->pgresult = R;
1812
1813         return make_pgresult(lpgr);
1814 }
1815
1816 #ifdef HAVE_POSTGRESQLV7
1817 /* actually I don't know when this made its way to libpq
1818  * I just assume 7.4 here
1819  * Bite me, if that's wrong ;P
1820  */
1821 DEFUN("pq-escape-string", Fpq_escape_string, 1, 1, 0, /*
1822 Return an SQL-suited escaped version of STRING.
1823 */
1824       (string))
1825 {
1826         char *result;
1827         int result_len;
1828         /* buffers for our args */
1829         char *string_ext;
1830         int string_len;
1831
1832         TO_EXTERNAL_FORMAT(LISP_STRING, string,
1833                            C_STRING_ALLOCA, string_ext, PG_OS_CODING);
1834         string_len = (int)XSTRING_CHAR_LENGTH(string);
1835
1836         result = (char *)xmalloc_atomic(4*XSTRING_LENGTH(string));
1837
1838         result_len = PQescapeString(result, string_ext, string_len);
1839
1840         return make_ext_string(result, result_len, PG_OS_CODING);
1841 }
1842
1843 DEFUN("pq-escape-bytea", Fpq_escape_bytea, 1, 1, 0, /*
1844 Return an SQL-suited escaped version of binary DATA.
1845 */
1846       (data))
1847 {
1848         char *result;
1849         unsigned int result_len;
1850         /* buffers for our args */
1851         char *data_ext;
1852         int data_len;
1853
1854         TO_EXTERNAL_FORMAT(LISP_STRING, data,
1855                            C_STRING_ALLOCA, data_ext, PG_OS_CODING);
1856         data_len = (int)XSTRING_CHAR_LENGTH(data);
1857
1858         result = (char*)PQescapeBytea((unsigned char*)data_ext, data_len,
1859                                       &result_len);
1860
1861         if (result == NULL)
1862                 return Qnil;
1863         else
1864                 return make_ext_string(result,result_len-1,PG_OS_CODING);
1865 }
1866
1867 DEFUN("pq-unescape-bytea", Fpq_unescape_bytea, 1, 1, 0, /*
1868 Return the unescaped form of DATA (which may be binary).
1869 Such binary data may result from a BYTEA column.
1870
1871 Note: Of course, escaped SQL strings are elisp-escaped again
1872 so you may have to use `pq-unescape-bytea' twice.
1873 */
1874       (data))
1875 {
1876         char *result;
1877         unsigned int result_len;
1878         /* buffers for our args */
1879         char *data_ext;
1880
1881         TO_EXTERNAL_FORMAT(LISP_STRING, data,
1882                            C_STRING_ALLOCA, data_ext, PG_OS_CODING);
1883
1884         result = (char*)PQunescapeBytea((unsigned char*)data_ext,
1885                                         &result_len);
1886
1887         if (result == NULL)
1888                 return Qnil;
1889         else
1890                 return make_ext_string(result,result_len,PG_OS_CODING);
1891 }
1892 #endif
1893
1894 DEFUN("pq-get-line", Fpq_get_line, 1, 1, 0,     /*
1895 Retrieve a line from server in copy in operation.
1896 The return value is a dotted pair where the cons cell is an integer code:
1897 -1: Copying is complete
1898 0: A record is complete
1899 1: A record is incomplete, it will be continued in the next `pq-get-line'
1900 operation.
1901 and the cdr cell is returned string data.
1902
1903 The copy operation is complete when the value `\.' (backslash dot) is
1904 returned.
1905 */
1906       (conn))
1907 {
1908         char buffer[BLCKSZ];    /* size of a Postgres disk block */
1909         PGconn *P;
1910         int ret;
1911
1912         CHECK_PGCONN(conn);
1913         P = (XPGCONN(conn))->pgconn;
1914         CHECK_CONNECTION_ALIVE(P);
1915
1916         ret = PQgetline(P, buffer, sizeof(buffer));
1917
1918         return Fcons(make_int(ret), build_ext_string(buffer, PG_OS_CODING));
1919 }
1920
1921 DEFUN("pq-put-line", Fpq_put_line, 2, 2, 0,     /*
1922 Send a line to the server in copy out operation.
1923
1924 Returns t if the operation succeeded, nil otherwise.
1925 */
1926       (conn, string))
1927 {
1928         PGconn *P;
1929         char *c_string;
1930
1931         CHECK_PGCONN(conn);
1932         CHECK_STRING(string);
1933
1934         P = (XPGCONN(conn))->pgconn;
1935         CHECK_CONNECTION_ALIVE(P);
1936         TO_EXTERNAL_FORMAT(LISP_STRING, string,
1937                            C_STRING_ALLOCA, c_string, Qnative);
1938
1939         return !PQputline(P, c_string) ? Qt : Qnil;
1940 }
1941
1942 DEFUN("pq-get-line-async", Fpq_get_line_async, 1, 1, 0, /*
1943 Get a line from the server in copy in operation asynchronously.
1944
1945 This routine is for applications that want to do "COPY <rel> to stdout"
1946 asynchronously, that is without blocking.  Having issued the COPY command
1947 and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput
1948 and this routine until the end-of-data signal is detected.  Unlike
1949 PQgetline, this routine takes responsibility for detecting end-of-data.
1950
1951 On each call, PQgetlineAsync will return data if a complete newline-
1952 terminated data line is available in libpq's input buffer, or if the
1953 incoming data line is too long to fit in the buffer offered by the caller.
1954 Otherwise, no data is returned until the rest of the line arrives.
1955
1956 If -1 is returned, the end-of-data signal has been recognized (and removed
1957 from libpq's input buffer).  The caller *must* next call PQendcopy and
1958 then return to normal processing.
1959
1960 RETURNS:
1961 -1    if the end-of-copy-data marker has been recognized
1962 0         if no data is available
1963 >0    the number of bytes returned.
1964 The data returned will not extend beyond a newline character.  If possible
1965 a whole line will be returned at one time.  But if the buffer offered by
1966 the caller is too small to hold a line sent by the backend, then a partial
1967 data line will be returned.  This can be detected by testing whether the
1968 last returned byte is '\n' or not.
1969 The returned string is *not* null-terminated.
1970 */
1971       (conn))
1972 {
1973         PGconn *P;
1974         char buffer[BLCKSZ];
1975         int ret;
1976
1977         CHECK_PGCONN(conn);
1978
1979         P = (XPGCONN(conn))->pgconn;
1980         CHECK_CONNECTION_ALIVE(P);
1981
1982         ret = PQgetlineAsync(P, buffer, sizeof(buffer));
1983
1984         if (ret == -1)
1985                 return Qt;      /* done! */
1986         else if (!ret)
1987                 return Qnil;    /* no data yet */
1988         else
1989                 return Fcons(make_int(ret),
1990                              make_ext_string((Extbyte *) buffer, ret,
1991                                              PG_OS_CODING));
1992 }
1993
1994 DEFUN("pq-put-nbytes", Fpq_put_nbytes, 2, 2, 0, /*
1995 Asynchronous copy out.
1996 */
1997       (conn, data))
1998 {
1999         /* NULs are not allowed.  I don't think this matters at this time. */
2000         PGconn *P;
2001         char *c_data;
2002
2003         CHECK_PGCONN(conn);
2004         CHECK_STRING(data);
2005
2006         P = (XPGCONN(conn))->pgconn;
2007         CHECK_CONNECTION_ALIVE(P);
2008         TO_EXTERNAL_FORMAT(LISP_STRING, data, C_STRING_ALLOCA, c_data, Qnative);
2009
2010         return !PQputnbytes(P, c_data, strlen(c_data)) ? Qt : Qnil;
2011 }
2012
2013 DEFUN("pq-end-copy", Fpq_end_copy, 1, 1, 0,     /*
2014 End a copying operation.
2015 */
2016       (conn))
2017 {
2018         PGconn *P;
2019
2020         CHECK_PGCONN(conn);
2021         P = (XPGCONN(conn))->pgconn;
2022         CHECK_CONNECTION_ALIVE(P);
2023
2024         return PQendcopy(P) ? Qt : Qnil;
2025 }
2026
2027 \f
2028 void
2029 syms_of_postgresql(void)
2030 {
2031         INIT_LRECORD_IMPLEMENTATION(pgconn);
2032         INIT_LRECORD_IMPLEMENTATION(pgresult);
2033
2034         defsymbol(&Qpostgresql, "postgresql");
2035
2036         /* opaque exported types */
2037         defsymbol(&Qpgconnp, "pgconnp");
2038         defsymbol(&Qpgresultp, "pgresultp");
2039
2040         /* connection status types
2041          * now implemented as keywords */
2042         DEFKEYWORD(Q_pg_connection_ok);
2043         DEFKEYWORD(Q_pg_connection_bad);
2044         DEFKEYWORD(Q_pg_connection_started);
2045         DEFKEYWORD(Q_pg_connection_made);
2046         DEFKEYWORD(Q_pg_connection_awaiting_response);
2047         DEFKEYWORD(Q_pg_connection_auth_ok);
2048         DEFKEYWORD(Q_pg_connection_setenv);
2049
2050         /* transaction status types */
2051         DEFKEYWORD(Q_pg_trans_idle);
2052         DEFKEYWORD(Q_pg_trans_active);
2053         DEFKEYWORD(Q_pg_trans_intrans);
2054         DEFKEYWORD(Q_pg_trans_inerror);
2055         DEFKEYWORD(Q_pg_trans_unknown);
2056
2057         /* Fields of PGconn */
2058         DEFKEYWORD(Q_pq_db);
2059         DEFKEYWORD(Q_pq_user);
2060         DEFKEYWORD(Q_pq_pass);
2061         DEFKEYWORD(Q_pq_host);
2062         DEFKEYWORD(Q_pq_port);
2063         DEFKEYWORD(Q_pq_tty);
2064         DEFKEYWORD(Q_pq_options);
2065         DEFKEYWORD(Q_pq_status);
2066         DEFKEYWORD(Q_pq_transaction_status);
2067         DEFKEYWORD(Q_pq_parameter_status);
2068         DEFKEYWORD(Q_pq_protocol_version);
2069         DEFKEYWORD(Q_pq_server_version);
2070         DEFKEYWORD(Q_pq_error_message);
2071         DEFKEYWORD(Q_pq_backend_pid);
2072 #ifdef HAVE_OPENSSL
2073         DEFKEYWORD(Q_pq_getssl);
2074 #endif
2075
2076         /* Query status results */
2077         DEFKEYWORD(Q_pgres_empty_query);
2078         DEFKEYWORD(Q_pgres_command_ok);
2079         DEFKEYWORD(Q_pgres_tuples_ok);
2080         DEFKEYWORD(Q_pgres_copy_out);
2081         DEFKEYWORD(Q_pgres_copy_in);
2082         DEFKEYWORD(Q_pgres_bad_response);
2083         DEFKEYWORD(Q_pgres_nonfatal_error);
2084         DEFKEYWORD(Q_pgres_fatal_error);
2085
2086         /* Poll status results */
2087         DEFKEYWORD(Q_pgres_polling_failed);
2088         DEFKEYWORD(Q_pgres_polling_reading);
2089         DEFKEYWORD(Q_pgres_polling_writing);
2090         DEFKEYWORD(Q_pgres_polling_ok);
2091         DEFKEYWORD(Q_pgres_polling_active);
2092
2093 #ifdef HAVE_POSTGRESQLV7
2094         DEFSUBR(Fpq_connect_start);
2095         DEFSUBR(Fpq_connect_poll);
2096 #ifdef MULE
2097         DEFSUBR(Fpq_client_encoding);
2098         DEFSUBR(Fpq_set_client_encoding);
2099 #endif                          /* MULE */
2100 #endif                          /* HAVE_POSTGRESQLV7 */
2101         DEFSUBR(Fpq_set_notice_processor);
2102
2103         DEFSUBR(Fpq_connection_p);
2104         DEFSUBR(Fpq_conn_defaults);
2105         DEFSUBR(Fpq_connectdb);
2106         DEFSUBR(Fpq_finish);
2107         DEFSUBR(Fpq_clear);
2108         DEFSUBR(Fpq_is_busy);
2109         DEFSUBR(Fpq_consume_input);
2110
2111 #ifdef HAVE_POSTGRESQLV7
2112         DEFSUBR(Fpq_escape_string);
2113         DEFSUBR(Fpq_escape_bytea);
2114         DEFSUBR(Fpq_unescape_bytea);
2115 #endif
2116
2117         DEFSUBR(Fpq_reset);
2118 #ifdef HAVE_POSTGRESQLV7
2119         DEFSUBR(Fpq_reset_start);
2120         DEFSUBR(Fpq_reset_poll);
2121 #endif
2122         DEFSUBR(Fpq_request_cancel);
2123         DEFSUBR(Fpq_connection_status);
2124         DEFSUBR(Fpq_connection_alive_p);
2125
2126         DEFSUBR(Fpq_exec);
2127         DEFSUBR(Fpq_send_query);
2128         DEFSUBR(Fpq_result_p);
2129         DEFSUBR(Fpq_get_result);
2130         DEFSUBR(Fpq_result_status);
2131         DEFSUBR(Fpq_result_status_string);
2132         DEFSUBR(Fpq_result_error_message);
2133         DEFSUBR(Fpq_ntuples);
2134         DEFSUBR(Fpq_nfields);
2135         DEFSUBR(Fpq_binary_tuples);
2136         DEFSUBR(Fpq_fname);
2137         DEFSUBR(Fpq_fnumber);
2138         DEFSUBR(Fpq_ftype);
2139         DEFSUBR(Fpq_fsize);
2140         DEFSUBR(Fpq_fmod);
2141         /***/
2142         DEFSUBR(Fpq_get_value);
2143         DEFSUBR(Fpq_get_length);
2144         DEFSUBR(Fpq_get_is_null);
2145         DEFSUBR(Fpq_cmd_status);
2146         DEFSUBR(Fpq_cmd_tuples);
2147         DEFSUBR(Fpq_oid_value);
2148
2149 #ifdef HAVE_POSTGRESQLV7
2150         DEFSUBR(Fpq_set_nonblocking);
2151         DEFSUBR(Fpq_is_nonblocking);
2152         DEFSUBR(Fpq_flush);
2153 #endif
2154         DEFSUBR(Fpq_notifies);
2155
2156 #if defined (HAVE_POSTGRESQLV7) && defined(MULE)
2157         DEFSUBR(Fpq_env_2_encoding);
2158 #endif
2159
2160         DEFSUBR(Fpq_lo_import);
2161         DEFSUBR(Fpq_lo_export);
2162
2163         DEFSUBR(Fpq_make_empty_pgresult);
2164
2165         /* copy in/out functions */
2166         DEFSUBR(Fpq_get_line);
2167         DEFSUBR(Fpq_put_line);
2168         DEFSUBR(Fpq_get_line_async);
2169         DEFSUBR(Fpq_put_nbytes);
2170         DEFSUBR(Fpq_end_copy);
2171 }
2172
2173 void vars_of_postgresql(void)
2174 {
2175         Fprovide(Qpostgresql);
2176 #ifdef HAVE_POSTGRESQLV7
2177         Fprovide(intern("postgresqlv7"));
2178 #endif
2179         Vpg_coding_system = Qnative;
2180         DEFVAR_LISP("pg-coding-system", &Vpg_coding_system      /*
2181 Default Postgres client coding system.
2182                                                                 */ );
2183
2184         DEFVAR_LISP("pg:host", &VXPGHOST        /*
2185 Default PostgreSQL server name.
2186 If not set, the server running on the local host is used.  The
2187 initial value is set from the PGHOST environment variable.
2188                                                  */ );
2189
2190         DEFVAR_LISP("pg:user", &VXPGUSER        /*
2191 Default PostgreSQL user name.
2192 This value is used when connecting to a database for authentication.
2193 The initial value is set from the PGUSER environment variable.
2194                                                  */ );
2195
2196         DEFVAR_LISP("pg:options", &VXPGOPTIONS  /*
2197 Default PostgreSQL user name.
2198 This value is used when connecting to a database for authentication.
2199 The initial value is set from the PGUSER environment variable.
2200                                                  */ );
2201
2202         DEFVAR_LISP("pg:port", &VXPGPORT        /*
2203 Default port to connect to PostgreSQL backend.
2204 This value is used when connecting to a database.
2205 The initial value is set from the PGPORT environment variable.
2206                                                  */ );
2207
2208         DEFVAR_LISP("pg:tty", &VXPGTTY  /*
2209 Default debugging TTY.
2210 There is no useful setting of this variable in the XEmacs Lisp API.
2211 The initial value is set from the PGTTY environment variable.
2212                                          */ );
2213
2214         DEFVAR_LISP("pg:database", &VXPGDATABASE        /*
2215 Default database to connect to.
2216 The initial value is set from the PGDATABASE environment variable.
2217                                                          */ );
2218
2219         DEFVAR_LISP("pg:realm", &VXPGREALM      /*
2220 Default kerberos realm to use for authentication.
2221 The initial value is set from the PGREALM environment variable.
2222                                                  */ );
2223
2224 #ifdef MULE
2225         /* It's not clear whether this is any use.  My intent is to
2226            autodetect the coding system from the database. */
2227         DEFVAR_LISP("pg:client-encoding", &VXPGCLIENTENCODING   /*
2228 Default client encoding to use.
2229 The initial value is set from the PGCLIENTENCODING environment variable.
2230                                                                  */ );
2231 #endif
2232
2233 #if !defined(HAVE_POSTGRESQLV7)
2234         DEFVAR_LISP("pg:authtype", &VXPGAUTHTYPE        /*
2235 Default authentication to use.
2236 The initial value is set from the PGAUTHTYPE environment variable.
2237
2238 WARNING:  This variable has gone away in versions of PostgreSQL newer
2239 than 6.5.
2240                                                          */ );
2241 #endif
2242
2243         DEFVAR_LISP("pg:geqo", &VXPGGEQO        /*
2244 Genetic Query Optimizer options.
2245 The initial value is set from the PGGEQO environment variable.
2246                                                  */ );
2247
2248         DEFVAR_LISP("pg:cost-index", &VXPGCOSTINDEX     /*
2249 Default cost index options.
2250 The initial value is set from the PGCOSTINDEX environment variable.
2251                                                          */ );
2252
2253         DEFVAR_LISP("pg:cost-heap", &VXPGCOSTHEAP       /*
2254 Default cost heap options.
2255 The initial value is set from the PGCOSTHEAP environment variable.
2256                                                          */ );
2257
2258         DEFVAR_LISP("pg:tz", &VXPGTZ    /*
2259 Default timezone to use.
2260 The initial value is set from the PGTZ environment variable.
2261                                          */ );
2262
2263         DEFVAR_LISP("pg:date-style", &VXPGDATESTYLE     /*
2264 Default date style to use.
2265 The initial value is set from the PGDATESTYLE environment variable.
2266                                                          */ );
2267 }
2268
2269 /* These initializations should not be done at dump-time. */
2270 void
2271 init_postgresql_from_environment(void)
2272 {
2273         char *p;
2274
2275         if ((p = getenv("PGHOST"))) {
2276                 VXPGHOST = build_ext_string(p, PG_OS_CODING);
2277         } else {
2278                 VXPGHOST = Qnil;
2279         }
2280
2281         if ((p = getenv("PGUSER"))) {
2282                 VXPGUSER = build_ext_string(p, PG_OS_CODING);
2283         } else {
2284                 VXPGUSER = Qnil;
2285         }
2286
2287         if ((p = getenv("PGOPTIONS"))) {
2288                 VXPGOPTIONS = build_ext_string(p, PG_OS_CODING);
2289         } else {
2290                 VXPGOPTIONS = Qnil;
2291         }
2292
2293         if ((p = getenv("PGPORT"))) {
2294                 VXPGPORT = make_int(atoi(p));
2295         } else {
2296                 VXPGPORT = Qnil;
2297         }
2298
2299         if ((p = getenv("PGTTY"))) {
2300                 VXPGTTY = build_ext_string(p, PG_OS_CODING);
2301         } else {
2302                 VXPGTTY = Qnil;
2303         }
2304
2305         if ((p = getenv("PGDATABASE"))) {
2306                 VXPGDATABASE = build_ext_string(p, PG_OS_CODING);
2307         } else {
2308                 VXPGDATABASE = Qnil;
2309         }
2310
2311         if ((p = getenv("PGREALM"))) {
2312                 VXPGREALM = build_ext_string(p, PG_OS_CODING);
2313         } else {
2314                 VXPGREALM = Qnil;
2315         }
2316
2317 #ifdef MULE
2318         /* It's not clear whether this is any use.  My intent is to
2319            autodetect the coding system from the database. */
2320         if ((p = getenv("PGCLIENTENCODING"))) {
2321                 VXPGCLIENTENCODING = build_ext_string(p, PG_OS_CODING);
2322         } else {
2323                 VXPGCLIENTENCODING = Qnil;
2324         }
2325 #endif
2326
2327 #if !defined(HAVE_POSTGRESQLV7)
2328         if ((p = getenv("PGAUTHTYPE"))) {
2329                 VXPGAUTHTYPE = build_ext_string(p, PG_OS_CODING);
2330         } else {
2331                 VXPGAUTHTYPE = Qnil;
2332         }
2333 #endif
2334
2335         if ((p = getenv("PGGEQO"))) {
2336                 VXPGGEQO = build_ext_string(p, PG_OS_CODING);
2337         } else {
2338                 VXPGGEQO = Qnil;
2339         }
2340
2341         if ((p = getenv("PGCOSTINDEX"))) {
2342                 VXPGCOSTINDEX = build_ext_string(p, PG_OS_CODING);
2343         } else {
2344                 VXPGCOSTINDEX = Qnil;
2345         }
2346
2347         if ((p = getenv("PGCOSTHEAP"))) {
2348                 VXPGCOSTHEAP = build_ext_string(p, PG_OS_CODING);
2349         } else {
2350                 VXPGCOSTHEAP = Qnil;
2351         }
2352
2353         if ((p = getenv("PGTZ"))) {
2354                 VXPGTZ = build_ext_string(p, PG_OS_CODING);
2355         } else {
2356                 VXPGTZ = Qnil;
2357         }
2358
2359         if ((p = getenv("PGDATESTYLE"))) {
2360                 VXPGDATESTYLE = build_ext_string(p, PG_OS_CODING);
2361         } else {
2362                 VXPGDATESTYLE = Qnil;
2363         }
2364 }
2365
2366 /* postgresql.c ends here */