XEmacs 21.2.33 "Melpomene".
[chise/xemacs-chise.git.1] / src / postgresql.c
1 /*
2   postgresql.c -- Emacs Lisp binding to libpq.so
3   Copyright (C) 2000 Electrotechnical Laboratory, JAPAN.
4   Licensed to the Free Software Foundation.
5
6   Author:  SL Baur <steve@beopen.com>
7   Maintainer:  SL Baur <steve@beopen.com>
8
9 Please send patches to this file to me first before submitting them to
10 xemacs-patches.
11
12
13 KNOWN PROBLEMS (Last update 15-March-2000)
14 +  None.
15
16 Implementation notes:
17 0. Supported PostgreSQL versions
18    This code was developed against libpq-6.5.3 and libpq-7.0-beta1.  Earlier
19    versions may work.  V7 support is more complete than V6.5 support.
20 1. Mule
21    Non-ASCII databases have been tested on both 6.5 and 7.0.
22 2. Asynchronous Operation
23    Starting with libpq-7.0, an asynchronous interface is offered.  This
24    binding supports the asynchronous calls to a limited extent.  Since the
25    XEmacs 21.2 core does not support a sensible interface to add managed but
26    unreadable (by XEmacs) file descriptors to the main select code, polling
27    is required to drive the asynchronous calls.  XtAppAddInput would work
28    fine, but we want to be able to use the database when running strictly in
29    tty mode.
30 3. Completeness
31    Various calls have been deliberately not exported to Lisp.  The
32    unexported calls are either left-over backwards compatibility code that
33    aren't needed, calls that cannot be implemented sensibly, or calls that
34    cannot be implemented safely.  A list of all global functions in libpq
35    but not exported to Lisp is below.
36 4. Policy
37    This interface tries very hard to not set any policy towards how database
38    code in Emacs Lisp will be written.
39 5. Documentation
40    For full lisp programming documentation, see the XEmacs Lisp Reference
41    Manual.  For PostgreSQL documentation, see the PostgreSQL distribution.
42
43 TODO (in rough order of priority):
44 1. Asynchronous notifies need to be implemented to the extent they can be.
45 2. The large object interface needs work with Emacs buffers in addition
46    to files.  Need two functions buffer->large_object, and large_object->
47    buffer.
48 */
49
50 /*
51   Unimplemented functions: [TODO]
52   PQsetNoticeProcessor
53
54   Implemented, but undocumented functions: [TODO]
55   PQgetline (copy in/out)
56   PQputline (copy in/out)
57   PQgetlineAsync (copy in/out Asynch.)
58   PQputnbytes (copy in/out Asynch.)
59   PQendcopy (copy in/out)
60
61   Unsupported functions:
62   PQsetdbLogin -- This function is deprecated, has a subset of the
63    functionality of PQconnectdb, and is better done in Lisp.
64   PQsetdb -- Same as for PQsetdbLogin
65   PQsocket -- Abstraction error, file descriptors should not be leaked
66    into Lisp code
67   PQprint -- print to a file descriptor, deprecated, better done in Lisp
68   PQdisplayTuples -- deprecated
69   PQprintTuples -- really, really deprecated
70   PQmblen -- Returns the length in bytes of multibyte character encoded
71    string.
72   PQtrace -- controls debug print tracing to a tty.
73   PQuntrace -- Ditto.  I don't see any way to do this sensibly.
74   PQoidStatus -- deprecated and nearly identical to PQoidValue
75   PQfn -- "Fast path" interface
76   lo_open (large object) [*]
77   lo_close (large object) [*]
78   lo_read (large object) [*]
79   lo_write (large object) [*]
80   lo_lseek (large object) [*]
81   lo_creat (large object) [*]
82   lo_tell (large object) [*]
83   lo_unlink (large object) [*]
84 */
85
86 #include <config.h>
87
88 /* This must be portable with XEmacs 21.1 so long as it is the official
89    released version of XEmacs and provides the basis of InfoDock.  The
90    interface to lcrecord handling has changed with 21.2, so unfortunately
91    we will need a few snippets of backwards compatibility code.
92 */
93 #if (EMACS_MAJOR_VERSION == 21) && (EMACS_MINOR_VERSION < 2)
94 #define RUNNING_XEMACS_21_1 1
95 #define POSTGRES_INCLUDE(file) <file>
96 #endif
97
98 /* #define POSTGRES_LO_IMPORT_IS_VOID 1 */
99
100 #include "lisp.h"
101 #include "sysdep.h"
102 #include "buffer.h"
103
104 #include POSTGRES_INCLUDE (libpq-fe.h)
105 #include "postgresql.h"
106
107 #ifdef RUNNING_XEMACS_21_1 /* handle interface changes */
108 #define I_HATE_CONST CONST
109 #define PG_OS_CODING FORMAT_FILENAME
110 #define TO_EXTERNAL_FORMAT(a,from,b,to,c) GET_C_STRING_EXT_DATA_ALLOCA(from,FORMAT_FILENAME,to)
111 #else
112 #define I_HATE_CONST const
113 #ifdef MULE
114 #define PG_OS_CODING Fget_coding_system(Vpg_coding_system)
115 #else
116 #define PG_OS_CODING Qnative
117 #endif
118 Lisp_Object Vpg_coding_system;
119 #endif
120
121 #define CHECK_LIVE_CONNECTION(P) { \
122         if (!P || (PQstatus (P) != CONNECTION_OK)) { \
123                 char *e = "bad value"; \
124                 if (P) e = PQerrorMessage (P); \
125                 error ("dead connection [%s]", e); \
126         } }
127 #define PUKE_IF_NULL(p) { \
128         if (!p) error ("bad value"); \
129         }
130
131 static Lisp_Object VXPGHOST;
132 static Lisp_Object VXPGUSER;
133 static Lisp_Object VXPGOPTIONS;
134 static Lisp_Object VXPGPORT;
135 static Lisp_Object VXPGTTY; /* This needs to be blanked! */
136 static Lisp_Object VXPGDATABASE;
137 static Lisp_Object VXPGREALM;
138 #ifdef MULE
139 static Lisp_Object VXPGCLIENTENCODING;
140 #endif /* MULE */
141
142 /* Other variables:
143    PGAUTHTYPE -- not used after PostgreSQL 6.5
144    PGGEQO
145    PGCOSTINDEX
146    PGCOSTHEAP
147    PGTZ
148    PGDATESTYLE
149 */
150 #ifndef HAVE_POSTGRESQLV7
151 static Lisp_Object VXPGAUTHTYPE;
152 #endif
153 static Lisp_Object VXPGGEQO, VXPGCOSTINDEX, VXPGCOSTHEAP, VXPGTZ, VXPGDATESTYLE;
154
155 static Lisp_Object Qpostgresql;
156 static Lisp_Object Qpg_connection_ok, Qpg_connection_bad;
157 static Lisp_Object Qpg_connection_started, Qpg_connection_made;
158 static Lisp_Object Qpg_connection_awaiting_response, Qpg_connection_auth_ok;
159 static Lisp_Object Qpg_connection_setenv;
160
161 static Lisp_Object Qpqdb, Qpquser, Qpqpass, Qpqhost, Qpqport, Qpqtty;
162 static Lisp_Object Qpqoptions, Qpqstatus, Qpqerrormessage, Qpqbackendpid;
163
164 static Lisp_Object Qpgres_empty_query, Qpgres_command_ok, Qpgres_tuples_ok;
165 static Lisp_Object Qpgres_copy_out, Qpgres_copy_in, Qpgres_bad_response;
166 static Lisp_Object Qpgres_nonfatal_error, Qpgres_fatal_error;
167
168 static Lisp_Object Qpgres_polling_failed, Qpgres_polling_reading;
169 static Lisp_Object Qpgres_polling_writing, Qpgres_polling_ok;
170 static Lisp_Object Qpgres_polling_active;
171 /****/
172
173 /* PGconn is an opaque object and we need to be able to store them in
174    Lisp code because libpq supports multiple connections.
175 */
176 Lisp_Object Qpgconnp;
177
178 static Lisp_Object
179 make_pgconn (Lisp_PGconn *pgconn)
180 {
181   Lisp_Object lisp_pgconn;
182   XSETPGCONN (lisp_pgconn, pgconn);
183   return lisp_pgconn;
184 }
185
186 static Lisp_Object
187 #ifdef RUNNING_XEMACS_21_1
188 mark_pgconn (Lisp_Object obj, void (*markobj) (Lisp_Object))
189 #else
190 mark_pgconn (Lisp_Object obj)
191 #endif
192 {
193   return Qnil;
194 }
195
196 static void
197 print_pgconn (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
198 {
199   char buf[256];
200   PGconn *P;
201   ConnStatusType cst;
202   char *host="", *db="", *user="", *port="";
203
204   P = (XPGCONN (obj))->pgconn;
205
206   if (!P) /* this may happen since we allow PQfinish() to be called */
207     strcpy (buf, "#<PGconn DEAD>"); /* evil! */
208   else if ((cst = PQstatus (P)) == CONNECTION_OK)
209     {
210       if (!(host = PQhost (P)))
211         host = "";
212       port = PQport (P);
213       db = PQdb (P);
214       if (!(user = PQuser (P)))
215         user = "";
216       sprintf (buf, "#<PGconn %s:%s %s/%s>", /* evil! */
217               !strlen (host) ? "localhost" : host,
218               port,
219               user,
220               db);
221     }
222   else if (cst == CONNECTION_BAD)
223     strcpy (buf, "#<PGconn BAD>"); /* evil! */
224   else
225     strcpy (buf, "#<PGconn connecting>"); /* evil! */
226
227   if (print_readably)
228     error ("printing unreadable object %s", buf);
229   else
230     write_c_string (buf, printcharfun);
231 }
232
233 static Lisp_PGconn *
234 allocate_pgconn (void)
235 {
236 #ifdef RUNNING_XEMACS_21_1
237   Lisp_PGconn *pgconn = alloc_lcrecord_type (Lisp_PGconn,
238                                              lrecord_pgconn);
239 #else
240   Lisp_PGconn *pgconn = alloc_lcrecord_type (Lisp_PGconn,
241                                              &lrecord_pgconn);
242 #endif
243   pgconn->pgconn = (PGconn *)NULL;
244   return pgconn;
245 }
246
247 static void
248 finalize_pgconn (void *header, int for_disksave)
249 {
250   Lisp_PGconn *pgconn = (Lisp_PGconn *)header;
251
252   if (for_disksave)
253     signal_simple_error ("Can't dump an emacs containing PGconn objects",
254                          make_pgconn (pgconn));
255
256   if (pgconn->pgconn)
257     {
258       PQfinish (pgconn->pgconn);
259       pgconn->pgconn = (PGconn *)NULL;
260     }
261 }
262
263 #ifdef RUNNING_XEMACS_21_1
264 DEFINE_LRECORD_IMPLEMENTATION ("pgconn", pgconn,
265                                mark_pgconn, print_pgconn, finalize_pgconn,
266                                NULL, NULL,
267                                Lisp_PGconn);
268 #else
269 DEFINE_LRECORD_IMPLEMENTATION ("pgconn", pgconn,
270                                mark_pgconn, print_pgconn, finalize_pgconn,
271                                NULL, NULL,
272                                0,
273                                Lisp_PGconn);
274 #endif
275 /****/
276
277 /* PGresult is an opaque object and we need to be able to store them in
278    Lisp code.
279 */
280 Lisp_Object Qpgresultp;
281
282 static Lisp_Object
283 make_pgresult (Lisp_PGresult *pgresult)
284 {
285   Lisp_Object lisp_pgresult;
286   XSETPGRESULT (lisp_pgresult, pgresult);
287   return lisp_pgresult;
288 }
289
290 static Lisp_Object
291 #ifdef RUNNING_XEMACS_21_1
292 mark_pgresult (Lisp_Object obj, void (*markobj) (Lisp_Object))
293 #else
294 mark_pgresult (Lisp_Object obj)
295 #endif
296 {
297   return Qnil;
298 }
299
300 #define RESULT_TUPLES_FMT "#<PGresult %s[%d] - %s>"
301 #define RESULT_CMD_TUPLES_FMT "#<PGresult %s[%s] - %s>"
302 #define RESULT_DEFAULT_FMT "#<PGresult %s - %s>"
303 static void
304 print_pgresult (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
305 {
306   char buf[1024];
307   PGresult *res;
308
309   res = (XPGRESULT (obj))->pgresult;
310
311   if (res)
312     {
313       switch (PQresultStatus (res))
314         {
315         case PGRES_TUPLES_OK:
316           /* Add number of tuples of result to output */
317           sprintf (buf, RESULT_TUPLES_FMT, /* evil! */
318                    PQresStatus (PQresultStatus (res)),
319                    PQntuples (res),
320                    PQcmdStatus (res));
321           break;
322         case PGRES_COMMAND_OK:
323           /* Add number of tuples affected by output-less command */
324           if (!strlen (PQcmdTuples (res))) goto notuples;
325           sprintf (buf, RESULT_CMD_TUPLES_FMT, /* evil! */
326                    PQresStatus (PQresultStatus (res)),
327                    PQcmdTuples (res),
328                    PQcmdStatus (res));
329           break;
330         default:
331 notuples:
332           /* No counts to print */
333           sprintf (buf, RESULT_DEFAULT_FMT, /* evil! */
334                    PQresStatus (PQresultStatus (res)),
335                    PQcmdStatus (res));
336           break;
337         }
338     }
339   else
340     strcpy (buf, "#<PGresult DEAD>"); /* evil! */
341
342   if (print_readably)
343     error ("printing unreadable object %s", buf);
344   else
345     write_c_string (buf, printcharfun);
346 }
347
348 #undef RESULT_TUPLES_FMT
349 #undef RESULT_CMD_TUPLES_FMT
350 #undef RESULT_DEFAULT_FMT
351
352 static Lisp_PGresult *
353 allocate_pgresult (void)
354 {
355 #ifdef RUNNING_XEMACS_21_1
356   Lisp_PGresult *pgresult = alloc_lcrecord_type (Lisp_PGresult,
357                                                  lrecord_pgresult);
358 #else
359   Lisp_PGresult *pgresult = alloc_lcrecord_type (Lisp_PGresult,
360                                                  &lrecord_pgresult);
361 #endif
362   pgresult->pgresult = (PGresult *)NULL;
363   return pgresult;
364 }
365
366 static void
367 finalize_pgresult (void *header, int for_disksave)
368 {
369   Lisp_PGresult *pgresult = (Lisp_PGresult *)header;
370
371   if (for_disksave)
372     signal_simple_error ("Can't dump an emacs containing PGresult objects",
373                          make_pgresult (pgresult));
374
375   if (pgresult->pgresult)
376     {
377       PQclear (pgresult->pgresult);
378       pgresult->pgresult = (PGresult *)NULL;
379     }
380 }
381
382 #ifdef RUNNING_XEMACS_21_1
383 DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult,
384                                mark_pgresult, print_pgresult, finalize_pgresult,
385                                NULL, NULL,
386                                Lisp_PGresult);
387 #else
388 DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult,
389                                mark_pgresult, print_pgresult, finalize_pgresult,
390                                NULL, NULL,
391                                0,
392                                Lisp_PGresult);
393 #endif
394
395 /***********************/
396
397 /* notices */
398 static void
399 xemacs_notice_processor (void *arg, I_HATE_CONST char *msg)
400 {
401   warn_when_safe (Qpostgresql, Qnotice, "%s", msg);
402 }
403
404 /* There are four ways (as of PostgreSQL v7) to connect to a database.
405    Two of them, PQsetdb and PQsetdbLogin, are deprecated.  Both of those
406    routines take a number of positional parameters and are better done in Lisp.
407    Note that PQconnectStart does not exist prior to v7.
408 */
409
410 DEFUN ("pq-conn-defaults", Fpq_conn_defaults, 0, 0, 0, /*
411 Return a connection default structure.
412 */
413        ())
414 {
415   /* This function can GC */
416   PQconninfoOption *pcio;
417   Lisp_Object temp, temp1;
418   int i;
419
420   pcio = PQconndefaults();
421   if (!pcio) return Qnil; /* can never happen in libpq-7.0 */
422   temp = list1 (Fcons (build_ext_string (pcio[0].keyword, PG_OS_CODING),
423                        Fcons (build_ext_string (pcio[0].envvar, PG_OS_CODING),
424                               Fcons (build_ext_string (pcio[0].compiled, PG_OS_CODING),
425                                      Fcons (build_ext_string (pcio[0].val, PG_OS_CODING),
426                                             Fcons (build_ext_string (pcio[0].label, PG_OS_CODING),
427                                                    Fcons (build_ext_string (pcio[0].dispchar, PG_OS_CODING),
428                                                           Fcons (make_int (pcio[0].dispsize), Qnil))))))));
429
430   for (i = 1; pcio[i].keyword; i++)
431     {
432       temp1 = list1 (Fcons (build_ext_string (pcio[i].keyword, PG_OS_CODING),
433                             Fcons (build_ext_string (pcio[i].envvar, PG_OS_CODING),
434                                    Fcons (build_ext_string (pcio[i].compiled, PG_OS_CODING),
435                                           Fcons (build_ext_string (pcio[i].val, PG_OS_CODING),
436                                                  Fcons (build_ext_string (pcio[i].label, PG_OS_CODING),
437                                                         Fcons (build_ext_string (pcio[i].dispchar, PG_OS_CODING),
438                                                                Fcons (make_int (pcio[i].dispsize), Qnil))))))));
439       {
440         Lisp_Object args[2];
441         args[0] = temp;
442         args[1] = temp1;
443         /* Fappend GCPROs its arguments */
444         temp = Fappend (2, args);
445       }
446     }
447
448   return temp;
449 }
450
451 /* PQconnectdb Makes a new connection to a backend.
452 PGconn *PQconnectdb(const char *conninfo)
453 */
454
455 DEFUN ("pq-connectdb", Fpq_connectdb, 1, 1, 0, /*
456 Make a new connection to a PostgreSQL backend.
457 */
458         (conninfo))
459 {
460   PGconn *P;
461   Lisp_PGconn *lisp_pgconn;
462   char *error_message = "Out of Memory?";
463   char *c_conninfo;
464
465   CHECK_STRING (conninfo);
466
467   TO_EXTERNAL_FORMAT(LISP_STRING, conninfo,
468                      C_STRING_ALLOCA, c_conninfo, Qnative);
469   P = PQconnectdb (c_conninfo);
470   if (P && (PQstatus (P) == CONNECTION_OK))
471     {
472       (void)PQsetNoticeProcessor (P, xemacs_notice_processor, NULL);
473       lisp_pgconn = allocate_pgconn();
474       lisp_pgconn->pgconn = P;
475       return make_pgconn (lisp_pgconn);
476     }
477   else
478     {
479       /* Connection failed.  Destroy the connection and signal an error. */
480       char buf[BLCKSZ];
481       strcpy (buf, error_message);
482       if (P)
483         {
484           /* storage for the error message gets erased when call PQfinish */
485           /* so we must temporarily stash it somewhere */
486           strncpy (buf, PQerrorMessage (P), sizeof (buf));
487           buf[sizeof (buf) - 1] = '\0';
488           PQfinish (P);
489         }
490       error ("libpq: %s", buf);
491     }
492 }
493
494 /* PQconnectStart Makes a new asynchronous connection to a backend.
495 PGconn *PQconnectStart(const char *conninfo)
496 */
497
498 #ifdef HAVE_POSTGRESQLV7
499 DEFUN ("pq-connect-start", Fpq_connect_start, 1, 1, 0, /*
500 Make a new asynchronous connection to a PostgreSQL backend.
501 */
502         (conninfo))
503 {
504   PGconn *P;
505   Lisp_PGconn *lisp_pgconn;
506   char *error_message = "Out of Memory?";
507   char *c_conninfo;
508
509   CHECK_STRING (conninfo);
510   TO_EXTERNAL_FORMAT (LISP_STRING, conninfo,
511                       C_STRING_ALLOCA, c_conninfo, Qnative);
512   P = PQconnectStart (c_conninfo);
513
514   if (P && (PQstatus (P) != CONNECTION_BAD))
515     {
516       (void)PQsetNoticeProcessor (P, xemacs_notice_processor, NULL);
517       lisp_pgconn = allocate_pgconn();
518       lisp_pgconn->pgconn = P;
519
520       return make_pgconn (lisp_pgconn);
521     }
522   else
523     {
524       /* capture the error message before destroying the object */
525       char buf[BLCKSZ];
526       strcpy (buf, error_message);
527       if (P)
528         {
529           strncpy (buf, PQerrorMessage (P), sizeof (buf));
530           buf[sizeof (buf) - 1] = '\0';
531           PQfinish (P);
532         }
533       error ("libpq: %s", buf);
534     }
535 }
536
537 DEFUN ("pq-connect-poll", Fpq_connect_poll, 1, 1, 0, /*
538 Poll an asynchronous connection for completion
539 */
540         (conn))
541 {
542   PGconn *P;
543   PostgresPollingStatusType PS;
544
545   CHECK_PGCONN (conn);
546
547   P = (XPGCONN (conn))->pgconn;
548   CHECK_LIVE_CONNECTION (P);
549
550   PS = PQconnectPoll (P);
551   switch (PS)
552     {
553     case PGRES_POLLING_FAILED:
554       /* Something Bad has happened */
555       {
556         char *e = PQerrorMessage (P);
557         error ("libpq: %s", e);
558       }
559     case PGRES_POLLING_OK:
560       return Qpgres_polling_ok;
561     case PGRES_POLLING_READING:
562       return Qpgres_polling_reading;
563     case PGRES_POLLING_WRITING:
564       return Qpgres_polling_writing;
565     case PGRES_POLLING_ACTIVE:
566       return Qpgres_polling_active;
567     default:
568       /* they've added a new field we don't know about */
569       error ("Help!  Unknown status code %08x from backend!", PS);
570     }
571 }
572
573 #ifdef MULE
574 DEFUN ("pq-client-encoding", Fpq_client_encoding, 1, 1, 0, /*
575 Return client coding system.
576 */
577        (conn))
578 {
579   PGconn *P;
580
581   CHECK_PGCONN (conn);
582   P = (XPGCONN (conn))->pgconn;
583   CHECK_LIVE_CONNECTION (P);
584
585   return make_int (PQclientEncoding (P));
586 }
587
588 DEFUN ("pq-set-client-encoding", Fpq_set_client_encoding, 2, 2, 0, /*
589 Set client coding system.
590 */
591        (conn, encoding))
592 {
593   PGconn *P;
594   int rc;
595   char *c_encoding;
596
597   CHECK_PGCONN (conn);
598   CHECK_STRING (encoding);
599
600   P = (XPGCONN (conn))->pgconn;
601   CHECK_LIVE_CONNECTION (P);
602
603   TO_EXTERNAL_FORMAT (LISP_STRING, encoding,
604                       C_STRING_ALLOCA, c_encoding, Qnative);
605
606   if ((rc = PQsetClientEncoding (P, c_encoding)) < 0)
607     error ("bad encoding");
608   else
609     return make_int (rc);
610 }
611
612 #endif
613 #endif /* HAVE_POSTGRESQLV7 */
614
615 /* PQfinish Close the connection to the backend. Also frees memory
616        used by the PGconn object.
617 void PQfinish(PGconn *conn)
618 */
619 DEFUN ("pq-finish", Fpq_finish, 1, 1, 0, /*
620 Close the connection to the backend.
621 */
622         (conn))
623 {
624   PGconn *P;
625
626   CHECK_PGCONN (conn);
627   P = (XPGCONN (conn))->pgconn;
628   PUKE_IF_NULL (P);
629
630   PQfinish (P);
631   /* #### PQfinish deallocates the PGconn structure, so we now have a
632      dangling pointer. */
633   /* Genocided all @'s ... */
634   (XPGCONN (conn))->pgconn = (PGconn *)NULL; /* You feel DEAD inside */
635   return Qnil;
636 }
637
638 DEFUN ("pq-clear", Fpq_clear, 1, 1, 0, /*
639 Forcibly erase a PGresult object.
640 */
641        (res))
642 {
643   PGresult *R;
644
645   CHECK_PGRESULT (res);
646   R = (XPGRESULT (res))->pgresult;
647   PUKE_IF_NULL (R);
648
649   PQclear (R);
650   /* Genocided all @'s ... */
651   (XPGRESULT (res))->pgresult = (PGresult *)NULL; /* You feel DEAD inside */
652
653   return Qnil;
654 }
655
656 DEFUN ("pq-is-busy", Fpq_is_busy, 1, 1, 0, /*
657 Return t if PQgetResult would block waiting for input.
658 */
659         (conn))
660 {
661   PGconn *P;
662
663   CHECK_PGCONN (conn);
664   P = (XPGCONN (conn))->pgconn;
665   CHECK_LIVE_CONNECTION (P);
666
667   return PQisBusy (P) ? Qt : Qnil;
668 }
669
670 DEFUN ("pq-consume-input", Fpq_consume_input, 1, 1, 0, /*
671 Consume any available input from the backend.
672 Returns nil if something bad happened.
673 */
674         (conn))
675 {
676   PGconn *P;
677
678   CHECK_PGCONN (conn);
679   P = (XPGCONN (conn))->pgconn;
680   CHECK_LIVE_CONNECTION (P);
681
682   return PQconsumeInput (P) ? Qt : Qnil;
683 }
684
685 /* PQreset Reset the communication port with the backend.
686 void PQreset(PGconn *conn)
687 */
688 DEFUN ("pq-reset", Fpq_reset, 1, 1, 0, /*
689 Reset the connection to the backend.
690 This function will close the connection to the backend and attempt to
691 reestablish a new connection to the same postmaster, using all the same
692 parameters previously used.  This may be useful for error recovery if a
693 working connection is lost.
694 */
695         (conn))
696 {
697   PGconn *P;
698
699   CHECK_PGCONN (conn);
700   P = (XPGCONN (conn))->pgconn;
701   PUKE_IF_NULL (P);/* we can resurrect a BAD connection, but not a dead one. */
702
703   PQreset (P);
704
705   return Qnil;
706 }
707
708 #ifdef HAVE_POSTGRESQLV7
709 DEFUN ("pq-reset-start", Fpq_reset_start, 1, 1, 0, /*
710 Reset connection to the backend asynchronously.
711 */
712        (conn))
713 {
714   PGconn *P;
715
716   CHECK_PGCONN (conn);
717   P = (XPGCONN (conn))->pgconn;
718   CHECK_LIVE_CONNECTION (P);
719
720   if (PQresetStart (P)) return Qt;
721   {
722     char *e = PQerrorMessage (P);
723     error ("libpq: %s", e);
724   }
725 }
726
727 DEFUN ("pq-reset-poll", Fpq_reset_poll, 1, 1, 0, /*
728 Poll an asynchronous reset for completion
729 */
730         (conn))
731 {
732   PGconn *P;
733   PostgresPollingStatusType PS;
734
735   CHECK_PGCONN (conn);
736
737   P = (XPGCONN (conn))->pgconn;
738   CHECK_LIVE_CONNECTION (P);
739
740   PS = PQresetPoll (P);
741   switch (PS)
742     {
743     case PGRES_POLLING_FAILED:
744       /* Something Bad has happened */
745       {
746         char *e = PQerrorMessage (P);
747         error ("libpq: %s", e);
748       }
749     case PGRES_POLLING_OK:
750       return Qpgres_polling_ok;
751     case PGRES_POLLING_READING:
752       return Qpgres_polling_reading;
753     case PGRES_POLLING_WRITING:
754       return Qpgres_polling_writing;
755     case PGRES_POLLING_ACTIVE:
756       return Qpgres_polling_active;
757     default:
758       /* they've added a new field we don't know about */
759       error ("Help!  Unknown status code %08x from backend!", PS);
760     }
761 }
762 #endif
763
764 DEFUN ("pq-request-cancel", Fpq_request_cancel, 1, 1, 0, /*
765 Attempt to request cancellation of the current operation.
766
767 The return value is t if the cancel request was successfully
768 dispatched, nil if not (in which case conn->errorMessage is set).
769 Note: successful dispatch is no guarantee that there will be any effect at
770 the backend.  The application must read the operation result as usual.
771 */
772        (conn))
773 {
774   PGconn *P;
775
776   CHECK_PGCONN (conn);
777   P = (XPGCONN (conn))->pgconn;
778   CHECK_LIVE_CONNECTION (P);
779
780   return PQrequestCancel (P) ? Qt : Qnil;
781 }
782
783 /* accessor function for the PGconn object */
784 DEFUN ("pq-pgconn", Fpq_pgconn, 2, 2, 0, /*
785 Accessor function for the PGconn object.
786 Currently recognized symbols for the field:
787 pq::db            Database name
788 pq::user          Database user name
789 pq::pass          Database user's password
790 pq::host          Hostname of PostgreSQL backend connected to
791 pq::port          TCP port number of connection
792 pq::tty           Debugging TTY (not used in Emacs)
793 pq::options       Additional backend options
794 pq::status        Connection status (either OK or BAD)
795 pq::error-message Last error message from the backend
796 pq::backend-pid   Process ID of backend process
797 */
798         (conn, field))
799 {
800   PGconn *P;
801
802   CHECK_PGCONN (conn);
803   P = (XPGCONN (conn))->pgconn;
804   PUKE_IF_NULL (P); /* BAD connections still have state to query */
805
806   if (EQ(field, Qpqdb))
807     /* PQdb Returns the database name of the connection.
808        char *PQdb(PGconn *conn)
809      */
810     return build_ext_string (PQdb(P), PG_OS_CODING);
811   else if (EQ (field, Qpquser))
812     /* PQuser Returns the user name of the connection.
813        char *PQuser(PGconn *conn)
814      */
815     return build_ext_string (PQuser(P), PG_OS_CODING);
816   else if (EQ (field, Qpqpass))
817     /* PQpass Returns the password of the connection.
818        char *PQpass(PGconn *conn)
819      */
820     return build_ext_string (PQpass(P), PG_OS_CODING);
821   else if (EQ (field, Qpqhost))
822     /* PQhost Returns the server host name of the connection.
823        char *PQhost(PGconn *conn)
824      */
825     return build_ext_string (PQhost(P), PG_OS_CODING);
826   else if (EQ (field, Qpqport))
827     {
828       char *p;
829       /* PQport Returns the port of the connection.
830          char *PQport(PGconn *conn)
831        */
832       if ((p = PQport(P)))
833         return make_int(atoi(p));
834       else
835         return make_int(-1);
836     }
837   else if (EQ (field, Qpqtty))
838     /* PQtty Returns the debug tty of the connection.
839        char *PQtty(PGconn *conn)
840      */
841     return build_ext_string (PQtty(P), PG_OS_CODING);
842   else if (EQ (field, Qpqoptions))
843   /* PQoptions Returns the backend options used in the connection.
844      char *PQoptions(PGconn *conn)
845    */
846     return build_ext_string (PQoptions(P), PG_OS_CODING);
847   else if (EQ (field, Qpqstatus))
848     {
849       ExecStatusType est;
850       /* PQstatus Returns the status of the connection. The status can be
851          CONNECTION_OK or CONNECTION_BAD.
852          ConnStatusType PQstatus(PGconn *conn)
853       */
854       switch ((est = PQstatus (P)))
855         {
856         case CONNECTION_OK: return Qpg_connection_ok;
857         case CONNECTION_BAD: return Qpg_connection_bad;
858 #ifdef HAVE_POSTGRESQLV7
859         case CONNECTION_STARTED: return Qpg_connection_started;
860         case CONNECTION_MADE: return Qpg_connection_made;
861         case CONNECTION_AWAITING_RESPONSE: return Qpg_connection_awaiting_response;
862         case CONNECTION_AUTH_OK: return Qpg_connection_auth_ok;
863         case CONNECTION_SETENV: return Qpg_connection_setenv;
864 #endif /* HAVE_POSTGRESQLV7 */
865         default:
866           /* they've added a new field we don't know about */
867           error ("Help!  Unknown exec status code %08x from backend!", est);
868         }
869     }
870   else if (EQ (field, Qpqerrormessage))
871     /* PQerrorMessage Returns the error message most recently generated
872        by an operation on the connection.
873        char *PQerrorMessage(PGconn* conn);
874      */
875     return build_ext_string (PQerrorMessage(P), PG_OS_CODING);
876   else if (EQ (field, Qpqbackendpid))
877     /* PQbackendPID Returns the process ID of the backend server handling
878        this connection.
879        int PQbackendPID(PGconn *conn);
880      */
881     return make_int (PQbackendPID(P));
882   else
883     error ("bad PGconn accessor");
884 }
885
886 /* Query functions */
887 DEFUN ("pq-exec", Fpq_exec, 2, 2, 0, /*
888 Submit a query to Postgres and wait for the result.
889 */
890         (conn, query))
891 {
892   PGconn *P;
893   Lisp_PGresult *lisp_pgresult;
894   PGresult *R;
895   char *c_query;
896
897   CHECK_PGCONN (conn);
898   CHECK_STRING (query);
899
900   P = (XPGCONN (conn))->pgconn;
901   CHECK_LIVE_CONNECTION (P);
902
903   TO_EXTERNAL_FORMAT (LISP_STRING, query,
904                       C_STRING_ALLOCA, c_query, Qnative);
905
906   R = PQexec (P, c_query);
907   {
908     char *tag, buf[BLCKSZ];
909
910     if (!R) error ("query: out of memory");
911     else
912       switch (PQresultStatus (R))
913         {
914         case PGRES_BAD_RESPONSE:
915           tag = "bad response [%s]";
916           goto err;
917         case PGRES_NONFATAL_ERROR:
918           tag = "non-fatal error [%s]";
919           goto err;
920         case PGRES_FATAL_ERROR:
921           tag = "fatal error [%s]";
922 err:
923           strncpy (buf, PQresultErrorMessage (R), sizeof (buf));
924           buf [sizeof (buf) - 1] = '\0';
925           PQclear (R);
926           error (tag, buf);
927           /*NOTREACHED*/
928         default:
929           break;
930         }
931   }
932
933   lisp_pgresult = allocate_pgresult ();
934   lisp_pgresult->pgresult = R;
935
936   return make_pgresult (lisp_pgresult);
937 }
938
939 DEFUN ("pq-send-query", Fpq_send_query, 2, 2, 0, /*
940 Submit a query to Postgres and don't wait for the result.
941 Returns: t if successfully submitted
942          nil if error (conn->errorMessage is set)
943 */
944         (conn, query))
945 {
946   PGconn *P;
947   char *c_query;
948
949   CHECK_PGCONN (conn);
950   CHECK_STRING (query);
951
952   P = (XPGCONN (conn))->pgconn;
953   CHECK_LIVE_CONNECTION (P);
954
955   TO_EXTERNAL_FORMAT (LISP_STRING, query,
956                       C_STRING_ALLOCA, c_query, Qnative);
957
958   if (PQsendQuery (P, c_query)) return Qt;
959   else error ("async query: %s", PQerrorMessage (P));
960 }
961
962 DEFUN ("pq-get-result", Fpq_get_result, 1, 1, 0, /*
963 Retrieve an asynchronous result from a query.
964 NIL is returned when no more query work remains.
965 */
966         (conn))
967 {
968   PGconn *P;
969   Lisp_PGresult *lisp_pgresult;
970   PGresult *R;
971
972   CHECK_PGCONN (conn);
973
974   P = (XPGCONN (conn))->pgconn;
975   CHECK_LIVE_CONNECTION (P);
976
977   R = PQgetResult (P);
978   if (!R) return Qnil; /* not an error, there's no more data to get */
979
980   {
981     char *tag, buf[BLCKSZ];
982
983     switch (PQresultStatus (R))
984       {
985       case PGRES_BAD_RESPONSE:
986         tag = "bad response [%s]";
987         goto err;
988       case PGRES_NONFATAL_ERROR:
989         tag = "non-fatal error [%s]";
990         goto err;
991       case PGRES_FATAL_ERROR:
992         tag = "fatal error [%s]";
993 err:
994         strncpy (buf, PQresultErrorMessage (R), sizeof (buf));
995         buf[sizeof (buf) - 1] = '\0';
996         PQclear (R);
997         error (tag, buf);
998         /*NOTREACHED*/
999       default:
1000         break;
1001       }
1002   }
1003
1004   lisp_pgresult = allocate_pgresult();
1005   lisp_pgresult->pgresult = R;
1006
1007   return make_pgresult (lisp_pgresult);
1008 }
1009
1010 DEFUN ("pq-result-status", Fpq_result_status, 1, 1, 0, /*
1011 Return result status of the query.
1012 */
1013         (result))
1014 {
1015   PGresult *R;
1016   ExecStatusType est;
1017
1018   CHECK_PGRESULT (result);
1019   R = (XPGRESULT (result))->pgresult;
1020   PUKE_IF_NULL (R);
1021
1022   switch ((est = PQresultStatus (R))) {
1023   case PGRES_EMPTY_QUERY: return Qpgres_empty_query;
1024   case PGRES_COMMAND_OK: return Qpgres_command_ok;
1025   case PGRES_TUPLES_OK: return Qpgres_tuples_ok;
1026   case PGRES_COPY_OUT: return Qpgres_copy_out;
1027   case PGRES_COPY_IN: return Qpgres_copy_in;
1028   case PGRES_BAD_RESPONSE: return Qpgres_bad_response;
1029   case PGRES_NONFATAL_ERROR: return Qpgres_nonfatal_error;
1030   case PGRES_FATAL_ERROR: return Qpgres_fatal_error;
1031   default:
1032     /* they've added a new field we don't know about */
1033     error ("Help!  Unknown exec status code %08x from backend!", est);
1034   }
1035 }
1036
1037 DEFUN ("pq-res-status", Fpq_res_status, 1, 1, 0, /*
1038 Return stringified result status of the query.
1039 */
1040         (result))
1041 {
1042   PGresult *R;
1043
1044   CHECK_PGRESULT (result);
1045   R = (XPGRESULT (result))->pgresult;
1046   PUKE_IF_NULL (R);
1047
1048   return build_ext_string (PQresStatus (PQresultStatus (R)), PG_OS_CODING);
1049 }
1050
1051 /* Sundry PGresult accessor functions */
1052 DEFUN ("pq-result-error-message", Fpq_result_error_message, 1, 1, 0, /*
1053 Return last message associated with the query.
1054 */
1055         (result))
1056 {
1057   PGresult *R;
1058
1059   CHECK_PGRESULT (result);
1060   R = (XPGRESULT (result))->pgresult;
1061   PUKE_IF_NULL (R);
1062
1063   return build_ext_string (PQresultErrorMessage (R), PG_OS_CODING);
1064 }
1065
1066 DEFUN ("pq-ntuples", Fpq_ntuples, 1, 1, 0, /*
1067 Return the number of tuples (instances) in the query result.
1068 */
1069         (result))
1070 {
1071   PGresult *R;
1072
1073   CHECK_PGRESULT (result);
1074   R = (XPGRESULT (result))->pgresult;
1075   PUKE_IF_NULL (R);
1076
1077   return make_int (PQntuples (R));
1078 }
1079
1080 DEFUN ("pq-nfields", Fpq_nfields, 1, 1, 0, /*
1081 Return the number of fields (attributes) in each tuple of the query result.
1082 */
1083         (result))
1084 {
1085   PGresult *R;
1086
1087   CHECK_PGRESULT (result);
1088   R = (XPGRESULT (result))->pgresult;
1089   PUKE_IF_NULL (R);
1090
1091   return make_int (PQnfields (R));
1092 }
1093
1094 DEFUN ("pq-binary-tuples", Fpq_binary_tuples, 1, 1, 0, /*
1095 Return t if the query result contains binary data, nil otherwise.
1096 */
1097         (result))
1098 {
1099   PGresult *R;
1100
1101   CHECK_PGRESULT (result);
1102   R = (XPGRESULT (result))->pgresult;
1103   PUKE_IF_NULL (R);
1104
1105   return (PQbinaryTuples (R)) ? Qt : Qnil;
1106 }
1107
1108 DEFUN ("pq-fname", Fpq_fname, 2, 2, 0, /*
1109 Return the field (attribute) name associated with the given field index.
1110 Field indices start at 0.
1111 */
1112         (result, field_index))
1113 {
1114   PGresult *R;
1115
1116   CHECK_PGRESULT (result);
1117   CHECK_INT (field_index);
1118   R = (XPGRESULT (result))->pgresult;
1119   PUKE_IF_NULL (R);
1120
1121   return build_ext_string (PQfname (R, XINT (field_index)), PG_OS_CODING);
1122 }
1123
1124 DEFUN ("pq-fnumber", Fpq_fnumber, 2, 2, 0, /*
1125 Return the number of fields (attributes) in each tuple of the query result.
1126 */
1127         (result, field_name))
1128 {
1129   PGresult *R;
1130   char *c_field_name;
1131
1132   CHECK_PGRESULT (result);
1133   CHECK_STRING (field_name);
1134   R = (XPGRESULT (result))->pgresult;
1135   PUKE_IF_NULL (R);
1136
1137   TO_EXTERNAL_FORMAT (LISP_STRING, field_name,
1138                       C_STRING_ALLOCA, c_field_name, Qnative);
1139
1140   return make_int (PQfnumber (R, c_field_name));
1141 }
1142
1143 DEFUN ("pq-ftype", Fpq_ftype, 2, 2, 0, /*
1144 Return the field type associated with the given field index.
1145 The integer returned is the internal coding of the type.  Field indices
1146 start at 0.
1147 */
1148         (result, field_num))
1149 {
1150   PGresult *R;
1151
1152   CHECK_PGRESULT (result);
1153   CHECK_INT (field_num);
1154   R = (XPGRESULT (result))->pgresult;
1155   PUKE_IF_NULL (R);
1156
1157   return make_int (PQftype (R, XINT (field_num)));
1158 }
1159
1160 DEFUN ("pq-fsize", Fpq_fsize, 2, 2, 0, /*
1161 Return the field size in bytes associated with the given field index.
1162 Field indices start at 0.
1163 */
1164         (result, field_index))
1165 {
1166   PGresult *R;
1167
1168   CHECK_PGRESULT (result);
1169   CHECK_INT (field_index);
1170   R = (XPGRESULT (result))->pgresult;
1171   PUKE_IF_NULL (R);
1172
1173   return make_int (PQftype (R, XINT (field_index)));
1174 }
1175
1176 DEFUN ("pq-fmod", Fpq_fmod, 2, 2, 0, /*
1177 Return the type modifier associated with a field.
1178 Field indices start at 0.
1179 */
1180         (result, field_index))
1181 {
1182   PGresult *R;
1183
1184   CHECK_PGRESULT (result);
1185   CHECK_INT (field_index);
1186   R = (XPGRESULT (result))->pgresult;
1187   PUKE_IF_NULL (R);
1188
1189   return make_int (PQfmod (R, XINT (field_index)));
1190 }
1191
1192 DEFUN ("pq-get-value", Fpq_get_value, 3, 3, 0, /*
1193 Return a single field (attribute) value of one tuple of a PGresult.
1194 Tuple and field indices start at 0.
1195 */
1196         (result, tup_num, field_num))
1197 {
1198   PGresult *R;
1199
1200   CHECK_PGRESULT (result);
1201   CHECK_INT (tup_num);
1202   CHECK_INT (field_num);
1203   R = (XPGRESULT (result))->pgresult;
1204   PUKE_IF_NULL (R);
1205
1206   return build_ext_string (PQgetvalue (R, XINT (tup_num), XINT (field_num)),
1207                            PG_OS_CODING);
1208 }
1209
1210 DEFUN ("pq-get-length", Fpq_get_length, 3, 3, 0, /*
1211 Returns the length of a field value in bytes.
1212 If result is binary, i.e. a result of a binary portal, then the
1213 length returned does NOT include the size field of the varlena.  (The
1214 data returned by PQgetvalue doesn't either.)
1215 */
1216         (result, tup_num, field_num))
1217 {
1218   PGresult *R;
1219
1220   CHECK_PGRESULT (result);
1221   CHECK_INT (tup_num);
1222   CHECK_INT (field_num);
1223   R = (XPGRESULT (result))->pgresult;
1224   PUKE_IF_NULL (R);
1225
1226   return make_int (PQgetlength (R, XINT (tup_num), XINT (field_num)));
1227 }
1228
1229 DEFUN ("pq-get-is-null", Fpq_get_is_null, 3, 3, 0, /*
1230 Returns the null status of a field value.
1231 */
1232         (result, tup_num, field_num))
1233 {
1234   PGresult *R;
1235
1236   CHECK_PGRESULT (result);
1237   CHECK_INT (tup_num);
1238   CHECK_INT (field_num);
1239   R = (XPGRESULT (result))->pgresult;
1240   PUKE_IF_NULL (R);
1241
1242   return PQgetisnull (R, XINT (tup_num), XINT (field_num)) ? Qt : Qnil;
1243 }
1244
1245 DEFUN ("pq-cmd-status", Fpq_cmd_status, 1, 1, 0, /*
1246 Returns the command status string from the SQL command that generated the result.
1247 */
1248         (result))
1249 {
1250   PGresult *R;
1251
1252   CHECK_PGRESULT (result);
1253   R = (XPGRESULT (result))->pgresult;
1254   PUKE_IF_NULL (R);
1255
1256   return build_ext_string (PQcmdStatus (R), PG_OS_CODING);
1257 }
1258
1259 DEFUN ("pq-cmd-tuples", Fpq_cmd_tuples, 1, 1, 0, /*
1260 Returns the number of rows affected by the SQL command
1261 */
1262         (result))
1263 {
1264   PGresult *R;
1265
1266   CHECK_PGRESULT (result);
1267   R = (XPGRESULT (result))->pgresult;
1268   PUKE_IF_NULL (R);
1269
1270   return build_ext_string (PQcmdTuples (R), PG_OS_CODING);
1271 }
1272
1273 DEFUN ("pq-oid-value", Fpq_oid_value, 1, 1, 0, /*
1274 Returns the object id of the tuple inserted.
1275 */
1276         (result))
1277 {
1278   PGresult *R;
1279
1280   CHECK_PGRESULT (result);
1281   R = (XPGRESULT (result))->pgresult;
1282   PUKE_IF_NULL (R);
1283
1284 #ifdef HAVE_POSTGRESQLV7
1285   return make_int (PQoidValue (R));
1286 #else
1287   /* Use the old interface */
1288   return make_int (atoi (PQoidStatus (R)));
1289 #endif
1290 }
1291
1292 #ifdef HAVE_POSTGRESQLV7
1293 DEFUN ("pq-set-nonblocking", Fpq_set_nonblocking, 2, 2, 0, /*
1294 Sets the PGconn's database connection non-blocking if the arg is TRUE
1295 or makes it non-blocking if the arg is FALSE, this will not protect
1296 you from PQexec(), you'll only be safe when using the non-blocking API.
1297
1298 Needs to be called only on a connected database connection.
1299 */
1300        (conn, arg))
1301 {
1302   PGconn *P;
1303
1304   CHECK_PGCONN (conn);
1305   P = (XPGCONN (conn))->pgconn;
1306   CHECK_LIVE_CONNECTION (P);
1307
1308   return make_int (PQsetnonblocking (P, !NILP (arg)));
1309 }
1310
1311 DEFUN ("pq-is-nonblocking", Fpq_is_nonblocking, 1, 1, 0, /*
1312 Return the blocking status of the database connection
1313 */
1314        (conn))
1315 {
1316   PGconn *P;
1317
1318   CHECK_PGCONN (conn);
1319   P = (XPGCONN (conn))->pgconn;
1320   CHECK_LIVE_CONNECTION (P);
1321
1322   return PQisnonblocking (P) ? Qt : Qnil;
1323 }
1324
1325 DEFUN ("pq-flush", Fpq_flush, 1, 1, 0, /*
1326 Force the write buffer to be written (or at least try)
1327 */
1328        (conn))
1329 {
1330   PGconn *P;
1331
1332   CHECK_PGCONN (conn);
1333   P = (XPGCONN (conn))->pgconn;
1334   CHECK_LIVE_CONNECTION (P);
1335
1336   return make_int (PQflush (P));
1337 }
1338 #endif
1339
1340 DEFUN ("pq-notifies", Fpq_notifies, 1, 1, 0, /*
1341 Return the latest async notification that has not yet been handled.
1342 If there has been a notification, then a list of two elements will be returned.
1343 The first element contains the relation name being notified, the second
1344 element contains the backend process ID number.  nil is returned if there
1345 aren't any notifications to process.
1346 */
1347        (conn))
1348 {
1349   /* This function cannot GC */
1350   PGconn *P;
1351   PGnotify *PGN;
1352
1353   CHECK_PGCONN (conn);
1354   P = (XPGCONN (conn))->pgconn;
1355   CHECK_LIVE_CONNECTION (P);
1356
1357   PGN = PQnotifies (P);
1358   if (!PGN)
1359     return Qnil;
1360   else
1361   {
1362     Lisp_Object temp;
1363
1364     temp = list2 (build_ext_string (PGN->relname, PG_OS_CODING), make_int (PGN->be_pid));
1365     free ((void *)PGN);
1366     return temp;
1367   }
1368 }
1369
1370 #if defined (HAVE_POSTGRESQLV7) && defined(MULE)
1371 DEFUN ("pq-env-2-encoding", Fpq_env_2_encoding, 0, 0, 0, /*
1372 Get encoding id from environment variable PGCLIENTENCODING.
1373 */
1374        ())
1375 {
1376   return make_int (PQenv2encoding ());
1377 }
1378 #endif /* MULE */
1379
1380 DEFUN ("pq-lo-import", Fpq_lo_import, 2, 2, 0, /*
1381 */
1382        (conn, filename))
1383 {
1384   PGconn *P;
1385   char *c_filename;
1386
1387   CHECK_PGCONN (conn);
1388   CHECK_STRING (filename);
1389
1390   P = (XPGCONN (conn))->pgconn;
1391   CHECK_LIVE_CONNECTION (P);
1392
1393   TO_EXTERNAL_FORMAT (LISP_STRING, filename,
1394                       C_STRING_ALLOCA, c_filename,
1395                       Qfile_name);
1396
1397   return make_int ((int)lo_import (P, c_filename));
1398 }
1399
1400 DEFUN ("pq-lo-export", Fpq_lo_export, 3, 3, 0, /*
1401 */
1402        (conn, oid, filename))
1403 {
1404   PGconn *P;
1405   char *c_filename;
1406
1407   CHECK_PGCONN (conn);
1408   CHECK_INT (oid);
1409   CHECK_STRING (filename);
1410
1411   P = (XPGCONN (conn))->pgconn;
1412   CHECK_LIVE_CONNECTION (P);
1413
1414   TO_EXTERNAL_FORMAT (LISP_STRING, filename,
1415                       C_STRING_ALLOCA, c_filename, Qfile_name);
1416
1417   return make_int ((int)lo_export (P, XINT (oid), c_filename));
1418 }
1419
1420 DEFUN ("pq-make-empty-pgresult", Fpq_make_empty_pgresult, 2, 2, 0, /*
1421 Make an empty PGresult object with the given status.
1422 */
1423        (conn, status))
1424 {
1425   PGconn *P;
1426   Lisp_PGresult *lpgr;
1427   PGresult *R;
1428   ExecStatusType est;
1429
1430   CHECK_PGCONN (conn);
1431   P = (XPGCONN (conn))->pgconn;
1432   CHECK_LIVE_CONNECTION (P); /* needed here? */
1433
1434   if (EQ (status, Qpgres_empty_query)) est = PGRES_EMPTY_QUERY;
1435   else if (EQ (status, Qpgres_command_ok)) est = PGRES_COMMAND_OK;
1436   else if (EQ (status, Qpgres_tuples_ok)) est = PGRES_TUPLES_OK;
1437   else if (EQ (status, Qpgres_copy_out)) est = PGRES_COPY_OUT;
1438   else if (EQ (status, Qpgres_copy_in)) est = PGRES_COPY_IN;
1439   else if (EQ (status, Qpgres_bad_response)) est = PGRES_BAD_RESPONSE;
1440   else if (EQ (status, Qpgres_nonfatal_error)) est = PGRES_NONFATAL_ERROR;
1441   else if (EQ (status, Qpgres_fatal_error)) est = PGRES_FATAL_ERROR;
1442   else signal_simple_error ("bad status symbol", status);
1443
1444   R = PQmakeEmptyPGresult (P, est);
1445   if (!R) error ("out of memory?");
1446
1447   lpgr = allocate_pgresult ();
1448   lpgr->pgresult = R;
1449
1450   return make_pgresult (lpgr);
1451 }
1452
1453 DEFUN ("pq-get-line", Fpq_get_line, 1, 1, 0, /*
1454 Retrieve a line from server in copy in operation.
1455 The return value is a dotted pair where the cons cell is an integer code:
1456    -1: Copying is complete
1457     0: A record is complete
1458     1: A record is incomplete, it will be continued in the next `pq-get-line'
1459        operation.
1460 and the cdr cell is returned string data.
1461
1462 The copy operation is complete when the value `\.' (backslash dot) is
1463 returned.
1464 */
1465        (conn))
1466 {
1467   char buffer[BLCKSZ]; /* size of a Postgres disk block */
1468   PGconn *P;
1469   int ret;
1470
1471   CHECK_PGCONN (conn);
1472   P = (XPGCONN (conn))->pgconn;
1473   CHECK_LIVE_CONNECTION (P);
1474
1475   ret = PQgetline (P, buffer, sizeof (buffer));
1476
1477   return Fcons (make_int (ret), build_ext_string (buffer, PG_OS_CODING));
1478 }
1479
1480 DEFUN ("pq-put-line", Fpq_put_line, 2, 2, 0, /*
1481 Send a line to the server in copy out operation.
1482
1483 Returns t if the operation succeeded, nil otherwise.
1484 */
1485        (conn, string))
1486 {
1487   PGconn *P;
1488   char *c_string;
1489
1490   CHECK_PGCONN (conn);
1491   CHECK_STRING (string);
1492
1493   P = (XPGCONN (conn))->pgconn;
1494   CHECK_LIVE_CONNECTION (P);
1495   TO_EXTERNAL_FORMAT (LISP_STRING, string,
1496                       C_STRING_ALLOCA, c_string, Qnative);
1497
1498   return !PQputline (P, c_string) ? Qt : Qnil;
1499 }
1500
1501 DEFUN ("pq-get-line-async", Fpq_get_line_async, 1, 1, 0, /*
1502 Get a line from the server in copy in operation asynchronously.
1503
1504 This routine is for applications that want to do "COPY <rel> to stdout"
1505 asynchronously, that is without blocking.  Having issued the COPY command
1506 and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput
1507 and this routine until the end-of-data signal is detected.  Unlike
1508 PQgetline, this routine takes responsibility for detecting end-of-data.
1509
1510 On each call, PQgetlineAsync will return data if a complete newline-
1511 terminated data line is available in libpq's input buffer, or if the
1512 incoming data line is too long to fit in the buffer offered by the caller.
1513 Otherwise, no data is returned until the rest of the line arrives.
1514
1515 If -1 is returned, the end-of-data signal has been recognized (and removed
1516 from libpq's input buffer).  The caller *must* next call PQendcopy and
1517 then return to normal processing.
1518
1519 RETURNS:
1520       -1    if the end-of-copy-data marker has been recognized
1521       0         if no data is available
1522       >0    the number of bytes returned.
1523 The data returned will not extend beyond a newline character.  If possible
1524 a whole line will be returned at one time.  But if the buffer offered by
1525 the caller is too small to hold a line sent by the backend, then a partial
1526 data line will be returned.  This can be detected by testing whether the
1527 last returned byte is '\n' or not.
1528 The returned string is *not* null-terminated.
1529 */
1530        (conn))
1531 {
1532   PGconn *P;
1533   char buffer[BLCKSZ];
1534   int ret;
1535
1536   CHECK_PGCONN (conn);
1537
1538   P = (XPGCONN (conn))->pgconn;
1539   CHECK_LIVE_CONNECTION (P);
1540
1541   ret = PQgetlineAsync (P, buffer, sizeof (buffer));
1542
1543   if (ret == -1) return Qt; /* done! */
1544   else if (!ret) return Qnil; /* no data yet */
1545   else return Fcons (make_int (ret),
1546                      make_ext_string (buffer, ret, PG_OS_CODING));
1547 }
1548
1549 DEFUN ("pq-put-nbytes", Fpq_put_nbytes, 2, 2, 0, /*
1550 Asynchronous copy out.
1551 */
1552        (conn, data))
1553 {
1554   /* NULs are not allowed.  I don't think this matters at this time. */
1555   PGconn *P;
1556   char *c_data;
1557
1558   CHECK_PGCONN (conn);
1559   CHECK_STRING (data);
1560
1561   P = (XPGCONN (conn))->pgconn;
1562   CHECK_LIVE_CONNECTION (P);
1563   TO_EXTERNAL_FORMAT (LISP_STRING, data,
1564                       C_STRING_ALLOCA, c_data, Qnative);
1565
1566   return !PQputnbytes (P, c_data, strlen (c_data)) ? Qt : Qnil;
1567 }
1568
1569 DEFUN ("pq-end-copy", Fpq_end_copy, 1, 1, 0, /*
1570 End a copying operation.
1571 */
1572        (conn))
1573 {
1574   PGconn *P;
1575
1576   CHECK_PGCONN (conn);
1577   P = (XPGCONN (conn))->pgconn;
1578   CHECK_LIVE_CONNECTION (P);
1579
1580   return PQendcopy (P) ? Qt : Qnil;
1581 }
1582
1583 void
1584 syms_of_postgresql(void)
1585 {
1586 #ifndef RUNNING_XEMACS_21_1
1587   INIT_LRECORD_IMPLEMENTATION (pgconn);
1588   INIT_LRECORD_IMPLEMENTATION (pgresult);
1589 #endif
1590   defsymbol (&Qpostgresql, "postgresql");
1591
1592   /* opaque exported types */
1593   defsymbol (&Qpgconnp, "pgconnp");
1594   defsymbol (&Qpgresultp, "pgresultp");
1595
1596   /* connection status types */
1597   defsymbol (&Qpg_connection_ok, "pg::connection-ok");
1598   defsymbol (&Qpg_connection_bad, "pg::connection-bad");
1599   defsymbol (&Qpg_connection_started, "pg::connection-started");
1600   defsymbol (&Qpg_connection_made, "pg::connection-made");
1601   defsymbol (&Qpg_connection_awaiting_response, "pg::connection-awaiting-response");
1602   defsymbol (&Qpg_connection_auth_ok, "pg::connection-auth-ok");
1603   defsymbol (&Qpg_connection_setenv, "pg::connection-setenv");
1604
1605   /* Fields of PGconn */
1606   defsymbol (&Qpqdb, "pq::db");
1607   defsymbol (&Qpquser, "pq::user");
1608   defsymbol (&Qpqpass, "pq::pass");
1609   defsymbol (&Qpqhost, "pq::host");
1610   defsymbol (&Qpqport, "pq::port");
1611   defsymbol (&Qpqtty, "pq::tty");
1612   defsymbol (&Qpqoptions, "pq::options");
1613   defsymbol (&Qpqstatus, "pq::status");
1614   defsymbol (&Qpqerrormessage, "pq::error-message");
1615   defsymbol (&Qpqbackendpid, "pq::backend-pid");
1616
1617   /* Query status results */
1618   defsymbol (&Qpgres_empty_query, "pgres::empty-query");
1619   defsymbol (&Qpgres_command_ok, "pgres::command-ok");
1620   defsymbol (&Qpgres_tuples_ok, "pgres::tuples-ok");
1621   defsymbol (&Qpgres_copy_out, "pgres::copy-out");
1622   defsymbol (&Qpgres_copy_in, "pgres::copy-in");
1623   defsymbol (&Qpgres_bad_response, "pgres::bad-response");
1624   defsymbol (&Qpgres_nonfatal_error, "pgres::nonfatal-error");
1625   defsymbol (&Qpgres_fatal_error, "pgres::fatal-error");
1626
1627   /* Poll status results */
1628   defsymbol (&Qpgres_polling_failed, "pgres::polling-failed");
1629   defsymbol (&Qpgres_polling_reading, "pgres::polling-reading");
1630   defsymbol (&Qpgres_polling_writing, "pgres::polling-writing");
1631   defsymbol (&Qpgres_polling_ok, "pgres::polling-ok");
1632   defsymbol (&Qpgres_polling_active, "pgres::polling-active");
1633
1634 #ifdef HAVE_POSTGRESQLV7
1635   DEFSUBR (Fpq_connect_start);
1636   DEFSUBR (Fpq_connect_poll);
1637 #ifdef MULE
1638   DEFSUBR (Fpq_client_encoding);
1639   DEFSUBR (Fpq_set_client_encoding);
1640 #endif /* MULE */
1641 #endif /* HAVE_POSTGRESQLV7 */
1642   DEFSUBR (Fpq_conn_defaults);
1643   DEFSUBR (Fpq_connectdb);
1644   DEFSUBR (Fpq_finish);
1645   DEFSUBR (Fpq_clear);
1646   DEFSUBR (Fpq_is_busy);
1647   DEFSUBR (Fpq_consume_input);
1648
1649   DEFSUBR (Fpq_reset);
1650 #ifdef HAVE_POSTGRESQLV7
1651   DEFSUBR (Fpq_reset_start);
1652   DEFSUBR (Fpq_reset_poll);
1653 #endif
1654   DEFSUBR (Fpq_request_cancel);
1655   DEFSUBR (Fpq_pgconn);
1656
1657   DEFSUBR (Fpq_exec);
1658   DEFSUBR (Fpq_send_query);
1659   DEFSUBR (Fpq_get_result);
1660   DEFSUBR (Fpq_result_status);
1661   DEFSUBR (Fpq_res_status);
1662   DEFSUBR (Fpq_result_error_message);
1663   DEFSUBR (Fpq_ntuples);
1664   DEFSUBR (Fpq_nfields);
1665   DEFSUBR (Fpq_binary_tuples);
1666   DEFSUBR (Fpq_fname);
1667   DEFSUBR (Fpq_fnumber);
1668   DEFSUBR (Fpq_ftype);
1669   DEFSUBR (Fpq_fsize);
1670   DEFSUBR (Fpq_fmod);
1671   /***/
1672   DEFSUBR (Fpq_get_value);
1673   DEFSUBR (Fpq_get_length);
1674   DEFSUBR (Fpq_get_is_null);
1675   DEFSUBR (Fpq_cmd_status);
1676   DEFSUBR (Fpq_cmd_tuples);
1677   DEFSUBR (Fpq_oid_value);
1678
1679 #ifdef HAVE_POSTGRESQLV7
1680   DEFSUBR (Fpq_set_nonblocking);
1681   DEFSUBR (Fpq_is_nonblocking);
1682   DEFSUBR (Fpq_flush);
1683 #endif
1684   DEFSUBR (Fpq_notifies);
1685
1686 #if defined (HAVE_POSTGRESQLV7) && defined(MULE)
1687   DEFSUBR (Fpq_env_2_encoding);
1688 #endif
1689
1690   DEFSUBR (Fpq_lo_import);
1691   DEFSUBR (Fpq_lo_export);
1692
1693   DEFSUBR (Fpq_make_empty_pgresult);
1694
1695   /* copy in/out functions */
1696   DEFSUBR (Fpq_get_line);
1697   DEFSUBR (Fpq_put_line);
1698   DEFSUBR (Fpq_get_line_async);
1699   DEFSUBR (Fpq_put_nbytes);
1700   DEFSUBR (Fpq_end_copy);
1701 }
1702
1703 void
1704 vars_of_postgresql(void)
1705 {
1706   char *p;
1707
1708   Fprovide (Qpostgresql);
1709 #ifdef HAVE_POSTGRESQLV7
1710   Fprovide (intern ("postgresqlv7"));
1711 #endif
1712 #ifndef RUNNING_XEMACS_21_1
1713   Vpg_coding_system = Qnative;
1714   DEFVAR_LISP ("pg-coding-system", &Vpg_coding_system /*
1715 Default Postgres client coding system.
1716 */ );
1717 #endif
1718
1719   if ((p = getenv ("PGHOST")))
1720     {
1721       VXPGHOST = build_ext_string (p, PG_OS_CODING);
1722     }
1723   else
1724     {
1725       VXPGHOST = Qnil;
1726     }
1727   DEFVAR_LISP ("pg:host", &VXPGHOST /*
1728 Default PostgreSQL server name.
1729 If not set, the server running on the local host is used.  The
1730 initial value is set from the PGHOST environment variable.
1731 */ );
1732
1733   if ((p = getenv ("PGUSER")))
1734     {
1735       VXPGUSER = build_ext_string (p, PG_OS_CODING);
1736     }
1737   else
1738     {
1739       VXPGUSER = Qnil;
1740     }
1741   DEFVAR_LISP ("pg:user", &VXPGUSER /*
1742 Default PostgreSQL user name.
1743 This value is used when connecting to a database for authentication.
1744 The initial value is set from the PGUSER environment variable.
1745 */ );
1746
1747   if ((p = getenv ("PGOPTIONS")))
1748     {
1749       VXPGOPTIONS = build_ext_string (p, PG_OS_CODING);
1750     }
1751   else
1752     {
1753       VXPGOPTIONS = Qnil;
1754     }
1755   DEFVAR_LISP ("pg:options", &VXPGOPTIONS /*
1756 Default PostgreSQL user name.
1757 This value is used when connecting to a database for authentication.
1758 The initial value is set from the PGUSER environment variable.
1759 */ );
1760
1761   if ((p = getenv ("PGPORT")))
1762     {
1763       VXPGPORT = make_int (atoi (p));
1764     }
1765   else
1766     {
1767       VXPGPORT = Qnil;
1768     }
1769   DEFVAR_LISP ("pg:port", &VXPGPORT /*
1770 Default port to connect to PostgreSQL backend.
1771 This value is used when connecting to a database.
1772 The initial value is set from the PGPORT environment variable.
1773 */ );
1774
1775   if ((p = getenv ("PGTTY")))
1776     {
1777       VXPGTTY = build_ext_string (p, PG_OS_CODING);
1778     }
1779   else
1780     {
1781       VXPGTTY = Qnil;
1782     }
1783   DEFVAR_LISP ("pg:tty", &VXPGTTY /*
1784 Default debugging TTY.
1785 There is no useful setting of this variable in the XEmacs Lisp API.
1786 The initial value is set from the PGTTY environment variable.
1787 */ );
1788
1789   if ((p = getenv ("PGDATABASE")))
1790     {
1791       VXPGDATABASE = build_ext_string (p, PG_OS_CODING);
1792     }
1793   else
1794     {
1795       VXPGDATABASE = Qnil;
1796     }
1797   DEFVAR_LISP ("pg:database", &VXPGDATABASE /*
1798 Default database to connect to.
1799 The initial value is set from the PGDATABASE environment variable.
1800 */ );
1801
1802   if ((p = getenv ("PGREALM")))
1803     {
1804       VXPGREALM = build_ext_string (p, PG_OS_CODING);
1805     }
1806   else
1807     {
1808       VXPGREALM = Qnil;
1809     }
1810   DEFVAR_LISP ("pg:realm", &VXPGREALM /*
1811 Default kerberos realm to use for authentication.
1812 The initial value is set from the PGREALM environment variable.
1813 */ );
1814
1815 #ifdef MULE
1816   /* It's not clear whether this is any use.  My intent is to
1817      autodetect the coding system from the database. */
1818   if ((p = getenv ("PGCLIENTENCODING")))
1819     {
1820       VXPGCLIENTENCODING = build_ext_string (p, PG_OS_CODING);
1821     }
1822   else
1823     {
1824       VXPGCLIENTENCODING = Qnil;
1825     }
1826   DEFVAR_LISP ("pg:client-encoding", &VXPGCLIENTENCODING /*
1827 Default client encoding to use.
1828 The initial value is set from the PGCLIENTENCODING environment variable.
1829 */ );
1830 #endif
1831
1832 #if !defined(HAVE_POSTGRESQLV7)
1833   if ((p = getenv ("PGAUTHTYPE")))
1834     {
1835       VXPGAUTHTYPE = build_ext_string (p, PG_OS_CODING);
1836     }
1837   else
1838     {
1839       VXPGAUTHTYPE = Qnil;
1840     }
1841   DEFVAR_LISP ("pg:authtype", &VXPGAUTHTYPE /*
1842 Default authentication to use.
1843 The initial value is set from the PGAUTHTYPE environment variable.
1844
1845 WARNING:  This variable has gone away in versions of PostgreSQL newer
1846 than 6.5.
1847 */ );
1848 #endif
1849
1850   if ((p = getenv ("PGGEQO")))
1851     {
1852       VXPGGEQO = build_ext_string (p, PG_OS_CODING);
1853     }
1854   else
1855     {
1856       VXPGGEQO = Qnil;
1857     }
1858   DEFVAR_LISP ("pg:geqo", &VXPGGEQO /*
1859 Genetic Query Optimizer options.
1860 The initial value is set from the PGGEQO environment variable.
1861 */ );
1862
1863   if ((p = getenv ("PGCOSTINDEX")))
1864     {
1865       VXPGCOSTINDEX = build_ext_string (p, PG_OS_CODING);
1866     }
1867   else
1868     {
1869       VXPGCOSTINDEX = Qnil;
1870     }
1871   DEFVAR_LISP ("pg:cost-index", &VXPGCOSTINDEX /*
1872 Default cost index options.
1873 The initial value is set from the PGCOSTINDEX environment variable.
1874 */ );
1875
1876   if ((p = getenv ("PGCOSTHEAP")))
1877     {
1878       VXPGCOSTHEAP = build_ext_string (p, PG_OS_CODING);
1879     }
1880   else
1881     {
1882       VXPGCOSTHEAP = Qnil;
1883     }
1884   DEFVAR_LISP ("pg:cost-heap", &VXPGCOSTHEAP /*
1885 Default cost heap options.
1886 The initial value is set from the PGCOSTHEAP environment variable.
1887 */ );
1888
1889   if ((p = getenv ("PGTZ")))
1890     {
1891       VXPGTZ = build_ext_string (p, PG_OS_CODING);
1892     }
1893   else
1894     {
1895       VXPGTZ = Qnil;
1896     }
1897   DEFVAR_LISP ("pg:tz", &VXPGTZ /*
1898 Default timezone to use.
1899 The initial value is set from the PGTZ environment variable.
1900 */ );
1901
1902   if ((p = getenv ("PGDATESTYLE")))
1903     {
1904       VXPGDATESTYLE = build_ext_string (p, PG_OS_CODING);
1905     }
1906   else
1907     {
1908       VXPGDATESTYLE = Qnil;
1909     }
1910   DEFVAR_LISP ("pg:date-style", &VXPGDATESTYLE /*
1911 Default date style to use.
1912 The initial value is set from the PGDATESTYLE environment variable.
1913 */ );
1914 }