Commit 552620c8 authored by Marc G. Fournier's avatar Marc G. Fournier

Changes to libpgtcl submitted by: wieck@sapserv.debis.de (Jan Wieck)

Adds:

    -lAttributes

        Returns another format of the results attribute list. Per
        attribute a sublist  of  {{attname}  atttype  attlen}  is
        returned  and  an  empty  string  if  no attributes where
        received.

    -numAttrs

        Returns the number of attributes in the result.
parent 582982e6
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# #
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/Makefile,v 1.2 1996/07/23 03:38:42 scrappy Exp $ # $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/Makefile,v 1.3 1996/10/30 06:18:36 scrappy Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -23,6 +23,8 @@ CFLAGS+= -I$(HEADERDIR) \ ...@@ -23,6 +23,8 @@ CFLAGS+= -I$(HEADERDIR) \
-I$(TCL_INCDIR) \ -I$(TCL_INCDIR) \
-I$(srcdir)/libpq -I$(srcdir)/libpq
LIBLDLIBS+= -L$(LIBDIR) -lpq
ifdef KRBVERS ifdef KRBVERS
CFLAGS+= $(KRBFLAGS) CFLAGS+= $(KRBFLAGS)
endif endif
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpgtcl.h,v 1.1.1.1 1996/07/09 06:22:16 scrappy Exp $ * $Id: libpgtcl.h,v 1.2 1996/10/30 06:18:37 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "tcl.h" #include "tcl.h"
extern int Pg_Init (Tcl_Interp *interp); extern int Pgtcl_Init (Tcl_Interp *interp);
extern int Pgtcl_SafeInit (Tcl_Interp *interp);
#endif /* LIBPGTCL_H */ #endif /* LIBPGTCL_H */
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.2 1996/10/07 21:19:06 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.3 1996/10/30 06:18:38 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,92 +19,145 @@ ...@@ -19,92 +19,145 @@
#include "pgtclCmds.h" #include "pgtclCmds.h"
/* /*
* PG_Init * Pgtcl_Init
* initialization package for the PGLITE Tcl package * initialization package for the PGLITE Tcl package
* *
*/ */
/*
* Tidy up forgotten postgres connection at Tcl_Exit
*/
void
Pgtcl_AtExit (ClientData cData)
{
Pg_clientData *cd = (Pg_clientData *)cData;
Tcl_HashEntry *hent;
Tcl_HashSearch hsearch;
Pg_ConnectionId *connid;
PGconn *conn;
while((hent = Tcl_FirstHashEntry(&(cd->dbh_hash), &hsearch)) != NULL) {
connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
conn = connid->conn;
PgDelConnectionId(cd, connid->id);
PQfinish(conn);
}
Tcl_DeleteHashTable(&(cd->dbh_hash));
Tcl_DeleteHashTable(&(cd->res_hash));
Tcl_DeleteExitHandler(Pgtcl_AtExit, cData);
}
/*
* Tidy up forgotten postgres connections on Interpreter deletion
*/
void
Pgtcl_Shutdown (ClientData cData, Tcl_Interp *interp)
{
Pgtcl_AtExit(cData);
}
int int
Pg_Init (Tcl_Interp *interp) Pgtcl_Init (Tcl_Interp *interp)
{ {
/* register all pgtcl commands */ Pg_clientData *cd;
/* Create and initialize the client data area */
cd = (Pg_clientData *)ckalloc(sizeof(Pg_clientData));
Tcl_InitHashTable(&(cd->dbh_hash), TCL_STRING_KEYS);
Tcl_InitHashTable(&(cd->res_hash), TCL_STRING_KEYS);
cd->dbh_count = 0L;
cd->res_count = 0L;
/* Arrange for tidy up when interpreter is deleted or Tcl exits */
Tcl_CallWhenDeleted(interp, Pgtcl_Shutdown, (ClientData)cd);
Tcl_CreateExitHandler(Pgtcl_AtExit, (ClientData)cd);
/* register all pgtcl commands */
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_connect", "pg_connect",
Pg_connect, Pg_connect,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_disconnect", "pg_disconnect",
Pg_disconnect, Pg_disconnect,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_exec", "pg_exec",
Pg_exec, Pg_exec,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_select", "pg_select",
Pg_select, Pg_select,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_result", "pg_result",
Pg_result, Pg_result,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_open", "pg_lo_open",
Pg_lo_open, Pg_lo_open,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_close", "pg_lo_close",
Pg_lo_close, Pg_lo_close,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_read", "pg_lo_read",
Pg_lo_read, Pg_lo_read,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_write", "pg_lo_write",
Pg_lo_write, Pg_lo_write,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_lseek", "pg_lo_lseek",
Pg_lo_lseek, Pg_lo_lseek,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_creat", "pg_lo_creat",
Pg_lo_creat, Pg_lo_creat,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_tell", "pg_lo_tell",
Pg_lo_tell, Pg_lo_tell,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_unlink", "pg_lo_unlink",
Pg_lo_unlink, Pg_lo_unlink,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_import", "pg_lo_import",
Pg_lo_import, Pg_lo_import,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_lo_export", "pg_lo_export",
Pg_lo_export, Pg_lo_export,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_PkgProvide(interp, "Pgtcl", "1.0");
return TCL_OK; return TCL_OK;
} }
int
Pgtcl_SafeInit (Tcl_Interp *interp)
{
return Pgtcl_Init(interp);
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.4 1996/10/07 21:19:07 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.5 1996/10/30 06:18:39 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -224,6 +224,7 @@ tcl_value (char *value) ...@@ -224,6 +224,7 @@ tcl_value (char *value)
int int
Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
char *pghost = NULL; char *pghost = NULL;
char *pgtty = NULL; char *pgtty = NULL;
char *pgport = NULL; char *pgport = NULL;
...@@ -277,7 +278,7 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -277,7 +278,7 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
if (conn->status == CONNECTION_OK) { if (conn->status == CONNECTION_OK) {
PgSetId(interp->result, (void*)conn); PgSetConnectionId(cd, interp->result, conn);
return TCL_OK; return TCL_OK;
} }
else { else {
...@@ -302,21 +303,21 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -302,21 +303,21 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
if (argc != 2) { if (argc != 2) {
Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_disconnect connection", 0); Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_disconnect connection", 0);
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName); PgDelConnectionId(cd, argv[1]);
PQfinish(conn); PQfinish(conn);
return TCL_OK; return TCL_OK;
} }
...@@ -335,26 +336,25 @@ Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -335,26 +336,25 @@ Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
PGresult *result; PGresult *result;
char* connPtrName;
if (argc != 3) { if (argc != 3) {
Tcl_AppendResult(interp, "Wrong # of arguments\n", Tcl_AppendResult(interp, "Wrong # of arguments\n",
"pg_exec connection queryString", 0); "pg_exec connection queryString", 0);
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1];
if (! PgValidId(connPtrName)) { conn = PgGetConnectionId(cd, argv[1]);
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
result = PQexec(conn, argv[2]); result = PQexec(conn, argv[2]);
if (result) { if (result) {
PgSetId(interp->result, (void*)result); PgSetResultId(cd, interp->result, argv[1], result);
return TCL_OK; return TCL_OK;
} }
else { else {
...@@ -386,6 +386,10 @@ Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -386,6 +386,10 @@ Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[])
the number of tuples in the query the number of tuples in the query
-attributes -attributes
returns a list of the name/type pairs of the tuple attributes returns a list of the name/type pairs of the tuple attributes
-lAttributes
returns a list of the {name type len} entries of the tuple attributes
-numAttrs
returns the number of attributes returned by the query
-getTuple tupleNumber -getTuple tupleNumber
returns the values of the tuple in a list returns the values of the tuple in a list
-clear -clear
...@@ -394,7 +398,7 @@ Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -394,7 +398,7 @@ Pg_exec(AlientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
char* resultPtrName; Pg_clientData *cd = (Pg_clientData *)cData;
PGresult *result; PGresult *result;
char *opt; char *opt;
int i; int i;
...@@ -408,13 +412,12 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -408,13 +412,12 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
goto Pg_result_errReturn; goto Pg_result_errReturn;
} }
resultPtrName = argv[1]; result = PgGetResultId(cd, argv[1]);
if (! PgValidId(resultPtrName)) { if (result == (PGresult *)NULL) {
Tcl_AppendResult(interp, "First argument is not a valid query result\n", 0); Tcl_AppendResult(interp, "First argument is not a valid query result\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
result = (PGresult*)PgGetId(resultPtrName);
opt = argv[2]; opt = argv[2];
if (strcmp(opt, "-status") == 0) { if (strcmp(opt, "-status") == 0) {
...@@ -426,10 +429,11 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -426,10 +429,11 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_OK; return TCL_OK;
} }
else if (strcmp(opt, "-conn") == 0) { else if (strcmp(opt, "-conn") == 0) {
PgSetId(interp->result, (void*)result->conn); PgGetConnByResultId(cd, interp->result, argv[1]);
return TCL_OK; return TCL_OK;
} }
else if (strcmp(opt, "-clear") == 0) { else if (strcmp(opt, "-clear") == 0) {
PgDelResultId(cd, argv[1]);
PQclear(result); PQclear(result);
return TCL_OK; return TCL_OK;
} }
...@@ -516,6 +520,21 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -516,6 +520,21 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
} }
return TCL_OK; return TCL_OK;
} }
else if (strcmp(opt, "-lAttributes") == 0) {
char buf[512];
Tcl_ResetResult(interp);
for (i = 0; i < PQnfields(result); i++) {
sprintf(buf, "{%s} %ld %d", PQfname(result, i),
PQftype(result, i),
PQfsize(result, i));
Tcl_AppendElement(interp, buf);
}
return TCL_OK;
}
else if (strcmp(opt, "-numAttrs") == 0) {
sprintf(interp->result, "%d", PQnfields(result));
return TCL_OK;
}
else { else {
Tcl_AppendResult(interp, "Invalid option",0); Tcl_AppendResult(interp, "Invalid option",0);
goto Pg_result_errReturn; goto Pg_result_errReturn;
...@@ -531,6 +550,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -531,6 +550,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
"\t-assignbyidx arrayVarName\n", "\t-assignbyidx arrayVarName\n",
"\t-numTuples\n", "\t-numTuples\n",
"\t-attributes\n" "\t-attributes\n"
"\t-lAttributes\n"
"\t-numAttrs\n"
"\t-getTuple tupleNumber\n", "\t-getTuple tupleNumber\n",
"\t-clear\n", "\t-clear\n",
"\t-oid\n", "\t-oid\n",
...@@ -553,8 +574,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -553,8 +574,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int lobjId; int lobjId;
int mode; int mode;
int fd; int fd;
...@@ -564,13 +585,13 @@ Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -564,13 +585,13 @@ Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
"pg_lo_open connection lobjOid mode", 0); "pg_lo_open connection lobjOid mode", 0);
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1];
if (! PgValidId(connPtrName)) { conn = PgGetConnectionId(cd, argv[1]);
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
lobjId = atoi(argv[2]); lobjId = atoi(argv[2]);
if (strlen(argv[3]) < 1 || if (strlen(argv[3]) < 1 ||
strlen(argv[3]) > 2) strlen(argv[3]) > 2)
...@@ -623,8 +644,8 @@ Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -623,8 +644,8 @@ Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int fd; int fd;
if (argc != 3) { if (argc != 3) {
...@@ -633,13 +654,12 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -633,13 +654,12 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
fd = atoi(argv[2]); fd = atoi(argv[2]);
sprintf(interp->result,"%d",lo_close(conn,fd)); sprintf(interp->result,"%d",lo_close(conn,fd));
return TCL_OK; return TCL_OK;
...@@ -659,8 +679,8 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -659,8 +679,8 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int fd; int fd;
int nbytes = 0; int nbytes = 0;
char *buf; char *buf;
...@@ -673,13 +693,12 @@ Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -673,13 +693,12 @@ Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
fd = atoi(argv[2]); fd = atoi(argv[2]);
bufVar = argv[3]; bufVar = argv[3];
...@@ -712,8 +731,8 @@ Pg_lo_write ...@@ -712,8 +731,8 @@ Pg_lo_write
int int
Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char *connPtrName;
char *buf; char *buf;
int fd; int fd;
int nbytes = 0; int nbytes = 0;
...@@ -725,13 +744,12 @@ Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -725,13 +744,12 @@ Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
fd = atoi(argv[2]); fd = atoi(argv[2]);
buf = argv[3]; buf = argv[3];
...@@ -761,8 +779,8 @@ whence can be either ...@@ -761,8 +779,8 @@ whence can be either
int int
Pg_lo_lseek(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_lseek(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int fd; int fd;
char *whenceStr; char *whenceStr;
int offset, whence; int offset, whence;
...@@ -773,13 +791,12 @@ Pg_lo_lseek(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -773,13 +791,12 @@ Pg_lo_lseek(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
fd = atoi(argv[2]); fd = atoi(argv[2]);
offset = atoi(argv[3]); offset = atoi(argv[3]);
...@@ -815,8 +832,8 @@ for now, we don't support any additional storage managers. ...@@ -815,8 +832,8 @@ for now, we don't support any additional storage managers.
int int
Pg_lo_creat(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_creat(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
char *modeStr; char *modeStr;
char *modeWord; char *modeWord;
int mode; int mode;
...@@ -827,14 +844,12 @@ Pg_lo_creat(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -827,14 +844,12 @@ Pg_lo_creat(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
modeStr = argv[2]; modeStr = argv[2];
modeWord = strtok(modeStr,"|"); modeWord = strtok(modeStr,"|");
...@@ -880,8 +895,8 @@ Pg_lo_tell ...@@ -880,8 +895,8 @@ Pg_lo_tell
int int
Pg_lo_tell(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_tell(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int fd; int fd;
if (argc != 3) { if (argc != 3) {
...@@ -890,13 +905,12 @@ Pg_lo_tell(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -890,13 +905,12 @@ Pg_lo_tell(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
fd = atoi(argv[2]); fd = atoi(argv[2]);
sprintf(interp->result,"%d",lo_tell(conn,fd)); sprintf(interp->result,"%d",lo_tell(conn,fd));
...@@ -916,8 +930,8 @@ Pg_lo_unlink ...@@ -916,8 +930,8 @@ Pg_lo_unlink
int int
Pg_lo_unlink(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_unlink(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
int lobjId; int lobjId;
int retval; int retval;
...@@ -927,13 +941,12 @@ Pg_lo_unlink(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -927,13 +941,12 @@ Pg_lo_unlink(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
lobjId = atoi(argv[2]); lobjId = atoi(argv[2]);
retval = lo_unlink(conn,lobjId); retval = lo_unlink(conn,lobjId);
...@@ -960,8 +973,8 @@ Pg_lo_import ...@@ -960,8 +973,8 @@ Pg_lo_import
int int
Pg_lo_import(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_import(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
char* filename; char* filename;
Oid lobjId; Oid lobjId;
...@@ -971,13 +984,12 @@ Pg_lo_import(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -971,13 +984,12 @@ Pg_lo_import(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
filename = argv[2]; filename = argv[2];
lobjId = lo_import(conn,filename); lobjId = lo_import(conn,filename);
...@@ -1001,8 +1013,8 @@ Pg_lo_export ...@@ -1001,8 +1013,8 @@ Pg_lo_export
int int
Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
char* connPtrName;
char* filename; char* filename;
Oid lobjId; Oid lobjId;
int retval; int retval;
...@@ -1013,13 +1025,12 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1013,13 +1025,12 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
connPtrName = argv[1]; conn = PgGetConnectionId(cd, argv[1]);
if (! PgValidId(connPtrName)) { if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, "Argument passed in is not a valid connection\n", 0); Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR; return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(connPtrName);
lobjId = atoi(argv[2]); lobjId = atoi(argv[2]);
filename = argv[3]; filename = argv[3];
...@@ -1055,6 +1066,7 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1055,6 +1066,7 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
int int
Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv) Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
PGconn *conn; PGconn *conn;
PGresult *result; PGresult *result;
int ch_flag, r; int ch_flag, r;
...@@ -1073,15 +1085,12 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv) ...@@ -1073,15 +1085,12 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
return TCL_ERROR; return TCL_ERROR;
} }
if (! PgValidId(argv[1])) conn = PgGetConnectionId(cd, argv[1]);
{ if (conn == (PGconn *)NULL) {
Tcl_AppendResult(interp, Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
"Argument passed in is not a valid connection\n", 0); return TCL_ERROR;
return TCL_ERROR;
} }
conn = (PGconn*)PgGetId(argv[1]);
if ((result = PQexec(conn, argv[2])) == 0) if ((result = PQexec(conn, argv[2])) == 0)
{ {
/* error occurred during the query */ /* error occurred during the query */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pgtclCmds.h,v 1.2 1996/10/07 21:19:09 scrappy Exp $ * $Id: pgtclCmds.h,v 1.3 1996/10/30 06:18:40 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -14,6 +14,31 @@ ...@@ -14,6 +14,31 @@
#define PGTCLCMDS_H #define PGTCLCMDS_H
#include "tcl.h" #include "tcl.h"
#include "libpq/pqcomm.h"
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
typedef struct Pg_clientData_s {
Tcl_HashTable dbh_hash;
Tcl_HashTable res_hash;
long dbh_count;
long res_count;
} Pg_clientData;
typedef struct Pg_ConnectionId_s {
char id[32];
PGconn *conn;
Tcl_HashTable res_hash;
} Pg_ConnectionId;
typedef struct Pg_ResultId_s {
char id[32];
PGresult *result;
Pg_ConnectionId *connection;
} Pg_ResultId;
/* **************************/ /* **************************/
/* registered Tcl functions */ /* registered Tcl functions */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.1.1.1 1996/07/09 06:22:16 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.2 1996/10/30 06:18:41 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,31 +21,186 @@ ...@@ -21,31 +21,186 @@
#include <string.h> #include <string.h>
#include "tcl.h" #include "tcl.h"
#include "pgtclCmds.h"
#include "pgtclId.h" #include "pgtclId.h"
/* convert a pointer into a string */ /*
* Create the Id for a new connection and hash it
*/
void
PgSetConnectionId(Pg_clientData *cd, char *id, PGconn *conn)
{
Tcl_HashEntry *hent;
Pg_ConnectionId *connid;
int hnew;
connid = (Pg_ConnectionId *)ckalloc(sizeof(Pg_ConnectionId));
connid->conn = conn;
Tcl_InitHashTable(&(connid->res_hash), TCL_STRING_KEYS);
sprintf(connid->id, "pgc%ld", cd->dbh_count++);
strcpy(id, connid->id);
hent = Tcl_CreateHashEntry(&(cd->dbh_hash), connid->id, &hnew);
Tcl_SetHashValue(hent, (ClientData)connid);
}
/*
* Get back the connection from the Id
*/
PGconn *
PgGetConnectionId(Pg_clientData *cd, char *id)
{
Tcl_HashEntry *hent;
Pg_ConnectionId *connid;
hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
if(hent == NULL) {
return (PGconn *)NULL;
}
connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
return connid->conn;
}
/*
* Remove a connection Id from the hash table and
* close all portals the user forgot.
*/
void
PgDelConnectionId(Pg_clientData *cd, char *id)
{
Tcl_HashEntry *hent;
Tcl_HashEntry *hent2;
Tcl_HashEntry *hent3;
Tcl_HashSearch hsearch;
Pg_ConnectionId *connid;
Pg_ResultId *resid;
hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
if(hent == NULL) {
return;
}
connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
hent2 = Tcl_FirstHashEntry(&(connid->res_hash), &hsearch);
while(hent2 != NULL) {
resid = (Pg_ResultId *)Tcl_GetHashValue(hent2);
PQclear(resid->result);
hent3 = Tcl_FindHashEntry(&(cd->res_hash), resid->id);
if(hent3 != NULL) {
Tcl_DeleteHashEntry(hent3);
}
ckfree(resid);
hent2 = Tcl_NextHashEntry(&hsearch);
}
Tcl_DeleteHashTable(&(connid->res_hash));
Tcl_DeleteHashEntry(hent);
ckfree(connid);
}
/*
* Create a new result Id and hash it
*/
void void
PgSetId(char *id, void *ptr) PgSetResultId(Pg_clientData *cd, char *id, char *connid_c, PGresult *res)
{
Tcl_HashEntry *hent;
Pg_ConnectionId *connid;
Pg_ResultId *resid;
int hnew;
hent = Tcl_FindHashEntry(&(cd->dbh_hash), connid_c);
if(hent == NULL) {
connid = NULL;
} else {
connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
}
resid = (Pg_ResultId *)ckalloc(sizeof(Pg_ResultId));
resid->result = res;
resid->connection = connid;
sprintf(resid->id, "pgr%ld", cd->res_count++);
strcpy(id, resid->id);
hent = Tcl_CreateHashEntry(&(cd->res_hash), resid->id, &hnew);
Tcl_SetHashValue(hent, (ClientData)resid);
if(connid != NULL) {
hent = Tcl_CreateHashEntry(&(connid->res_hash), resid->id, &hnew);
Tcl_SetHashValue(hent, (ClientData)resid);
}
}
/*
* Get back the result pointer from the Id
*/
PGresult *
PgGetResultId(Pg_clientData *cd, char *id)
{ {
(void) sprintf(id, "pgp%lx", (long) ptr); Tcl_HashEntry *hent;
Pg_ResultId *resid;
hent = Tcl_FindHashEntry(&(cd->res_hash), id);
if(hent == NULL) {
return (PGresult *)NULL;
}
resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
return resid->result;
} }
/* get back a pointer from a string */ /*
void * * Remove a result Id from the hash tables
PgGetId(char *id) */
void
PgDelResultId(Pg_clientData *cd, char *id)
{ {
long ptr; Tcl_HashEntry *hent;
ptr = strtol(id+3, NULL, 16); Tcl_HashEntry *hent2;
return (void *) ptr; Pg_ResultId *resid;
hent = Tcl_FindHashEntry(&(cd->res_hash), id);
if(hent == NULL) {
return;
}
resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
if (resid->connection != NULL) {
hent2 = Tcl_FindHashEntry(&(resid->connection->res_hash), id);
if(hent2 != NULL) {
Tcl_DeleteHashEntry(hent2);
}
}
Tcl_DeleteHashEntry(hent);
ckfree(resid);
} }
/* check to see if the string is a valid pgtcl pointer */
int /*
PgValidId(char* id) * Get the connection Id from the result Id
*/
void
PgGetConnByResultId(Pg_clientData *cd, char *id, char *resid_c)
{ {
if ( (strlen(id) > 3) && id[0]=='p' && id[1] == 'g' && id[2] == 'p') Tcl_HashEntry *hent;
return 1; Pg_ResultId *resid;
else
return 0; hent = Tcl_FindHashEntry(&(cd->res_hash), id);
if(hent == NULL) {
return;
}
resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
if (resid->connection != NULL) {
strcpy(id, resid->connection->id);
}
} }
...@@ -8,11 +8,15 @@ ...@@ -8,11 +8,15 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pgtclId.h,v 1.1.1.1 1996/07/09 06:22:16 scrappy Exp $ * $Id: pgtclId.h,v 1.2 1996/10/30 06:18:42 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
extern void PgSetId(char *id, void *ptr); extern void PgSetConnectionId(Pg_clientData *cd, char *id, PGconn *conn);
extern void* PgGetId(char *id); extern PGconn *PgGetConnectionId(Pg_clientData *cd, char *id);
extern int PgValidId(char* id); extern void PgDelConnectionId(Pg_clientData *cd, char *id);
extern void PgSetResultId(Pg_clientData *cd, char *id, char *connid, PGresult *res);
extern PGresult *PgGetResultId(Pg_clientData *cd, char *id);
extern void PgDelResultId(Pg_clientData *cd, char *id);
extern void PgGetConnByResultId(Pg_clientData *cd, char *id, char *resid);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment