15dfecf96Smrg/*
25dfecf96Smrg * Copyright (c) 2001 by The XFree86 Project, Inc.
35dfecf96Smrg *
45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a
55dfecf96Smrg * copy of this software and associated documentation files (the "Software"),
65dfecf96Smrg * to deal in the Software without restriction, including without limitation
75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the
95dfecf96Smrg * Software is furnished to do so, subject to the following conditions:
105dfecf96Smrg *
115dfecf96Smrg * The above copyright notice and this permission notice shall be included in
125dfecf96Smrg * all copies or substantial portions of the Software.
135dfecf96Smrg *
145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
205dfecf96Smrg * SOFTWARE.
215dfecf96Smrg *
225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall
235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other
245dfecf96Smrg * dealings in this Software without prior written authorization from the
255dfecf96Smrg * XFree86 Project.
265dfecf96Smrg *
275dfecf96Smrg * Author: Paulo César Pereira de Andrade
285dfecf96Smrg */
295dfecf96Smrg
305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/modules/psql.c,v 1.12tsi Exp $ */
315dfecf96Smrg
325dfecf96Smrg#include <stdlib.h>
335dfecf96Smrg#include <libpq-fe.h>
345dfecf96Smrg#undef USE_SSL		/* cannot get it to compile... */
355dfecf96Smrg#include <postgres.h>
365dfecf96Smrg#include <utils/geo_decls.h>
375dfecf96Smrg#include "lisp/internal.h"
385dfecf96Smrg#include "lisp/private.h"
395dfecf96Smrg
405dfecf96Smrg/*
415dfecf96Smrg * Prototypes
425dfecf96Smrg */
435dfecf96Smrgint psqlLoadModule(void);
445dfecf96Smrg
455dfecf96SmrgLispObj *Lisp_PQbackendPID(LispBuiltin*);
465dfecf96SmrgLispObj *Lisp_PQclear(LispBuiltin*);
475dfecf96SmrgLispObj *Lisp_PQconsumeInput(LispBuiltin*);
485dfecf96SmrgLispObj *Lisp_PQdb(LispBuiltin*);
495dfecf96SmrgLispObj *Lisp_PQerrorMessage(LispBuiltin*);
505dfecf96SmrgLispObj *Lisp_PQexec(LispBuiltin*);
515dfecf96SmrgLispObj *Lisp_PQfinish(LispBuiltin*);
525dfecf96SmrgLispObj *Lisp_PQfname(LispBuiltin*);
535dfecf96SmrgLispObj *Lisp_PQfnumber(LispBuiltin*);
545dfecf96SmrgLispObj *Lisp_PQfsize(LispBuiltin*);
555dfecf96SmrgLispObj *Lisp_PQftype(LispBuiltin*);
565dfecf96SmrgLispObj *Lisp_PQgetlength(LispBuiltin*);
575dfecf96SmrgLispObj *Lisp_PQgetvalue(LispBuiltin*);
585dfecf96SmrgLispObj *Lisp_PQhost(LispBuiltin*);
595dfecf96SmrgLispObj *Lisp_PQnfields(LispBuiltin*);
605dfecf96SmrgLispObj *Lisp_PQnotifies(LispBuiltin*);
615dfecf96SmrgLispObj *Lisp_PQntuples(LispBuiltin*);
625dfecf96SmrgLispObj *Lisp_PQoptions(LispBuiltin*);
635dfecf96SmrgLispObj *Lisp_PQpass(LispBuiltin*);
645dfecf96SmrgLispObj *Lisp_PQport(LispBuiltin*);
655dfecf96SmrgLispObj *Lisp_PQresultStatus(LispBuiltin*);
665dfecf96SmrgLispObj *Lisp_PQsetdb(LispBuiltin*);
675dfecf96SmrgLispObj *Lisp_PQsetdbLogin(LispBuiltin*);
685dfecf96SmrgLispObj *Lisp_PQsocket(LispBuiltin*);
695dfecf96SmrgLispObj *Lisp_PQstatus(LispBuiltin*);
705dfecf96SmrgLispObj *Lisp_PQtty(LispBuiltin*);
715dfecf96SmrgLispObj *Lisp_PQuser(LispBuiltin*);
725dfecf96Smrg
735dfecf96Smrg/*
745dfecf96Smrg * Initialization
755dfecf96Smrg */
765dfecf96Smrgstatic LispBuiltin lispbuiltins[] = {
775dfecf96Smrg    {LispFunction, Lisp_PQbackendPID, "pq-backend-pid connection"},
785dfecf96Smrg    {LispFunction, Lisp_PQclear, "pq-clear result"},
795dfecf96Smrg    {LispFunction, Lisp_PQconsumeInput, "pq-consume-input connection"},
805dfecf96Smrg    {LispFunction, Lisp_PQdb, "pq-db connection"},
815dfecf96Smrg    {LispFunction, Lisp_PQerrorMessage, "pq-error-message connection"},
825dfecf96Smrg    {LispFunction, Lisp_PQexec, "pq-exec connection query"},
835dfecf96Smrg    {LispFunction, Lisp_PQfinish, "pq-finish connection"},
845dfecf96Smrg    {LispFunction, Lisp_PQfname, "pq-fname result field-number"},
855dfecf96Smrg    {LispFunction, Lisp_PQfnumber, "pq-fnumber result field-name"},
865dfecf96Smrg    {LispFunction, Lisp_PQfsize, "pq-fsize result field-number"},
875dfecf96Smrg    {LispFunction, Lisp_PQftype, "pq-ftype result field-number"},
885dfecf96Smrg    {LispFunction, Lisp_PQgetlength, "pq-getlength result tupple field-number"},
895dfecf96Smrg    {LispFunction, Lisp_PQgetvalue, "pq-getvalue result tupple field-number &optional type"},
905dfecf96Smrg    {LispFunction, Lisp_PQhost, "pq-host connection"},
915dfecf96Smrg    {LispFunction, Lisp_PQnfields, "pq-nfields result"},
925dfecf96Smrg    {LispFunction, Lisp_PQnotifies, "pq-notifies connection"},
935dfecf96Smrg    {LispFunction, Lisp_PQntuples, "pq-ntuples result"},
945dfecf96Smrg    {LispFunction, Lisp_PQoptions, "pq-options connection"},
955dfecf96Smrg    {LispFunction, Lisp_PQpass, "pq-pass connection"},
965dfecf96Smrg    {LispFunction, Lisp_PQport, "pq-port connection"},
975dfecf96Smrg    {LispFunction, Lisp_PQresultStatus, "pq-result-status result"},
985dfecf96Smrg    {LispFunction, Lisp_PQsetdb, "pq-setdb host port options tty dbname"},
995dfecf96Smrg    {LispFunction, Lisp_PQsetdbLogin, "pq-setdb-login host port options tty dbname login password"},
1005dfecf96Smrg    {LispFunction, Lisp_PQsocket, "pq-socket connection"},
1015dfecf96Smrg    {LispFunction, Lisp_PQstatus, "pq-status connection"},
1025dfecf96Smrg    {LispFunction, Lisp_PQtty, "pq-tty connection"},
1035dfecf96Smrg    {LispFunction, Lisp_PQuser, "pq-user connection"},
1045dfecf96Smrg};
1055dfecf96Smrg
1065dfecf96SmrgLispModuleData psqlLispModuleData = {
1075dfecf96Smrg    LISP_MODULE_VERSION,
1085dfecf96Smrg    psqlLoadModule
1095dfecf96Smrg};
1105dfecf96Smrg
1115dfecf96Smrgstatic int PGconn_t, PGresult_t;
1125dfecf96Smrg
1135dfecf96Smrg/*
1145dfecf96Smrg * Implementation
1155dfecf96Smrg */
1165dfecf96Smrgint
1175dfecf96SmrgpsqlLoadModule(void)
1185dfecf96Smrg{
1195dfecf96Smrg    int i;
1205dfecf96Smrg    char *fname = "PSQL-LOAD-MODULE";
1215dfecf96Smrg
1225dfecf96Smrg    PGconn_t = LispRegisterOpaqueType("PGconn*");
1235dfecf96Smrg    PGresult_t = LispRegisterOpaqueType("PGresult*");
1245dfecf96Smrg
1255dfecf96Smrg    GCDisable();
1265dfecf96Smrg    /* NOTE: Implemented just enough to make programming examples
1275dfecf96Smrg     * (and my needs) work.
1285dfecf96Smrg     * Completing this is an exercise to the reader, or may be implemented
1295dfecf96Smrg     * when/if required.
1305dfecf96Smrg     */
1315dfecf96Smrg    LispExecute("(DEFSTRUCT PG-NOTIFY RELNAME BE-PID)\n"
1325dfecf96Smrg		"(DEFSTRUCT PG-POINT X Y)\n"
1335dfecf96Smrg		"(DEFSTRUCT PG-BOX HIGH LOW)\n"
1345dfecf96Smrg		"(DEFSTRUCT PG-POLYGON SIZE NUM-POINTS BOUNDBOX POINTS)\n");
1355dfecf96Smrg
1365dfecf96Smrg    /* enum ConnStatusType */
1375dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-OK"),
1385dfecf96Smrg			  REAL(CONNECTION_OK), fname, 0);
1395dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-BAD"),
1405dfecf96Smrg			  REAL(CONNECTION_BAD), fname, 0);
1415dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-STARTED"),
1425dfecf96Smrg			  REAL(CONNECTION_STARTED), fname, 0);
1435dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-MADE"),
1445dfecf96Smrg			  REAL(CONNECTION_MADE), fname, 0);
1455dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-AWAITING-RESPONSE"),
1465dfecf96Smrg			  REAL(CONNECTION_AWAITING_RESPONSE), fname, 0);
1475dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-AUTH-OK"),
1485dfecf96Smrg			  REAL(CONNECTION_AUTH_OK), fname, 0);
1495dfecf96Smrg    (void)LispSetVariable(ATOM2("PG-CONNECTION-SETENV"),
1505dfecf96Smrg			  REAL(CONNECTION_SETENV), fname, 0);
1515dfecf96Smrg
1525dfecf96Smrg
1535dfecf96Smrg    /* enum ExecStatusType */
1545dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-EMPTY-QUERY"),
1555dfecf96Smrg			  REAL(PGRES_EMPTY_QUERY), fname, 0);
1565dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-COMMAND-OK"),
1575dfecf96Smrg			  REAL(PGRES_COMMAND_OK), fname, 0);
1585dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-TUPLES-OK"),
1595dfecf96Smrg			  REAL(PGRES_TUPLES_OK), fname, 0);
1605dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-COPY-OUT"),
1615dfecf96Smrg			  REAL(PGRES_COPY_OUT), fname, 0);
1625dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-COPY-IN"),
1635dfecf96Smrg			  REAL(PGRES_COPY_IN), fname, 0);
1645dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-BAD-RESPONSE"),
1655dfecf96Smrg			  REAL(PGRES_BAD_RESPONSE), fname, 0);
1665dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-NONFATAL-ERROR"),
1675dfecf96Smrg			  REAL(PGRES_NONFATAL_ERROR), fname, 0);
1685dfecf96Smrg    (void)LispSetVariable(ATOM2("PGRES-FATAL-ERROR"),
1695dfecf96Smrg			  REAL(PGRES_FATAL_ERROR), fname, 0);
1705dfecf96Smrg    GCEnable();
1715dfecf96Smrg
1725dfecf96Smrg    for (i = 0; i < sizeof(lispbuiltins) / sizeof(lispbuiltins[0]); i++)
1735dfecf96Smrg	LispAddBuiltinFunction(&lispbuiltins[i]);
1745dfecf96Smrg
1755dfecf96Smrg    return (1);
1765dfecf96Smrg}
1775dfecf96Smrg
1785dfecf96SmrgLispObj *
1795dfecf96SmrgLisp_PQbackendPID(LispBuiltin *builtin)
1805dfecf96Smrg/*
1815dfecf96Smrg pq-backend-pid connection
1825dfecf96Smrg */
1835dfecf96Smrg{
1845dfecf96Smrg    int pid;
1855dfecf96Smrg    PGconn *conn;
1865dfecf96Smrg
1875dfecf96Smrg    LispObj *connection;
1885dfecf96Smrg
1895dfecf96Smrg    connection = ARGUMENT(0);
1905dfecf96Smrg
1915dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
1925dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
1935dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
1945dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
1955dfecf96Smrg
1965dfecf96Smrg    pid = PQbackendPID(conn);
1975dfecf96Smrg
1985dfecf96Smrg    return (INTEGER(pid));
1995dfecf96Smrg}
2005dfecf96Smrg
2015dfecf96SmrgLispObj *
2025dfecf96SmrgLisp_PQclear(LispBuiltin *builtin)
2035dfecf96Smrg/*
2045dfecf96Smrg pq-clear result
2055dfecf96Smrg */
2065dfecf96Smrg{
2075dfecf96Smrg    PGresult *res;
2085dfecf96Smrg
2095dfecf96Smrg    LispObj *result;
2105dfecf96Smrg
2115dfecf96Smrg    result = ARGUMENT(0);
2125dfecf96Smrg
2135dfecf96Smrg    if (!CHECKO(result, PGresult_t))
2145dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
2155dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
2165dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
2175dfecf96Smrg
2185dfecf96Smrg    PQclear(res);
2195dfecf96Smrg
2205dfecf96Smrg    return (NIL);
2215dfecf96Smrg}
2225dfecf96Smrg
2235dfecf96SmrgLispObj *
2245dfecf96SmrgLisp_PQconsumeInput(LispBuiltin *builtin)
2255dfecf96Smrg/*
2265dfecf96Smrg pq-consume-input connection
2275dfecf96Smrg */
2285dfecf96Smrg{
2295dfecf96Smrg    int result;
2305dfecf96Smrg    PGconn *conn;
2315dfecf96Smrg
2325dfecf96Smrg    LispObj *connection;
2335dfecf96Smrg
2345dfecf96Smrg    connection = ARGUMENT(0);
2355dfecf96Smrg
2365dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
2375dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
2385dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
2395dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
2405dfecf96Smrg
2415dfecf96Smrg    result = PQconsumeInput(conn);
2425dfecf96Smrg
2435dfecf96Smrg    return (INTEGER(result));
2445dfecf96Smrg}
2455dfecf96Smrg
2465dfecf96SmrgLispObj *
2475dfecf96SmrgLisp_PQdb(LispBuiltin *builtin)
2485dfecf96Smrg/*
2495dfecf96Smrg pq-db connection
2505dfecf96Smrg */
2515dfecf96Smrg{
2525dfecf96Smrg    char *string;
2535dfecf96Smrg    PGconn *conn;
2545dfecf96Smrg
2555dfecf96Smrg    LispObj *connection;
2565dfecf96Smrg
2575dfecf96Smrg    connection = ARGUMENT(0);
2585dfecf96Smrg
2595dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
2605dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
2615dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
2625dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
2635dfecf96Smrg
2645dfecf96Smrg    string = PQdb(conn);
2655dfecf96Smrg
2665dfecf96Smrg    return (string ? STRING(string) : NIL);
2675dfecf96Smrg}
2685dfecf96Smrg
2695dfecf96SmrgLispObj *
2705dfecf96SmrgLisp_PQerrorMessage(LispBuiltin *builtin)
2715dfecf96Smrg{
2725dfecf96Smrg    char *string;
2735dfecf96Smrg    PGconn *conn;
2745dfecf96Smrg
2755dfecf96Smrg    LispObj *connection;
2765dfecf96Smrg
2775dfecf96Smrg    connection = ARGUMENT(0);
2785dfecf96Smrg
2795dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
2805dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
2815dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
2825dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
2835dfecf96Smrg
2845dfecf96Smrg    string = PQerrorMessage(conn);
2855dfecf96Smrg
2865dfecf96Smrg    return (string ? STRING(string) : NIL);
2875dfecf96Smrg}
2885dfecf96Smrg
2895dfecf96SmrgLispObj *
2905dfecf96SmrgLisp_PQexec(LispBuiltin *builtin)
2915dfecf96Smrg/*
2925dfecf96Smrg pq-exec connection query
2935dfecf96Smrg */
2945dfecf96Smrg{
2955dfecf96Smrg    PGconn *conn;
2965dfecf96Smrg    PGresult *res;
2975dfecf96Smrg
2985dfecf96Smrg    LispObj *connection, *query;
2995dfecf96Smrg
3005dfecf96Smrg    query = ARGUMENT(1);
3015dfecf96Smrg    connection = ARGUMENT(0);
3025dfecf96Smrg
3035dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
3045dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
3055dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
3065dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
3075dfecf96Smrg
3085dfecf96Smrg    CHECK_STRING(query);
3095dfecf96Smrg    res = PQexec(conn, THESTR(query));
3105dfecf96Smrg
3115dfecf96Smrg    return (res ? OPAQUE(res, PGresult_t) : NIL);
3125dfecf96Smrg}
3135dfecf96Smrg
3145dfecf96SmrgLispObj *
3155dfecf96SmrgLisp_PQfinish(LispBuiltin *builtin)
3165dfecf96Smrg/*
3175dfecf96Smrg pq-finish connection
3185dfecf96Smrg */
3195dfecf96Smrg{
3205dfecf96Smrg    PGconn *conn;
3215dfecf96Smrg
3225dfecf96Smrg    LispObj *connection;
3235dfecf96Smrg
3245dfecf96Smrg    connection = ARGUMENT(0);
3255dfecf96Smrg
3265dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
3275dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
3285dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
3295dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
3305dfecf96Smrg
3315dfecf96Smrg    PQfinish(conn);
3325dfecf96Smrg
3335dfecf96Smrg    return (NIL);
3345dfecf96Smrg}
3355dfecf96Smrg
3365dfecf96SmrgLispObj *
3375dfecf96SmrgLisp_PQfname(LispBuiltin *builtin)
3385dfecf96Smrg/*
3395dfecf96Smrg pq-fname result field-number
3405dfecf96Smrg */
3415dfecf96Smrg{
3425dfecf96Smrg    char *string;
3435dfecf96Smrg    int field;
3445dfecf96Smrg    PGresult *res;
3455dfecf96Smrg
3465dfecf96Smrg    LispObj *result, *field_number;
3475dfecf96Smrg
3485dfecf96Smrg    field_number = ARGUMENT(1);
3495dfecf96Smrg    result = ARGUMENT(0);
3505dfecf96Smrg
3515dfecf96Smrg    if (!CHECKO(result, PGresult_t))
3525dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
3535dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
3545dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
3555dfecf96Smrg
3565dfecf96Smrg    CHECK_INDEX(field_number);
3575dfecf96Smrg    field = FIXNUM_VALUE(field_number);
3585dfecf96Smrg
3595dfecf96Smrg    string = PQfname(res, field);
3605dfecf96Smrg
3615dfecf96Smrg    return (string ? STRING(string) : NIL);
3625dfecf96Smrg}
3635dfecf96Smrg
3645dfecf96SmrgLispObj *
3655dfecf96SmrgLisp_PQfnumber(LispBuiltin *builtin)
3665dfecf96Smrg/*
3675dfecf96Smrg pq-fnumber result field-name
3685dfecf96Smrg */
3695dfecf96Smrg{
3705dfecf96Smrg    int number;
3715dfecf96Smrg    int field;
3725dfecf96Smrg    PGresult *res;
3735dfecf96Smrg
3745dfecf96Smrg    LispObj *result, *field_name;
3755dfecf96Smrg
3765dfecf96Smrg    field_name = ARGUMENT(1);
3775dfecf96Smrg    result = ARGUMENT(0);
3785dfecf96Smrg
3795dfecf96Smrg    if (!CHECKO(result, PGresult_t))
3805dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
3815dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
3825dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
3835dfecf96Smrg
3845dfecf96Smrg    CHECK_STRING(field_name);
3855dfecf96Smrg    number = PQfnumber(res, THESTR(field_name));
3865dfecf96Smrg
3875dfecf96Smrg    return (INTEGER(number));
3885dfecf96Smrg}
3895dfecf96Smrg
3905dfecf96SmrgLispObj *
3915dfecf96SmrgLisp_PQfsize(LispBuiltin *builtin)
3925dfecf96Smrg/*
3935dfecf96Smrg pq-fsize result field-number
3945dfecf96Smrg */
3955dfecf96Smrg{
3965dfecf96Smrg    int size, field;
3975dfecf96Smrg    PGresult *res;
3985dfecf96Smrg
3995dfecf96Smrg    LispObj *result, *field_number;
4005dfecf96Smrg
4015dfecf96Smrg    field_number = ARGUMENT(1);
4025dfecf96Smrg    result = ARGUMENT(0);
4035dfecf96Smrg
4045dfecf96Smrg    if (!CHECKO(result, PGresult_t))
4055dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
4065dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
4075dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
4085dfecf96Smrg
4095dfecf96Smrg    CHECK_INDEX(field_number);
4105dfecf96Smrg    field = FIXNUM_VALUE(field_number);
4115dfecf96Smrg
4125dfecf96Smrg    size = PQfsize(res, field);
4135dfecf96Smrg
4145dfecf96Smrg    return (INTEGER(size));
4155dfecf96Smrg}
4165dfecf96Smrg
4175dfecf96SmrgLispObj *
4185dfecf96SmrgLisp_PQftype(LispBuiltin *builtin)
4195dfecf96Smrg{
4205dfecf96Smrg    Oid oid;
4215dfecf96Smrg    int field;
4225dfecf96Smrg    PGresult *res;
4235dfecf96Smrg
4245dfecf96Smrg    LispObj *result, *field_number;
4255dfecf96Smrg
4265dfecf96Smrg    field_number = ARGUMENT(1);
4275dfecf96Smrg    result = ARGUMENT(0);
4285dfecf96Smrg
4295dfecf96Smrg    if (!CHECKO(result, PGresult_t))
4305dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
4315dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
4325dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
4335dfecf96Smrg
4345dfecf96Smrg    CHECK_INDEX(field_number);
4355dfecf96Smrg    field = FIXNUM_VALUE(field_number);
4365dfecf96Smrg
4375dfecf96Smrg    oid = PQftype(res, field);
4385dfecf96Smrg
4395dfecf96Smrg    return (INTEGER(oid));
4405dfecf96Smrg}
4415dfecf96Smrg
4425dfecf96SmrgLispObj *
4435dfecf96SmrgLisp_PQgetlength(LispBuiltin *builtin)
4445dfecf96Smrg/*
4455dfecf96Smrg pq-getlength result tupple field-number
4465dfecf96Smrg */
4475dfecf96Smrg{
4485dfecf96Smrg    PGresult *res;
4495dfecf96Smrg    int tuple, field, length;
4505dfecf96Smrg
4515dfecf96Smrg    LispObj *result, *otupple, *field_number;
4525dfecf96Smrg
4535dfecf96Smrg    field_number = ARGUMENT(2);
4545dfecf96Smrg    otupple = ARGUMENT(1);
4555dfecf96Smrg    result = ARGUMENT(0);
4565dfecf96Smrg
4575dfecf96Smrg    if (!CHECKO(result, PGresult_t))
4585dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
4595dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
4605dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
4615dfecf96Smrg
4625dfecf96Smrg    CHECK_INDEX(otupple);
4635dfecf96Smrg    tuple = FIXNUM_VALUE(otupple);
4645dfecf96Smrg
4655dfecf96Smrg    CHECK_INDEX(field_number);
4665dfecf96Smrg    field = FIXNUM_VALUE(field_number);
4675dfecf96Smrg
4685dfecf96Smrg    length = PQgetlength(res, tuple, field);
4695dfecf96Smrg
4705dfecf96Smrg    return (INTEGER(length));
4715dfecf96Smrg}
4725dfecf96Smrg
4735dfecf96SmrgLispObj *
4745dfecf96SmrgLisp_PQgetvalue(LispBuiltin *builtin)
4755dfecf96Smrg/*
4765dfecf96Smrg pq-getvalue result tuple field &optional type-specifier
4775dfecf96Smrg */
4785dfecf96Smrg{
4795dfecf96Smrg    char *string;
4805dfecf96Smrg    double real = 0.0;
4815dfecf96Smrg    PGresult *res;
4825dfecf96Smrg    int tuple, field, isint = 0, isreal = 0, integer;
4835dfecf96Smrg
4845dfecf96Smrg    LispObj *result, *otupple, *field_number, *type;
4855dfecf96Smrg
4865dfecf96Smrg    type = ARGUMENT(3);
4875dfecf96Smrg    field_number = ARGUMENT(2);
4885dfecf96Smrg    otupple = ARGUMENT(1);
4895dfecf96Smrg    result = ARGUMENT(0);
4905dfecf96Smrg
4915dfecf96Smrg    if (!CHECKO(result, PGresult_t))
4925dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
4935dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
4945dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
4955dfecf96Smrg
4965dfecf96Smrg    CHECK_INDEX(otupple);
4975dfecf96Smrg    tuple = FIXNUM_VALUE(otupple);
4985dfecf96Smrg
4995dfecf96Smrg    CHECK_INDEX(field_number);
5005dfecf96Smrg    field = FIXNUM_VALUE(field_number);
5015dfecf96Smrg
5025dfecf96Smrg    string = PQgetvalue(res, tuple, field);
5035dfecf96Smrg
5045dfecf96Smrg    if (type != UNSPEC) {
5055dfecf96Smrg	char *typestring;
5065dfecf96Smrg
5075dfecf96Smrg	CHECK_SYMBOL(type);
5085dfecf96Smrg	typestring = ATOMID(type);
5095dfecf96Smrg
5105dfecf96Smrg	if (strcmp(typestring, "INT16") == 0) {
5115dfecf96Smrg	    integer = *(short*)string;
5125dfecf96Smrg	    isint = 1;
5135dfecf96Smrg	    goto simple_type;
5145dfecf96Smrg	}
5155dfecf96Smrg	else if (strcmp(typestring, "INT32") == 0) {
5165dfecf96Smrg	    integer = *(int*)string;
5175dfecf96Smrg	    isint = 1;
5185dfecf96Smrg	    goto simple_type;
5195dfecf96Smrg	}
5205dfecf96Smrg	else if (strcmp(typestring, "FLOAT") == 0) {
5215dfecf96Smrg	    real = *(float*)string;
5225dfecf96Smrg	    isreal = 1;
5235dfecf96Smrg	    goto simple_type;
5245dfecf96Smrg	}
5255dfecf96Smrg	else if (strcmp(typestring, "REAL") == 0) {
5265dfecf96Smrg	    real = *(double*)string;
5275dfecf96Smrg	    isreal = 1;
5285dfecf96Smrg	    goto simple_type;
5295dfecf96Smrg	}
5305dfecf96Smrg	else if (strcmp(typestring, "PG-POLYGON") == 0)
5315dfecf96Smrg	    goto polygon_type;
5325dfecf96Smrg	else if (strcmp(typestring, "STRING") != 0)
5335dfecf96Smrg	    LispDestroy("%s: unknown type %s",
5345dfecf96Smrg			STRFUN(builtin), typestring);
5355dfecf96Smrg    }
5365dfecf96Smrg
5375dfecf96Smrgsimple_type:
5385dfecf96Smrg    return (isint ? INTEGER(integer) : isreal ? DFLOAT(real) :
5395dfecf96Smrg	    (string ? STRING(string) : NIL));
5405dfecf96Smrg
5415dfecf96Smrgpolygon_type:
5425dfecf96Smrg  {
5435dfecf96Smrg    LispObj *poly, *box, *p = NIL, *cdr, *obj;
5445dfecf96Smrg    POLYGON *polygon;
5455dfecf96Smrg    int i, size;
5465dfecf96Smrg
5475dfecf96Smrg    size = PQgetlength(res, tuple, field);
5485dfecf96Smrg    polygon = (POLYGON*)(string - sizeof(int));
5495dfecf96Smrg
5505dfecf96Smrg    GCDisable();
5515dfecf96Smrg    /* get polygon->boundbox */
5525dfecf96Smrg    cdr = EVAL(CONS(ATOM("MAKE-PG-POINT"),
5535dfecf96Smrg		    CONS(KEYWORD("X"),
5545dfecf96Smrg			 CONS(REAL(polygon->boundbox.high.x),
5555dfecf96Smrg			      CONS(KEYWORD("Y"),
5565dfecf96Smrg				   CONS(REAL(polygon->boundbox.high.y), NIL))))));
5575dfecf96Smrg    obj = EVAL(CONS(ATOM("MAKE-PG-POINT"),
5585dfecf96Smrg		    CONS(KEYWORD("X"),
5595dfecf96Smrg			 CONS(REAL(polygon->boundbox.low.x),
5605dfecf96Smrg			      CONS(KEYWORD("Y"),
5615dfecf96Smrg				   CONS(REAL(polygon->boundbox.low.y), NIL))))));
5625dfecf96Smrg    box = EVAL(CONS(ATOM("MAKE-PG-BOX"),
5635dfecf96Smrg		    CONS(KEYWORD("HIGH"),
5645dfecf96Smrg			 CONS(cdr,
5655dfecf96Smrg			      CONS(KEYWORD("LOW"),
5665dfecf96Smrg				   CONS(obj, NIL))))));
5675dfecf96Smrg    /* get polygon->p values */
5685dfecf96Smrg    for (i = 0; i < polygon->npts; i++) {
5695dfecf96Smrg	obj = EVAL(CONS(ATOM("MAKE-PG-POINT"),
5705dfecf96Smrg			CONS(KEYWORD("X"),
5715dfecf96Smrg			     CONS(REAL(polygon->p[i].x),
5725dfecf96Smrg			      CONS(KEYWORD("Y"),
5735dfecf96Smrg				   CONS(REAL(polygon->p[i].y), NIL))))));
5745dfecf96Smrg	if (i == 0)
5755dfecf96Smrg	    p = cdr = CONS(obj, NIL);
5765dfecf96Smrg	else {
5775dfecf96Smrg	    RPLACD(cdr, CONS(obj, NIL));
5785dfecf96Smrg	    cdr = CDR(cdr);
5795dfecf96Smrg	}
5805dfecf96Smrg    }
5815dfecf96Smrg
5825dfecf96Smrg    /* make result */
5835dfecf96Smrg    poly = EVAL(CONS(ATOM("MAKE-PG-POLYGON"),
5845dfecf96Smrg		     CONS(KEYWORD("SIZE"),
5855dfecf96Smrg			  CONS(REAL(size),
5865dfecf96Smrg			       CONS(KEYWORD("NUM-POINTS"),
5875dfecf96Smrg				    CONS(REAL(polygon->npts),
5885dfecf96Smrg					 CONS(KEYWORD("BOUNDBOX"),
5895dfecf96Smrg					      CONS(box,
5905dfecf96Smrg						   CONS(KEYWORD("POINTS"),
5915dfecf96Smrg							CONS(QUOTE(p), NIL))))))))));
5925dfecf96Smrg    GCEnable();
5935dfecf96Smrg
5945dfecf96Smrg    return (poly);
5955dfecf96Smrg  }
5965dfecf96Smrg}
5975dfecf96Smrg
5985dfecf96SmrgLispObj *
5995dfecf96SmrgLisp_PQhost(LispBuiltin *builtin)
6005dfecf96Smrg/*
6015dfecf96Smrg pq-host connection
6025dfecf96Smrg */
6035dfecf96Smrg{
6045dfecf96Smrg    char *string;
6055dfecf96Smrg    PGconn *conn;
6065dfecf96Smrg
6075dfecf96Smrg    LispObj *connection;
6085dfecf96Smrg
6095dfecf96Smrg    connection = ARGUMENT(0);
6105dfecf96Smrg
6115dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
6125dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
6135dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
6145dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
6155dfecf96Smrg
6165dfecf96Smrg    string = PQhost(conn);
6175dfecf96Smrg
6185dfecf96Smrg    return (string ? STRING(string) : NIL);
6195dfecf96Smrg}
6205dfecf96Smrg
6215dfecf96SmrgLispObj *
6225dfecf96SmrgLisp_PQnfields(LispBuiltin *builtin)
6235dfecf96Smrg/*
6245dfecf96Smrg pq-nfields result
6255dfecf96Smrg */
6265dfecf96Smrg{
6275dfecf96Smrg    int nfields;
6285dfecf96Smrg    PGresult *res;
6295dfecf96Smrg
6305dfecf96Smrg    LispObj *result;
6315dfecf96Smrg
6325dfecf96Smrg    result = ARGUMENT(0);
6335dfecf96Smrg
6345dfecf96Smrg    if (!CHECKO(result, PGresult_t))
6355dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
6365dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
6375dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
6385dfecf96Smrg
6395dfecf96Smrg    nfields = PQnfields(res);
6405dfecf96Smrg
6415dfecf96Smrg    return (INTEGER(nfields));
6425dfecf96Smrg}
6435dfecf96Smrg
6445dfecf96SmrgLispObj *
6455dfecf96SmrgLisp_PQnotifies(LispBuiltin *builtin)
6465dfecf96Smrg/*
6475dfecf96Smrg pq-notifies connection
6485dfecf96Smrg */
6495dfecf96Smrg{
6505dfecf96Smrg    LispObj *result, *code, *cod = COD;
6515dfecf96Smrg    PGconn *conn;
6525dfecf96Smrg    PGnotify *notifies;
6535dfecf96Smrg
6545dfecf96Smrg    LispObj *connection;
6555dfecf96Smrg
6565dfecf96Smrg    connection = ARGUMENT(0);
6575dfecf96Smrg
6585dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
6595dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
6605dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
6615dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
6625dfecf96Smrg
6635dfecf96Smrg    if ((notifies = PQnotifies(conn)) == NULL)
6645dfecf96Smrg	return (NIL);
6655dfecf96Smrg
6665dfecf96Smrg    GCDisable();
6675dfecf96Smrg    code = CONS(ATOM("MAKE-PG-NOTIFY"),
6685dfecf96Smrg		  CONS(KEYWORD("RELNAME"),
6695dfecf96Smrg		       CONS(STRING(notifies->relname),
6705dfecf96Smrg			    CONS(KEYWORD("BE-PID"),
6715dfecf96Smrg				 CONS(REAL(notifies->be_pid), NIL)))));
6725dfecf96Smrg    COD = CONS(code, COD);
6735dfecf96Smrg    GCEnable();
6745dfecf96Smrg    result = EVAL(code);
6755dfecf96Smrg    COD = cod;
6765dfecf96Smrg
6775dfecf96Smrg    free(notifies);
6785dfecf96Smrg
6795dfecf96Smrg    return (result);
6805dfecf96Smrg}
6815dfecf96Smrg
6825dfecf96SmrgLispObj *
6835dfecf96SmrgLisp_PQntuples(LispBuiltin *builtin)
6845dfecf96Smrg/*
6855dfecf96Smrg pq-ntuples result
6865dfecf96Smrg */
6875dfecf96Smrg{
6885dfecf96Smrg    int ntuples;
6895dfecf96Smrg    PGresult *res;
6905dfecf96Smrg
6915dfecf96Smrg    LispObj *result;
6925dfecf96Smrg
6935dfecf96Smrg    result = ARGUMENT(0);
6945dfecf96Smrg
6955dfecf96Smrg    if (!CHECKO(result, PGresult_t))
6965dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
6975dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
6985dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
6995dfecf96Smrg
7005dfecf96Smrg    ntuples = PQntuples(res);
7015dfecf96Smrg
7025dfecf96Smrg    return (INTEGER(ntuples));
7035dfecf96Smrg}
7045dfecf96Smrg
7055dfecf96SmrgLispObj *
7065dfecf96SmrgLisp_PQoptions(LispBuiltin *builtin)
7075dfecf96Smrg/*
7085dfecf96Smrg pq-options connection
7095dfecf96Smrg */
7105dfecf96Smrg{
7115dfecf96Smrg    char *string;
7125dfecf96Smrg    PGconn *conn;
7135dfecf96Smrg
7145dfecf96Smrg    LispObj *connection;
7155dfecf96Smrg
7165dfecf96Smrg    connection = ARGUMENT(0);
7175dfecf96Smrg
7185dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
7195dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
7205dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
7215dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
7225dfecf96Smrg
7235dfecf96Smrg    string = PQoptions(conn);
7245dfecf96Smrg
7255dfecf96Smrg    return (string ? STRING(string) : NIL);
7265dfecf96Smrg}
7275dfecf96Smrg
7285dfecf96SmrgLispObj *
7295dfecf96SmrgLisp_PQpass(LispBuiltin *builtin)
7305dfecf96Smrg/*
7315dfecf96Smrg pq-pass connection
7325dfecf96Smrg */
7335dfecf96Smrg{
7345dfecf96Smrg    char *string;
7355dfecf96Smrg    PGconn *conn;
7365dfecf96Smrg
7375dfecf96Smrg    LispObj *connection;
7385dfecf96Smrg
7395dfecf96Smrg    connection = ARGUMENT(0);
7405dfecf96Smrg
7415dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
7425dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
7435dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
7445dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
7455dfecf96Smrg
7465dfecf96Smrg    string = PQpass(conn);
7475dfecf96Smrg
7485dfecf96Smrg    return (string ? STRING(string) : NIL);
7495dfecf96Smrg}
7505dfecf96Smrg
7515dfecf96SmrgLispObj *
7525dfecf96SmrgLisp_PQport(LispBuiltin *builtin)
7535dfecf96Smrg/*
7545dfecf96Smrg pq-port connection
7555dfecf96Smrg */
7565dfecf96Smrg{
7575dfecf96Smrg    char *string;
7585dfecf96Smrg    PGconn *conn;
7595dfecf96Smrg
7605dfecf96Smrg    LispObj *connection;
7615dfecf96Smrg
7625dfecf96Smrg    connection = ARGUMENT(0);
7635dfecf96Smrg
7645dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
7655dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
7665dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
7675dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
7685dfecf96Smrg
7695dfecf96Smrg    string = PQport(conn);
7705dfecf96Smrg
7715dfecf96Smrg    return (string ? STRING(string) : NIL);
7725dfecf96Smrg}
7735dfecf96Smrg
7745dfecf96SmrgLispObj *
7755dfecf96SmrgLisp_PQresultStatus(LispBuiltin *builtin)
7765dfecf96Smrg/*
7775dfecf96Smrg pq-result-status result
7785dfecf96Smrg */
7795dfecf96Smrg{
7805dfecf96Smrg    int status;
7815dfecf96Smrg    PGresult *res;
7825dfecf96Smrg
7835dfecf96Smrg    LispObj *result;
7845dfecf96Smrg
7855dfecf96Smrg    result = ARGUMENT(0);
7865dfecf96Smrg
7875dfecf96Smrg    if (!CHECKO(result, PGresult_t))
7885dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGresult*",
7895dfecf96Smrg		    STRFUN(builtin), STROBJ(result));
7905dfecf96Smrg    res = (PGresult*)(result->data.opaque.data);
7915dfecf96Smrg
7925dfecf96Smrg    status = PQresultStatus(res);
7935dfecf96Smrg
7945dfecf96Smrg    return (INTEGER(status));
7955dfecf96Smrg}
7965dfecf96Smrg
7975dfecf96SmrgLispObj *
7985dfecf96SmrgLispPQsetdb(LispBuiltin *builtin, int loginp)
7995dfecf96Smrg/*
8005dfecf96Smrg pq-setdb host port options tty dbname
8015dfecf96Smrg pq-setdb-login host port options tty dbname login password
8025dfecf96Smrg */
8035dfecf96Smrg{
8045dfecf96Smrg    PGconn *conn;
8055dfecf96Smrg    char *host, *port, *options, *tty, *dbname, *login, *password;
8065dfecf96Smrg
8075dfecf96Smrg    LispObj *ohost, *oport, *ooptions, *otty, *odbname, *ologin, *opassword;
8085dfecf96Smrg
8095dfecf96Smrg    if (loginp) {
8105dfecf96Smrg	opassword = ARGUMENT(6);
8115dfecf96Smrg	ologin = ARGUMENT(5);
8125dfecf96Smrg    }
8135dfecf96Smrg    else
8145dfecf96Smrg	opassword = ologin = NIL;
8155dfecf96Smrg    odbname = ARGUMENT(4);
8165dfecf96Smrg    otty = ARGUMENT(3);
8175dfecf96Smrg    ooptions = ARGUMENT(2);
8185dfecf96Smrg    oport = ARGUMENT(1);
8195dfecf96Smrg    ohost = ARGUMENT(0);
8205dfecf96Smrg
8215dfecf96Smrg    if (ohost != NIL) {
8225dfecf96Smrg	CHECK_STRING(ohost);
8235dfecf96Smrg	host = THESTR(ohost);
8245dfecf96Smrg    }
8255dfecf96Smrg    else
8265dfecf96Smrg	host = NULL;
8275dfecf96Smrg
8285dfecf96Smrg    if (oport != NIL) {
8295dfecf96Smrg	CHECK_STRING(oport);
8305dfecf96Smrg	port = THESTR(oport);
8315dfecf96Smrg    }
8325dfecf96Smrg    else
8335dfecf96Smrg	port = NULL;
8345dfecf96Smrg
8355dfecf96Smrg    if (ooptions != NIL) {
8365dfecf96Smrg	CHECK_STRING(ooptions);
8375dfecf96Smrg	options = THESTR(ooptions);
8385dfecf96Smrg    }
8395dfecf96Smrg    else
8405dfecf96Smrg	options = NULL;
8415dfecf96Smrg
8425dfecf96Smrg    if (otty != NIL) {
8435dfecf96Smrg	CHECK_STRING(otty);
8445dfecf96Smrg	tty = THESTR(otty);
8455dfecf96Smrg    }
8465dfecf96Smrg    else
8475dfecf96Smrg	tty = NULL;
8485dfecf96Smrg
8495dfecf96Smrg    if (odbname != NIL) {
8505dfecf96Smrg	CHECK_STRING(odbname);
8515dfecf96Smrg	dbname = THESTR(odbname);
8525dfecf96Smrg    }
8535dfecf96Smrg    else
8545dfecf96Smrg	dbname = NULL;
8555dfecf96Smrg
8565dfecf96Smrg    if (ologin != NIL) {
8575dfecf96Smrg	CHECK_STRING(ologin);
8585dfecf96Smrg	login = THESTR(ologin);
8595dfecf96Smrg    }
8605dfecf96Smrg    else
8615dfecf96Smrg	login = NULL;
8625dfecf96Smrg
8635dfecf96Smrg    if (opassword != NIL) {
8645dfecf96Smrg	CHECK_STRING(opassword);
8655dfecf96Smrg	password = THESTR(opassword);
8665dfecf96Smrg    }
8675dfecf96Smrg    else
8685dfecf96Smrg	password = NULL;
8695dfecf96Smrg
8705dfecf96Smrg    conn = PQsetdbLogin(host, port, options, tty, dbname, login, password);
8715dfecf96Smrg
8725dfecf96Smrg    return (conn ? OPAQUE(conn, PGconn_t) : NIL);
8735dfecf96Smrg}
8745dfecf96Smrg
8755dfecf96SmrgLispObj *
8765dfecf96SmrgLisp_PQsetdb(LispBuiltin *builtin)
8775dfecf96Smrg/*
8785dfecf96Smrg pq-setdb host port options tty dbname
8795dfecf96Smrg */
8805dfecf96Smrg{
8815dfecf96Smrg    return (LispPQsetdb(builtin, 0));
8825dfecf96Smrg}
8835dfecf96Smrg
8845dfecf96SmrgLispObj *
8855dfecf96SmrgLisp_PQsetdbLogin(LispBuiltin *builtin)
8865dfecf96Smrg/*
8875dfecf96Smrg pq-setdb-login host port options tty dbname login password
8885dfecf96Smrg */
8895dfecf96Smrg{
8905dfecf96Smrg    return (LispPQsetdb(builtin, 1));
8915dfecf96Smrg}
8925dfecf96Smrg
8935dfecf96SmrgLispObj *
8945dfecf96SmrgLisp_PQsocket(LispBuiltin *builtin)
8955dfecf96Smrg/*
8965dfecf96Smrg pq-socket connection
8975dfecf96Smrg */
8985dfecf96Smrg{
8995dfecf96Smrg    int sock;
9005dfecf96Smrg    PGconn *conn;
9015dfecf96Smrg
9025dfecf96Smrg    LispObj *connection;
9035dfecf96Smrg
9045dfecf96Smrg    connection = ARGUMENT(0);
9055dfecf96Smrg
9065dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
9075dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
9085dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
9095dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
9105dfecf96Smrg
9115dfecf96Smrg    sock = PQsocket(conn);
9125dfecf96Smrg
9135dfecf96Smrg    return (INTEGER(sock));
9145dfecf96Smrg}
9155dfecf96Smrg
9165dfecf96SmrgLispObj *
9175dfecf96SmrgLisp_PQstatus(LispBuiltin *builtin)
9185dfecf96Smrg/*
9195dfecf96Smrg pq-status connection
9205dfecf96Smrg */
9215dfecf96Smrg{
9225dfecf96Smrg    int status;
9235dfecf96Smrg    PGconn *conn;
9245dfecf96Smrg
9255dfecf96Smrg    LispObj *connection;
9265dfecf96Smrg
9275dfecf96Smrg    connection = ARGUMENT(0);
9285dfecf96Smrg
9295dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
9305dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
9315dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
9325dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
9335dfecf96Smrg
9345dfecf96Smrg    status = PQstatus(conn);
9355dfecf96Smrg
9365dfecf96Smrg    return (INTEGER(status));
9375dfecf96Smrg}
9385dfecf96Smrg
9395dfecf96SmrgLispObj *
9405dfecf96SmrgLisp_PQtty(LispBuiltin *builtin)
9415dfecf96Smrg/*
9425dfecf96Smrg pq-tty connection
9435dfecf96Smrg */
9445dfecf96Smrg{
9455dfecf96Smrg    char *string;
9465dfecf96Smrg    PGconn *conn;
9475dfecf96Smrg
9485dfecf96Smrg    LispObj *connection;
9495dfecf96Smrg
9505dfecf96Smrg    connection = ARGUMENT(0);
9515dfecf96Smrg
9525dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
9535dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
9545dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
9555dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
9565dfecf96Smrg
9575dfecf96Smrg    string = PQtty(conn);
9585dfecf96Smrg
9595dfecf96Smrg    return (string ? STRING(string) : NIL);
9605dfecf96Smrg}
9615dfecf96Smrg
9625dfecf96SmrgLispObj *
9635dfecf96SmrgLisp_PQuser(LispBuiltin *builtin)
9645dfecf96Smrg/*
9655dfecf96Smrg pq-user connection
9665dfecf96Smrg */
9675dfecf96Smrg{
9685dfecf96Smrg    char *string;
9695dfecf96Smrg    PGconn *conn;
9705dfecf96Smrg
9715dfecf96Smrg    LispObj *connection;
9725dfecf96Smrg
9735dfecf96Smrg    connection = ARGUMENT(0);
9745dfecf96Smrg
9755dfecf96Smrg    if (!CHECKO(connection, PGconn_t))
9765dfecf96Smrg	LispDestroy("%s: cannot convert %s to PGconn*",
9775dfecf96Smrg		    STRFUN(builtin), STROBJ(connection));
9785dfecf96Smrg    conn = (PGconn*)(connection->data.opaque.data);
9795dfecf96Smrg
9805dfecf96Smrg    string = PQuser(conn);
9815dfecf96Smrg
9825dfecf96Smrg    return (string ? STRING(string) : NIL);
9835dfecf96Smrg}
984