comparison modules/postgresql/postgresql.c @ 996:25e260cb7994

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