Mercurial > hg > xemacs-beta
comparison src/postgresql.c @ 406:b8cc9ab3f761 r21-2-33
Import from CVS: tag r21-2-33
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:17:09 +0200 |
parents | 2f8bb876ab1d |
children | 501cfd01ee6d |
comparison
equal
deleted
inserted
replaced
405:0e08f63c74d2 | 406:b8cc9ab3f761 |
---|---|
55 PQgetline (copy in/out) | 55 PQgetline (copy in/out) |
56 PQputline (copy in/out) | 56 PQputline (copy in/out) |
57 PQgetlineAsync (copy in/out Asynch.) | 57 PQgetlineAsync (copy in/out Asynch.) |
58 PQputnbytes (copy in/out Asynch.) | 58 PQputnbytes (copy in/out Asynch.) |
59 PQendcopy (copy in/out) | 59 PQendcopy (copy in/out) |
60 PQsetenvStart (Asynch. Queries) | |
61 PQsetenvPoll (Asynch. Queries) | |
62 PQsetenvHandle (Asynch. Queries) | |
63 | 60 |
64 Unsupported functions: | 61 Unsupported functions: |
65 PQsetdbLogin -- This function is deprecated, has a subset of the | 62 PQsetdbLogin -- This function is deprecated, has a subset of the |
66 functionality of PQconnectdb, and is better done in Lisp. | 63 functionality of PQconnectdb, and is better done in Lisp. |
67 PQsetdb -- Same as for PQsetdbLogin | 64 PQsetdb -- Same as for PQsetdbLogin |
93 interface to lcrecord handling has changed with 21.2, so unfortunately | 90 interface to lcrecord handling has changed with 21.2, so unfortunately |
94 we will need a few snippets of backwards compatibility code. | 91 we will need a few snippets of backwards compatibility code. |
95 */ | 92 */ |
96 #if (EMACS_MAJOR_VERSION == 21) && (EMACS_MINOR_VERSION < 2) | 93 #if (EMACS_MAJOR_VERSION == 21) && (EMACS_MINOR_VERSION < 2) |
97 #define RUNNING_XEMACS_21_1 1 | 94 #define RUNNING_XEMACS_21_1 1 |
95 #define POSTGRES_INCLUDE(file) <file> | |
98 #endif | 96 #endif |
99 | 97 |
100 /* #define POSTGRES_LO_IMPORT_IS_VOID 1 */ | 98 /* #define POSTGRES_LO_IMPORT_IS_VOID 1 */ |
101 | 99 |
102 #include "lisp.h" | 100 #include "lisp.h" |
103 #include "sysdep.h" | 101 #include "sysdep.h" |
104 #include "buffer.h" | 102 #include "buffer.h" |
105 | 103 |
106 #include <libpq-fe.h> | 104 #include POSTGRES_INCLUDE (libpq-fe.h) |
107 /* Undefine the following when asynchronous setenvs are fixed in libpq. */ | |
108 /* #define LIBPQ_7_0_IS_FIXED */ | |
109 #include "postgresql.h" | 105 #include "postgresql.h" |
110 | 106 |
111 #ifdef RUNNING_XEMACS_21_1 /* handle interface changes */ | 107 #ifdef RUNNING_XEMACS_21_1 /* handle interface changes */ |
112 #define I_HATE_CONST CONST | 108 #define I_HATE_CONST CONST |
113 #define PG_OS_CODING FORMAT_FILENAME | 109 #define PG_OS_CODING FORMAT_FILENAME |
394 NULL, NULL, | 390 NULL, NULL, |
395 0, | 391 0, |
396 Lisp_PGresult); | 392 Lisp_PGresult); |
397 #endif | 393 #endif |
398 | 394 |
399 /****/ | |
400 #ifdef HAVE_POSTGRESQLV7 | |
401 /* PGsetenvHandle is an opaque object and we need to be able to store them in | |
402 Lisp code so we can make asynchronous environmental calls. | |
403 | |
404 Asynchronous setenv calls were introduced in libpq-7.0. | |
405 */ | |
406 #ifdef LIBPQ_7_0_IS_FIXED | |
407 | |
408 Lisp_Object Qpgsetenvp; | |
409 | |
410 static Lisp_Object | |
411 make_pgsetenv (Lisp_PGsetenvHandle *pgsetenv) | |
412 { | |
413 Lisp_Object lisp_pgsetenv; | |
414 XSETPGSETENV (lisp_pgsetenv, pgsetenv); | |
415 return lisp_pgsetenv; | |
416 } | |
417 | |
418 static Lisp_Object | |
419 #ifdef RUNNING_XEMACS_21_1 | |
420 mark_pgsetenv (Lisp_Object obj, void (*markobj) (Lisp_Object)) | |
421 #else | |
422 mark_pgsetenv (Lisp_Object obj) | |
423 #endif | |
424 { | |
425 return Qnil; | |
426 } | |
427 | |
428 static void | |
429 print_pgsetenv (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
430 { | |
431 char *fmt = "#<PGsetenvHandle %s>"; | |
432 char buf[1024]; | |
433 PGsetenvHandle *h; | |
434 | |
435 h = (XPGSETENV (obj))->pgsetenv; | |
436 | |
437 sprintf (buf, fmt, h ? "live" : "DEAD"); | |
438 | |
439 /* There are no accessor functions to retrieve any fields, so we must */ | |
440 /* treat this as being completely opaque. */ | |
441 if (print_readably) | |
442 error ("printing unreadable object %s", buf); | |
443 else | |
444 write_c_string (buf, printcharfun); | |
445 } | |
446 | |
447 static Lisp_PGsetenvHandle * | |
448 allocate_pgresult (void) | |
449 { | |
450 #ifdef RUNNING_XEMACS_21_1 | |
451 Lisp_PGsetenvHandle *pgsetenv = | |
452 alloc_lcrecord_type (Lisp_PGsetenvHandle, lrecord_pgsetenv); | |
453 #else | |
454 Lisp_PGsetenvHandle *pgsetenv = | |
455 alloc_lcrecord_type (Lisp_PGsetenvHandle, &lrecord_pgsetenv); | |
456 #endif | |
457 pgsetenv->pgsetenv = (PGsetenvState *)NULL; | |
458 return pgsetenv; | |
459 } | |
460 | |
461 static void | |
462 finalize_pgsetenv (void *header, int for_disksave) | |
463 { | |
464 Lisp_PGsetenvHandle *pgsetenv = (Lisp_PGsetenvHandle *)header; | |
465 | |
466 if (for_disksave) | |
467 signal_simple_error ("Can't dump an emacs containing PGsetenvHandle objects", | |
468 make_pgsetenv (pgsetenv)); | |
469 | |
470 /* #### PGsetenvHandle's are allocated with malloc(), however in | |
471 libpq-7.0 the treatment of them is little short of disastrous. | |
472 We don't dare attempt to free it, because there are many code | |
473 paths which lead to the handle being freed internally. The | |
474 connection routines leak setenv handles and so will we until | |
475 libpq gets cleaned up. | |
476 Actually, in 7.0b1 asynchronous setenv cannot work outside libpq, so | |
477 these functions are disabled in this API. | |
478 */ | |
479 if (pgsetenv->pgsetenv) | |
480 { | |
481 free (pgsetenv->pgsetenv); | |
482 pgsetenv->pgsetenv = (PGsetenvHandle *)NULL; | |
483 } | |
484 } | |
485 | |
486 #ifdef RUNNING_XEMACS_21_1 | |
487 DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult, | |
488 mark_pgresult, print_pgresult, finalize_pgresult, | |
489 NULL, NULL, | |
490 Lisp_PGresult); | |
491 #else | |
492 DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult, | |
493 mark_pgresult, print_pgresult, finalize_pgresult, | |
494 NULL, NULL, | |
495 0, | |
496 Lisp_PGresult); | |
497 #endif /* RUNNING_XEMACS_21_1 */ | |
498 | |
499 #endif /* LIBPQ_7_0_IS_FIXED */ | |
500 #endif /* HAVE_POSTGRESQLV7 */ | |
501 | |
502 /***********************/ | 395 /***********************/ |
503 | 396 |
504 /* notices */ | 397 /* notices */ |
505 static void | 398 static void |
506 xemacs_notice_processor (void *arg, I_HATE_CONST char *msg) | 399 xemacs_notice_processor (void *arg, I_HATE_CONST char *msg) |
1685 CHECK_LIVE_CONNECTION (P); | 1578 CHECK_LIVE_CONNECTION (P); |
1686 | 1579 |
1687 return PQendcopy (P) ? Qt : Qnil; | 1580 return PQendcopy (P) ? Qt : Qnil; |
1688 } | 1581 } |
1689 | 1582 |
1690 /* The setenv suite of functions. The author of the libpq manual doesn't | |
1691 know a whole lot about them, and neither do I. | |
1692 */ | |
1693 #if !defined (HAVE_POSTGRESQLV7) || defined (LIBPQ_7_0_IS_FIXED) | |
1694 DEFUN ("pq-setenv", Fpq_setenv, 1, 1, 0, /* | |
1695 Set environmental parameters on the backend synchronously. | |
1696 Returns t if the operation was successful, nil otherwise. | |
1697 */ | |
1698 (conn)) | |
1699 { | |
1700 PGconn *P; | |
1701 | |
1702 CHECK_PGCONN (conn); | |
1703 P = (XPGCONN (conn))->pgconn; | |
1704 CHECK_LIVE_CONNECTION (P); | |
1705 | |
1706 return PQsetenv (P) ? Qt : Qnil; | |
1707 } | |
1708 #endif | |
1709 | |
1710 #ifdef LIBPQ_7_0_IS_FIXED | |
1711 | |
1712 DEFUN ("pq-setenv-start", Fpq_setenv_start, 1, 1, 0, /* | |
1713 Set environmental parameters on the backend asynchronously. | |
1714 A PGsetenvHandle is returned on success, nil otherwise. | |
1715 */ | |
1716 (conn)) | |
1717 { | |
1718 PGconn *P; | |
1719 PGsetenvHandle *handle; | |
1720 Lisp_setenvHandle *lseh; | |
1721 | |
1722 CHECK_PGCONN (conn); | |
1723 P = (XPGCONN (conn))->pgconn; | |
1724 CHECK_LIVE_CONNECTION (P); | |
1725 | |
1726 handle = PQsetenvStart (P); | |
1727 if (!handle) error ("out of memory?"); | |
1728 | |
1729 lseh = allocate_pgsetenv (); | |
1730 lseh->setenv = handle; | |
1731 | |
1732 return make_pgsetenv (lseh); | |
1733 } | |
1734 | |
1735 DEFUN ("pq-setenv-poll", Fpq_setenv_poll, 1, 1, 0, /* | |
1736 Poll an asynchronous setenv operation for completion. | |
1737 */ | |
1738 (conn)) | |
1739 { | |
1740 PGconn *P; | |
1741 PostgresPollingStatusType pst; | |
1742 | |
1743 CHECK_PGCONN (conn); | |
1744 P = (XPGCONN (conn))->pgconn; | |
1745 CHECK_LIVE_CONNECTION (P); | |
1746 | |
1747 pst = PQsetenvPoll (P); | |
1748 switch (pst) | |
1749 { | |
1750 case PGRES_POLLING_FAILED: | |
1751 /* Something Bad has happened */ | |
1752 { | |
1753 char *e = PQerrorMessage (P); | |
1754 error ("libpq: %s", e); | |
1755 } | |
1756 case PGRES_POLLING_OK: | |
1757 return Qpgres_polling_ok; | |
1758 case PGRES_POLLING_READING: | |
1759 return Qpgres_polling_reading; | |
1760 case PGRES_POLLING_WRITING: | |
1761 return Qpgres_polling_writing; | |
1762 case PGRES_POLLING_ACTIVE: | |
1763 return Qpgres_polling_active; | |
1764 default: | |
1765 /* they've added a new field we don't know about */ | |
1766 error ("Help! Unknown status code %08x from backend!", PS); | |
1767 } | |
1768 } | |
1769 | |
1770 DEFUN ("pq-setenv-abort", Fpq_setenv_abort, 1, 1, 0, /* | |
1771 Attempt to abort an in-progress asynchronous setenv operation. | |
1772 */ | |
1773 (handle)) | |
1774 { | |
1775 PGsetenvHandle *h; | |
1776 | |
1777 CHECK_PGSETENV (handle); | |
1778 h = (XPGSETENV (handle))->pgsetenv; | |
1779 PUKE_IF_NULL (h); | |
1780 | |
1781 PQsetenvAbort (h); | |
1782 /* PQsetenvAbort usually free(3)'s the handle, don't take any chances. */ | |
1783 (XSETENV (handle))->pgsetenv = (PGsetenvHandle *)NULL; | |
1784 | |
1785 return Qt; | |
1786 } | |
1787 #endif /* LIBPQ_7_0_IS_FIXED */ | |
1788 | |
1789 void | 1583 void |
1790 syms_of_postgresql(void) | 1584 syms_of_postgresql(void) |
1791 { | 1585 { |
1792 #ifndef RUNNING_XEMACS_21_1 | 1586 #ifndef RUNNING_XEMACS_21_1 |
1793 INIT_LRECORD_IMPLEMENTATION (pgconn); | 1587 INIT_LRECORD_IMPLEMENTATION (pgconn); |
1794 INIT_LRECORD_IMPLEMENTATION (pgresult); | 1588 INIT_LRECORD_IMPLEMENTATION (pgresult); |
1795 #ifdef LIBPQ_7_0_IS_FIXED | |
1796 INIT_LRECORD_IMPLEMENTATION (pgsetenv); | |
1797 #endif | |
1798 #endif | 1589 #endif |
1799 defsymbol (&Qpostgresql, "postgresql"); | 1590 defsymbol (&Qpostgresql, "postgresql"); |
1800 | 1591 |
1801 /* opaque exported types */ | 1592 /* opaque exported types */ |
1802 defsymbol (&Qpgconnp, "pgconnp"); | 1593 defsymbol (&Qpgconnp, "pgconnp"); |
1905 DEFSUBR (Fpq_get_line); | 1696 DEFSUBR (Fpq_get_line); |
1906 DEFSUBR (Fpq_put_line); | 1697 DEFSUBR (Fpq_put_line); |
1907 DEFSUBR (Fpq_get_line_async); | 1698 DEFSUBR (Fpq_get_line_async); |
1908 DEFSUBR (Fpq_put_nbytes); | 1699 DEFSUBR (Fpq_put_nbytes); |
1909 DEFSUBR (Fpq_end_copy); | 1700 DEFSUBR (Fpq_end_copy); |
1910 | |
1911 /* The value of the setenv functions is questioned in the libpq manual. */ | |
1912 #if !defined (HAVE_POSTGRESQLV7) || defined (LIBPQ_7_0_IS_FIXED) | |
1913 DEFSUBR (Fpq_setenv); | |
1914 #endif | |
1915 #ifdef LIBPQ_7_0_IS_FIXED | |
1916 DEFSUBR (Fpq_setenv_start); | |
1917 DEFSUBR (Fpq_setenv_poll); | |
1918 DEFSUBR (Fpq_setenv_abort); | |
1919 #endif /* LIBPQ_7_0_IS_FIXED */ | |
1920 } | 1701 } |
1921 | 1702 |
1922 void | 1703 void |
1923 vars_of_postgresql(void) | 1704 vars_of_postgresql(void) |
1924 { | 1705 { |