xenocara/app/xedit/lisp/modules/psql.c
2006-11-25 20:07:29 +00:00

984 lines
22 KiB
C

/*
* Copyright (c) 2001 by The XFree86 Project, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the XFree86 Project shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the
* XFree86 Project.
*
* Author: Paulo César Pereira de Andrade
*/
/* $XFree86: xc/programs/xedit/lisp/modules/psql.c,v 1.12tsi Exp $ */
#include <stdlib.h>
#include <libpq-fe.h>
#undef USE_SSL /* cannot get it to compile... */
#include <postgres.h>
#include <utils/geo_decls.h>
#include "lisp/internal.h"
#include "lisp/private.h"
/*
* Prototypes
*/
int psqlLoadModule(void);
LispObj *Lisp_PQbackendPID(LispBuiltin*);
LispObj *Lisp_PQclear(LispBuiltin*);
LispObj *Lisp_PQconsumeInput(LispBuiltin*);
LispObj *Lisp_PQdb(LispBuiltin*);
LispObj *Lisp_PQerrorMessage(LispBuiltin*);
LispObj *Lisp_PQexec(LispBuiltin*);
LispObj *Lisp_PQfinish(LispBuiltin*);
LispObj *Lisp_PQfname(LispBuiltin*);
LispObj *Lisp_PQfnumber(LispBuiltin*);
LispObj *Lisp_PQfsize(LispBuiltin*);
LispObj *Lisp_PQftype(LispBuiltin*);
LispObj *Lisp_PQgetlength(LispBuiltin*);
LispObj *Lisp_PQgetvalue(LispBuiltin*);
LispObj *Lisp_PQhost(LispBuiltin*);
LispObj *Lisp_PQnfields(LispBuiltin*);
LispObj *Lisp_PQnotifies(LispBuiltin*);
LispObj *Lisp_PQntuples(LispBuiltin*);
LispObj *Lisp_PQoptions(LispBuiltin*);
LispObj *Lisp_PQpass(LispBuiltin*);
LispObj *Lisp_PQport(LispBuiltin*);
LispObj *Lisp_PQresultStatus(LispBuiltin*);
LispObj *Lisp_PQsetdb(LispBuiltin*);
LispObj *Lisp_PQsetdbLogin(LispBuiltin*);
LispObj *Lisp_PQsocket(LispBuiltin*);
LispObj *Lisp_PQstatus(LispBuiltin*);
LispObj *Lisp_PQtty(LispBuiltin*);
LispObj *Lisp_PQuser(LispBuiltin*);
/*
* Initialization
*/
static LispBuiltin lispbuiltins[] = {
{LispFunction, Lisp_PQbackendPID, "pq-backend-pid connection"},
{LispFunction, Lisp_PQclear, "pq-clear result"},
{LispFunction, Lisp_PQconsumeInput, "pq-consume-input connection"},
{LispFunction, Lisp_PQdb, "pq-db connection"},
{LispFunction, Lisp_PQerrorMessage, "pq-error-message connection"},
{LispFunction, Lisp_PQexec, "pq-exec connection query"},
{LispFunction, Lisp_PQfinish, "pq-finish connection"},
{LispFunction, Lisp_PQfname, "pq-fname result field-number"},
{LispFunction, Lisp_PQfnumber, "pq-fnumber result field-name"},
{LispFunction, Lisp_PQfsize, "pq-fsize result field-number"},
{LispFunction, Lisp_PQftype, "pq-ftype result field-number"},
{LispFunction, Lisp_PQgetlength, "pq-getlength result tupple field-number"},
{LispFunction, Lisp_PQgetvalue, "pq-getvalue result tupple field-number &optional type"},
{LispFunction, Lisp_PQhost, "pq-host connection"},
{LispFunction, Lisp_PQnfields, "pq-nfields result"},
{LispFunction, Lisp_PQnotifies, "pq-notifies connection"},
{LispFunction, Lisp_PQntuples, "pq-ntuples result"},
{LispFunction, Lisp_PQoptions, "pq-options connection"},
{LispFunction, Lisp_PQpass, "pq-pass connection"},
{LispFunction, Lisp_PQport, "pq-port connection"},
{LispFunction, Lisp_PQresultStatus, "pq-result-status result"},
{LispFunction, Lisp_PQsetdb, "pq-setdb host port options tty dbname"},
{LispFunction, Lisp_PQsetdbLogin, "pq-setdb-login host port options tty dbname login password"},
{LispFunction, Lisp_PQsocket, "pq-socket connection"},
{LispFunction, Lisp_PQstatus, "pq-status connection"},
{LispFunction, Lisp_PQtty, "pq-tty connection"},
{LispFunction, Lisp_PQuser, "pq-user connection"},
};
LispModuleData psqlLispModuleData = {
LISP_MODULE_VERSION,
psqlLoadModule
};
static int PGconn_t, PGresult_t;
/*
* Implementation
*/
int
psqlLoadModule(void)
{
int i;
char *fname = "PSQL-LOAD-MODULE";
PGconn_t = LispRegisterOpaqueType("PGconn*");
PGresult_t = LispRegisterOpaqueType("PGresult*");
GCDisable();
/* NOTE: Implemented just enough to make programming examples
* (and my needs) work.
* Completing this is an exercise to the reader, or may be implemented
* when/if required.
*/
LispExecute("(DEFSTRUCT PG-NOTIFY RELNAME BE-PID)\n"
"(DEFSTRUCT PG-POINT X Y)\n"
"(DEFSTRUCT PG-BOX HIGH LOW)\n"
"(DEFSTRUCT PG-POLYGON SIZE NUM-POINTS BOUNDBOX POINTS)\n");
/* enum ConnStatusType */
(void)LispSetVariable(ATOM2("PG-CONNECTION-OK"),
REAL(CONNECTION_OK), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-BAD"),
REAL(CONNECTION_BAD), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-STARTED"),
REAL(CONNECTION_STARTED), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-MADE"),
REAL(CONNECTION_MADE), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-AWAITING-RESPONSE"),
REAL(CONNECTION_AWAITING_RESPONSE), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-AUTH-OK"),
REAL(CONNECTION_AUTH_OK), fname, 0);
(void)LispSetVariable(ATOM2("PG-CONNECTION-SETENV"),
REAL(CONNECTION_SETENV), fname, 0);
/* enum ExecStatusType */
(void)LispSetVariable(ATOM2("PGRES-EMPTY-QUERY"),
REAL(PGRES_EMPTY_QUERY), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-COMMAND-OK"),
REAL(PGRES_COMMAND_OK), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-TUPLES-OK"),
REAL(PGRES_TUPLES_OK), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-COPY-OUT"),
REAL(PGRES_COPY_OUT), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-COPY-IN"),
REAL(PGRES_COPY_IN), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-BAD-RESPONSE"),
REAL(PGRES_BAD_RESPONSE), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-NONFATAL-ERROR"),
REAL(PGRES_NONFATAL_ERROR), fname, 0);
(void)LispSetVariable(ATOM2("PGRES-FATAL-ERROR"),
REAL(PGRES_FATAL_ERROR), fname, 0);
GCEnable();
for (i = 0; i < sizeof(lispbuiltins) / sizeof(lispbuiltins[0]); i++)
LispAddBuiltinFunction(&lispbuiltins[i]);
return (1);
}
LispObj *
Lisp_PQbackendPID(LispBuiltin *builtin)
/*
pq-backend-pid connection
*/
{
int pid;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
pid = PQbackendPID(conn);
return (INTEGER(pid));
}
LispObj *
Lisp_PQclear(LispBuiltin *builtin)
/*
pq-clear result
*/
{
PGresult *res;
LispObj *result;
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
PQclear(res);
return (NIL);
}
LispObj *
Lisp_PQconsumeInput(LispBuiltin *builtin)
/*
pq-consume-input connection
*/
{
int result;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
result = PQconsumeInput(conn);
return (INTEGER(result));
}
LispObj *
Lisp_PQdb(LispBuiltin *builtin)
/*
pq-db connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQdb(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQerrorMessage(LispBuiltin *builtin)
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQerrorMessage(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQexec(LispBuiltin *builtin)
/*
pq-exec connection query
*/
{
PGconn *conn;
PGresult *res;
LispObj *connection, *query;
query = ARGUMENT(1);
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
CHECK_STRING(query);
res = PQexec(conn, THESTR(query));
return (res ? OPAQUE(res, PGresult_t) : NIL);
}
LispObj *
Lisp_PQfinish(LispBuiltin *builtin)
/*
pq-finish connection
*/
{
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
PQfinish(conn);
return (NIL);
}
LispObj *
Lisp_PQfname(LispBuiltin *builtin)
/*
pq-fname result field-number
*/
{
char *string;
int field;
PGresult *res;
LispObj *result, *field_number;
field_number = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_INDEX(field_number);
field = FIXNUM_VALUE(field_number);
string = PQfname(res, field);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQfnumber(LispBuiltin *builtin)
/*
pq-fnumber result field-name
*/
{
int number;
int field;
PGresult *res;
LispObj *result, *field_name;
field_name = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_STRING(field_name);
number = PQfnumber(res, THESTR(field_name));
return (INTEGER(number));
}
LispObj *
Lisp_PQfsize(LispBuiltin *builtin)
/*
pq-fsize result field-number
*/
{
int size, field;
PGresult *res;
LispObj *result, *field_number;
field_number = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_INDEX(field_number);
field = FIXNUM_VALUE(field_number);
size = PQfsize(res, field);
return (INTEGER(size));
}
LispObj *
Lisp_PQftype(LispBuiltin *builtin)
{
Oid oid;
int field;
PGresult *res;
LispObj *result, *field_number;
field_number = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_INDEX(field_number);
field = FIXNUM_VALUE(field_number);
oid = PQftype(res, field);
return (INTEGER(oid));
}
LispObj *
Lisp_PQgetlength(LispBuiltin *builtin)
/*
pq-getlength result tupple field-number
*/
{
PGresult *res;
int tuple, field, length;
LispObj *result, *otupple, *field_number;
field_number = ARGUMENT(2);
otupple = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_INDEX(otupple);
tuple = FIXNUM_VALUE(otupple);
CHECK_INDEX(field_number);
field = FIXNUM_VALUE(field_number);
length = PQgetlength(res, tuple, field);
return (INTEGER(length));
}
LispObj *
Lisp_PQgetvalue(LispBuiltin *builtin)
/*
pq-getvalue result tuple field &optional type-specifier
*/
{
char *string;
double real = 0.0;
PGresult *res;
int tuple, field, isint = 0, isreal = 0, integer;
LispObj *result, *otupple, *field_number, *type;
type = ARGUMENT(3);
field_number = ARGUMENT(2);
otupple = ARGUMENT(1);
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
CHECK_INDEX(otupple);
tuple = FIXNUM_VALUE(otupple);
CHECK_INDEX(field_number);
field = FIXNUM_VALUE(field_number);
string = PQgetvalue(res, tuple, field);
if (type != UNSPEC) {
char *typestring;
CHECK_SYMBOL(type);
typestring = ATOMID(type);
if (strcmp(typestring, "INT16") == 0) {
integer = *(short*)string;
isint = 1;
goto simple_type;
}
else if (strcmp(typestring, "INT32") == 0) {
integer = *(int*)string;
isint = 1;
goto simple_type;
}
else if (strcmp(typestring, "FLOAT") == 0) {
real = *(float*)string;
isreal = 1;
goto simple_type;
}
else if (strcmp(typestring, "REAL") == 0) {
real = *(double*)string;
isreal = 1;
goto simple_type;
}
else if (strcmp(typestring, "PG-POLYGON") == 0)
goto polygon_type;
else if (strcmp(typestring, "STRING") != 0)
LispDestroy("%s: unknown type %s",
STRFUN(builtin), typestring);
}
simple_type:
return (isint ? INTEGER(integer) : isreal ? DFLOAT(real) :
(string ? STRING(string) : NIL));
polygon_type:
{
LispObj *poly, *box, *p = NIL, *cdr, *obj;
POLYGON *polygon;
int i, size;
size = PQgetlength(res, tuple, field);
polygon = (POLYGON*)(string - sizeof(int));
GCDisable();
/* get polygon->boundbox */
cdr = EVAL(CONS(ATOM("MAKE-PG-POINT"),
CONS(KEYWORD("X"),
CONS(REAL(polygon->boundbox.high.x),
CONS(KEYWORD("Y"),
CONS(REAL(polygon->boundbox.high.y), NIL))))));
obj = EVAL(CONS(ATOM("MAKE-PG-POINT"),
CONS(KEYWORD("X"),
CONS(REAL(polygon->boundbox.low.x),
CONS(KEYWORD("Y"),
CONS(REAL(polygon->boundbox.low.y), NIL))))));
box = EVAL(CONS(ATOM("MAKE-PG-BOX"),
CONS(KEYWORD("HIGH"),
CONS(cdr,
CONS(KEYWORD("LOW"),
CONS(obj, NIL))))));
/* get polygon->p values */
for (i = 0; i < polygon->npts; i++) {
obj = EVAL(CONS(ATOM("MAKE-PG-POINT"),
CONS(KEYWORD("X"),
CONS(REAL(polygon->p[i].x),
CONS(KEYWORD("Y"),
CONS(REAL(polygon->p[i].y), NIL))))));
if (i == 0)
p = cdr = CONS(obj, NIL);
else {
RPLACD(cdr, CONS(obj, NIL));
cdr = CDR(cdr);
}
}
/* make result */
poly = EVAL(CONS(ATOM("MAKE-PG-POLYGON"),
CONS(KEYWORD("SIZE"),
CONS(REAL(size),
CONS(KEYWORD("NUM-POINTS"),
CONS(REAL(polygon->npts),
CONS(KEYWORD("BOUNDBOX"),
CONS(box,
CONS(KEYWORD("POINTS"),
CONS(QUOTE(p), NIL))))))))));
GCEnable();
return (poly);
}
}
LispObj *
Lisp_PQhost(LispBuiltin *builtin)
/*
pq-host connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQhost(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQnfields(LispBuiltin *builtin)
/*
pq-nfields result
*/
{
int nfields;
PGresult *res;
LispObj *result;
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
nfields = PQnfields(res);
return (INTEGER(nfields));
}
LispObj *
Lisp_PQnotifies(LispBuiltin *builtin)
/*
pq-notifies connection
*/
{
LispObj *result, *code, *cod = COD;
PGconn *conn;
PGnotify *notifies;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
if ((notifies = PQnotifies(conn)) == NULL)
return (NIL);
GCDisable();
code = CONS(ATOM("MAKE-PG-NOTIFY"),
CONS(KEYWORD("RELNAME"),
CONS(STRING(notifies->relname),
CONS(KEYWORD("BE-PID"),
CONS(REAL(notifies->be_pid), NIL)))));
COD = CONS(code, COD);
GCEnable();
result = EVAL(code);
COD = cod;
free(notifies);
return (result);
}
LispObj *
Lisp_PQntuples(LispBuiltin *builtin)
/*
pq-ntuples result
*/
{
int ntuples;
PGresult *res;
LispObj *result;
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
ntuples = PQntuples(res);
return (INTEGER(ntuples));
}
LispObj *
Lisp_PQoptions(LispBuiltin *builtin)
/*
pq-options connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQoptions(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQpass(LispBuiltin *builtin)
/*
pq-pass connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQpass(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQport(LispBuiltin *builtin)
/*
pq-port connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQport(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQresultStatus(LispBuiltin *builtin)
/*
pq-result-status result
*/
{
int status;
PGresult *res;
LispObj *result;
result = ARGUMENT(0);
if (!CHECKO(result, PGresult_t))
LispDestroy("%s: cannot convert %s to PGresult*",
STRFUN(builtin), STROBJ(result));
res = (PGresult*)(result->data.opaque.data);
status = PQresultStatus(res);
return (INTEGER(status));
}
LispObj *
LispPQsetdb(LispBuiltin *builtin, int loginp)
/*
pq-setdb host port options tty dbname
pq-setdb-login host port options tty dbname login password
*/
{
PGconn *conn;
char *host, *port, *options, *tty, *dbname, *login, *password;
LispObj *ohost, *oport, *ooptions, *otty, *odbname, *ologin, *opassword;
if (loginp) {
opassword = ARGUMENT(6);
ologin = ARGUMENT(5);
}
else
opassword = ologin = NIL;
odbname = ARGUMENT(4);
otty = ARGUMENT(3);
ooptions = ARGUMENT(2);
oport = ARGUMENT(1);
ohost = ARGUMENT(0);
if (ohost != NIL) {
CHECK_STRING(ohost);
host = THESTR(ohost);
}
else
host = NULL;
if (oport != NIL) {
CHECK_STRING(oport);
port = THESTR(oport);
}
else
port = NULL;
if (ooptions != NIL) {
CHECK_STRING(ooptions);
options = THESTR(ooptions);
}
else
options = NULL;
if (otty != NIL) {
CHECK_STRING(otty);
tty = THESTR(otty);
}
else
tty = NULL;
if (odbname != NIL) {
CHECK_STRING(odbname);
dbname = THESTR(odbname);
}
else
dbname = NULL;
if (ologin != NIL) {
CHECK_STRING(ologin);
login = THESTR(ologin);
}
else
login = NULL;
if (opassword != NIL) {
CHECK_STRING(opassword);
password = THESTR(opassword);
}
else
password = NULL;
conn = PQsetdbLogin(host, port, options, tty, dbname, login, password);
return (conn ? OPAQUE(conn, PGconn_t) : NIL);
}
LispObj *
Lisp_PQsetdb(LispBuiltin *builtin)
/*
pq-setdb host port options tty dbname
*/
{
return (LispPQsetdb(builtin, 0));
}
LispObj *
Lisp_PQsetdbLogin(LispBuiltin *builtin)
/*
pq-setdb-login host port options tty dbname login password
*/
{
return (LispPQsetdb(builtin, 1));
}
LispObj *
Lisp_PQsocket(LispBuiltin *builtin)
/*
pq-socket connection
*/
{
int sock;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
sock = PQsocket(conn);
return (INTEGER(sock));
}
LispObj *
Lisp_PQstatus(LispBuiltin *builtin)
/*
pq-status connection
*/
{
int status;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
status = PQstatus(conn);
return (INTEGER(status));
}
LispObj *
Lisp_PQtty(LispBuiltin *builtin)
/*
pq-tty connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQtty(conn);
return (string ? STRING(string) : NIL);
}
LispObj *
Lisp_PQuser(LispBuiltin *builtin)
/*
pq-user connection
*/
{
char *string;
PGconn *conn;
LispObj *connection;
connection = ARGUMENT(0);
if (!CHECKO(connection, PGconn_t))
LispDestroy("%s: cannot convert %s to PGconn*",
STRFUN(builtin), STROBJ(connection));
conn = (PGconn*)(connection->data.opaque.data);
string = PQuser(conn);
return (string ? STRING(string) : NIL);
}