comparison modules/postgresql/postgresql.c @ 4985:358aa3bb603f

Automatic merge
author Ben Wing <ben@xemacs.org>
date Fri, 05 Feb 2010 12:12:28 -0600
parents 4aebb0131297
children b5df3737028a
comparison
equal deleted inserted replaced
4984:f23cd0184dcf 4985:358aa3bb603f
95 #endif 95 #endif
96 96
97 /* #define POSTGRES_LO_IMPORT_IS_VOID 1 */ 97 /* #define POSTGRES_LO_IMPORT_IS_VOID 1 */
98 98
99 #include "lisp.h" 99 #include "lisp.h"
100 #include "sysdep.h"
101 100
102 #include "buffer.h" 101 #include "buffer.h"
103 #include "postgresql.h" 102 #include "postgresql.h"
104 #include "process.h" 103 #include "process.h"
105 #ifdef HAVE_SHLIB 104 #ifdef HAVE_SHLIB
106 # include "emodules.h" 105 # include "emodules.h"
107 #endif 106 #endif
107 #include "sysdep.h"
108 #include "sysfile.h"
108 109
109 #ifdef RUNNING_XEMACS_21_1 /* handle interface changes */ 110 #ifdef RUNNING_XEMACS_21_1 /* handle interface changes */
110 #define PG_OS_CODING FORMAT_FILENAME 111 #define PG_OS_CODING FORMAT_FILENAME
111 #define TO_EXTERNAL_FORMAT(a,from,b,to,c) GET_C_STRING_EXT_DATA_ALLOCA(from,FORMAT_FILENAME,to) 112 #define TO_EXTERNAL_FORMAT(a,from,b,to,c) GET_C_STRING_EXT_DATA_ALLOCA(from,FORMAT_FILENAME,to)
112 #else 113 #else
121 #define CHECK_LIVE_CONNECTION(P) \ 122 #define CHECK_LIVE_CONNECTION(P) \
122 do \ 123 do \
123 { \ 124 { \
124 if (!P || (PQstatus (P) != CONNECTION_OK)) \ 125 if (!P || (PQstatus (P) != CONNECTION_OK)) \
125 { \ 126 { \
126 const Ibyte *err; \ 127 Lisp_Object err; \
127 \ 128 \
128 if (P) \ 129 if (P) \
129 err = NEW_EXTERNAL_TO_C_STRING (PQerrorMessage (P), PG_OS_CODING); \ 130 err = build_extstring (PQerrorMessage (P), PG_OS_CODING); \
130 else \ 131 else \
131 err = (const Ibyte *) "bad value"; \ 132 err = build_msg_string ("Bad value"); \
132 signal_ferror (Qprocess_error, "dead connection [%s]", err); \ 133 signal_error (Qprocess_error, "Dead connection", err); \
133 } \ 134 } \
134 } \ 135 } \
135 while (0) 136 while (0)
136 137
137 #define PUKE_IF_NULL(p) \ 138 #define PUKE_IF_NULL(p) \
138 do \ 139 do \
139 { \ 140 { \
140 if (!p) signal_error (Qinvalid_argument, "bad value", Qunbound); \ 141 if (!p) signal_error (Qinvalid_argument, "Bad value", Qunbound); \
141 } \ 142 } \
142 while (0) 143 while (0)
144
145 #define SIGNAL_ERROR(p, reason) \
146 do \
147 { \
148 signal_error (Qprocess_error, reason, \
149 build_extstring (PQerrorMessage (p), PG_OS_CODING)); \
150 } \
151 while (0)
143 152
144 static Lisp_Object VXPGHOST; 153 static Lisp_Object VXPGHOST;
145 static Lisp_Object VXPGUSER; 154 static Lisp_Object VXPGUSER;
146 static Lisp_Object VXPGOPTIONS; 155 static Lisp_Object VXPGOPTIONS;
147 static Lisp_Object VXPGPORT; 156 static Lisp_Object VXPGPORT;
477 486
478 /* PQconnectdb Makes a new connection to a backend. 487 /* PQconnectdb Makes a new connection to a backend.
479 PGconn *PQconnectdb(const char *conninfo) 488 PGconn *PQconnectdb(const char *conninfo)
480 */ 489 */
481 490
482 /* ###autoload */ 491 #ifdef HAVE_POSTGRESQLV7
483 DEFUN ("pq-connectdb", Fpq_connectdb, 1, 1, 0, /* 492 #define USED_IF_V7(x) x
484 Make a new connection to a PostgreSQL backend. 493 #else
485 */ 494 #define USED_IF_V7(x) UNUSED (x)
486 (conninfo)) 495 #endif
496
497 static Lisp_Object
498 postgresql_connect (Lisp_Object conninfo, int USED_IF_V7 (async))
487 { 499 {
488 PGconn *P; 500 PGconn *P;
489 Lisp_PGconn *lisp_pgconn; 501 Lisp_PGconn *lisp_pgconn;
490 const Ascbyte *error_message = "Out of Memory?";
491 Extbyte *c_conninfo;
492 502
493 CHECK_STRING (conninfo); 503 CHECK_STRING (conninfo);
494 504
495 LISP_STRING_TO_EXTERNAL (conninfo, c_conninfo, PG_OS_CODING); 505 P = (
496 P = PQconnectdb (c_conninfo); 506 #ifdef HAVE_POSTGRESQLV7
507 async ? PQconnectStart :
508 #endif
509 PQconnectdb)
510 (LISP_STRING_TO_EXTERNAL (conninfo, PG_OS_CODING));
497 if (P && (PQstatus (P) == CONNECTION_OK)) 511 if (P && (PQstatus (P) == CONNECTION_OK))
498 { 512 {
499 (void)PQsetNoticeProcessor (P, xemacs_notice_processor, NULL); 513 (void) PQsetNoticeProcessor (P, xemacs_notice_processor, NULL);
500 lisp_pgconn = allocate_pgconn (); 514 lisp_pgconn = allocate_pgconn ();
501 lisp_pgconn->pgconn = P; 515 lisp_pgconn->pgconn = P;
502 return make_pgconn (lisp_pgconn); 516 return make_pgconn (lisp_pgconn);
503 } 517 }
504 else 518 else
505 { 519 {
506 /* Connection failed. Destroy the connection and signal an error. */ 520 /* Connection failed. Destroy the connection and signal an error. */
507 Ibyte *errmsg = (Ibyte *) error_message; 521
522 Lisp_Object errmsg;
508 if (P) 523 if (P)
509 { 524 {
510 /* storage for the error message gets erased when call PQfinish */ 525 errmsg = build_extstring (PQerrorMessage (P), PG_OS_CODING);
511 /* so we must temporarily stash it somewhere -- make alloca() copy */
512 errmsg = NEW_EXTERNAL_TO_C_STRING (PQerrorMessage (P), PG_OS_CODING);
513 IBYTE_STRING_TO_ALLOCA (errmsg, errmsg);
514 PQfinish (P); 526 PQfinish (P);
515 } 527 }
516 signal_ferror (Qprocess_error, "libpq: %s", errmsg); 528 else
529 errmsg = build_msg_string ("Out of Memory?");
530 signal_error (Qprocess_error, "Connecting to PostGreSQL backend",
531 errmsg);
517 } 532 }
533 }
534
535 /* ###autoload */
536 DEFUN ("pq-connectdb", Fpq_connectdb, 1, 1, 0, /*
537 Make a new connection to a PostgreSQL backend.
538 */
539 (conninfo))
540 {
541 return postgresql_connect (conninfo, 0);
518 } 542 }
519 543
520 /* PQconnectStart Makes a new asynchronous connection to a backend. 544 /* PQconnectStart Makes a new asynchronous connection to a backend.
521 PGconn *PQconnectStart(const char *conninfo) 545 PGconn *PQconnectStart(const char *conninfo)
522 */ 546 */
526 DEFUN ("pq-connect-start", Fpq_connect_start, 1, 1, 0, /* 550 DEFUN ("pq-connect-start", Fpq_connect_start, 1, 1, 0, /*
527 Make a new asynchronous connection to a PostgreSQL backend. 551 Make a new asynchronous connection to a PostgreSQL backend.
528 */ 552 */
529 (conninfo)) 553 (conninfo))
530 { 554 {
531 PGconn *P; 555 return postgresql_connect (conninfo, 1);
532 Lisp_PGconn *lisp_pgconn;
533 const Ascbyte *error_message = "Out of Memory?";
534 Extbyte *c_conninfo;
535
536 CHECK_STRING (conninfo);
537
538 LISP_STRING_TO_EXTERNAL (conninfo, c_conninfo, PG_OS_CODING);
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 } 556 }
563 557
564 DEFUN ("pq-connect-poll", Fpq_connect_poll, 1, 1, 0, /* 558 DEFUN ("pq-connect-poll", Fpq_connect_poll, 1, 1, 0, /*
565 Poll an asynchronous connection for completion 559 Poll an asynchronous connection for completion
566 */ 560 */
577 polling_status = PQconnectPoll (P); 571 polling_status = PQconnectPoll (P);
578 switch (polling_status) 572 switch (polling_status)
579 { 573 {
580 case PGRES_POLLING_FAILED: 574 case PGRES_POLLING_FAILED:
581 /* Something Bad has happened */ 575 /* Something Bad has happened */
582 { 576 SIGNAL_ERROR (P, "Polling asynchronous connection");
583 char *e = PQerrorMessage (P);
584 signal_ferror (Qprocess_error, "libpq: %s", e);
585 }
586 case PGRES_POLLING_OK: 577 case PGRES_POLLING_OK:
587 return Qpgres_polling_ok; 578 return Qpgres_polling_ok;
588 case PGRES_POLLING_READING: 579 case PGRES_POLLING_READING:
589 return Qpgres_polling_reading; 580 return Qpgres_polling_reading;
590 case PGRES_POLLING_WRITING: 581 case PGRES_POLLING_WRITING:
743 CHECK_PGCONN (conn); 734 CHECK_PGCONN (conn);
744 P = (XPGCONN (conn))->pgconn; 735 P = (XPGCONN (conn))->pgconn;
745 CHECK_LIVE_CONNECTION (P); 736 CHECK_LIVE_CONNECTION (P);
746 737
747 if (PQresetStart (P)) return Qt; 738 if (PQresetStart (P)) return Qt;
748 { 739 SIGNAL_ERROR (P, "Resetting connection");
749 char *e = PQerrorMessage (P);
750 signal_ferror (Qprocess_error, "libpq: %s", e);
751 }
752 } 740 }
753 741
754 DEFUN ("pq-reset-poll", Fpq_reset_poll, 1, 1, 0, /* 742 DEFUN ("pq-reset-poll", Fpq_reset_poll, 1, 1, 0, /*
755 Poll an asynchronous reset for completion. 743 Poll an asynchronous reset for completion.
756 */ 744 */
766 754
767 polling_status = PQresetPoll (P); 755 polling_status = PQresetPoll (P);
768 switch (polling_status) 756 switch (polling_status)
769 { 757 {
770 case PGRES_POLLING_FAILED: 758 case PGRES_POLLING_FAILED:
771 /* Something Bad has happened */ 759 SIGNAL_ERROR (P, "Polling asynchronous reset");
772 {
773 char *e = PQerrorMessage (P);
774 signal_ferror (Qprocess_error, "libpq: %s", e);
775 }
776 case PGRES_POLLING_OK: 760 case PGRES_POLLING_OK:
777 return Qpgres_polling_ok; 761 return Qpgres_polling_ok;
778 case PGRES_POLLING_READING: 762 case PGRES_POLLING_READING:
779 return Qpgres_polling_reading; 763 return Qpgres_polling_reading;
780 case PGRES_POLLING_WRITING: 764 case PGRES_POLLING_WRITING:
982 966
983 TO_EXTERNAL_FORMAT (LISP_STRING, query, 967 TO_EXTERNAL_FORMAT (LISP_STRING, query,
984 C_STRING_ALLOCA, c_query, Qnative); 968 C_STRING_ALLOCA, c_query, Qnative);
985 969
986 if (PQsendQuery (P, c_query)) return Qt; 970 if (PQsendQuery (P, c_query)) return Qt;
987 else signal_ferror (Qprocess_error, "async query: %s", PQerrorMessage (P)); 971 else SIGNAL_ERROR (P, "Sending asynchronous query");
988 } 972 }
989 973
990 DEFUN ("pq-get-result", Fpq_get_result, 1, 1, 0, /* 974 DEFUN ("pq-get-result", Fpq_get_result, 1, 1, 0, /*
991 Retrieve an asynchronous result from a query. 975 Retrieve an asynchronous result from a query.
992 NIL is returned when no more query work remains. 976 NIL is returned when no more query work remains.
1420 CHECK_STRING (filename); 1404 CHECK_STRING (filename);
1421 1405
1422 P = (XPGCONN (conn))->pgconn; 1406 P = (XPGCONN (conn))->pgconn;
1423 CHECK_LIVE_CONNECTION (P); 1407 CHECK_LIVE_CONNECTION (P);
1424 1408
1425 TO_EXTERNAL_FORMAT (LISP_STRING, filename, 1409 LISP_PATHNAME_CONVERT_OUT (filename, c_filename);
1426 C_STRING_ALLOCA, c_filename,
1427 Qfile_name);
1428 1410
1429 return make_int ((int)lo_import (P, c_filename)); 1411 return make_int ((int)lo_import (P, c_filename));
1430 } 1412 }
1431 1413
1432 DEFUN ("pq-lo-export", Fpq_lo_export, 3, 3, 0, /* 1414 DEFUN ("pq-lo-export", Fpq_lo_export, 3, 3, 0, /*
1441 CHECK_STRING (filename); 1423 CHECK_STRING (filename);
1442 1424
1443 P = (XPGCONN (conn))->pgconn; 1425 P = (XPGCONN (conn))->pgconn;
1444 CHECK_LIVE_CONNECTION (P); 1426 CHECK_LIVE_CONNECTION (P);
1445 1427
1446 TO_EXTERNAL_FORMAT (LISP_STRING, filename, 1428 LISP_PATHNAME_CONVERT_OUT (filename, c_filename);
1447 C_STRING_ALLOCA, c_filename, Qfile_name);
1448 1429
1449 return make_int ((int)lo_export (P, XINT (oid), c_filename)); 1430 return make_int ((int)lo_export (P, XINT (oid), c_filename));
1450 } 1431 }
1451 1432
1452 DEFUN ("pq-make-empty-pgresult", Fpq_make_empty_pgresult, 2, 2, 0, /* 1433 DEFUN ("pq-make-empty-pgresult", Fpq_make_empty_pgresult, 2, 2, 0, /*