diff options
author | Marc G. Fournier <scrappy@hub.org> | 1998-03-15 08:03:00 +0000 |
---|---|---|
committer | Marc G. Fournier <scrappy@hub.org> | 1998-03-15 08:03:00 +0000 |
commit | 6ac2528616697eb2d155ff693874e37c7273b797 (patch) | |
tree | 80f1258f558ba290b44341828f90a7a7a087abda /src/interfaces/libpgtcl/pgtcl.c | |
parent | 609026bb6b9cc05f9aa0e5a4ad7e06b5a352e969 (diff) | |
download | postgresql-6ac2528616697eb2d155ff693874e37c7273b797.tar.gz postgresql-6ac2528616697eb2d155ff693874e37c7273b797.zip |
From: Randy Kunkee <kunkee@pluto.ops.NeoSoft.com>
It is my hope that the following "patches" to libpgtcl get included
in the next release.
See the update to the README file to get a full description of the changes.
This version of libpgtcl is completely interpreter-safe, implements the
database connection handle as a channel (no events yet, but will make it
a lot easier to do fileevents on it in the future), and supports the SQL
"copy table to stdout" and "copy table from stdin" commands, with the
I/O being from and to the connection handle. The connection and result
handles are formatted in a way to make access to the tables more efficient.
Diffstat (limited to 'src/interfaces/libpgtcl/pgtcl.c')
-rw-r--r-- | src/interfaces/libpgtcl/pgtcl.c | 259 |
1 files changed, 109 insertions, 150 deletions
diff --git a/src/interfaces/libpgtcl/pgtcl.c b/src/interfaces/libpgtcl/pgtcl.c index e8502da5c24..a90c0c7c490 100644 --- a/src/interfaces/libpgtcl/pgtcl.c +++ b/src/interfaces/libpgtcl/pgtcl.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.9 1997/09/08 02:40:08 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.10 1998/03/15 08:02:57 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -23,163 +23,122 @@ #include "pgtclId.h" /* - * Pgtcl_Init - * initialization package for the PGLITE Tcl package + * Pgtcl_Init + * initialization package for the PGLITE Tcl package * */ -/* - * Tidy up forgotten postgres connection at Tcl_Exit - */ -static 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_DeleteHashTable(&(cd->notify_hash)); - - Tcl_DeleteExitHandler(Pgtcl_AtExit, cData); -} - -/* - * Tidy up forgotten postgres connections on Interpreter deletion - */ -static void -Pgtcl_Shutdown(ClientData cData, Tcl_Interp * interp) -{ - Pgtcl_AtExit(cData); -} - int -Pgtcl_Init(Tcl_Interp * interp) +Pgtcl_Init (Tcl_Interp *interp) { - 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); - Tcl_InitHashTable(&(cd->notify_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, - "pg_conndefaults", - Pg_conndefaults, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_connect", - Pg_connect, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_disconnect", - Pg_disconnect, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_exec", - Pg_exec, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_select", - Pg_select, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_result", - Pg_result, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_open", - Pg_lo_open, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_close", - Pg_lo_close, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_read", - Pg_lo_read, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_write", - Pg_lo_write, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_lseek", - Pg_lo_lseek, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_creat", - Pg_lo_creat, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_tell", - Pg_lo_tell, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_unlink", - Pg_lo_unlink, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_import", - Pg_lo_import, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_lo_export", - Pg_lo_export, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_listen", - Pg_listen, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_CreateCommand(interp, - "pg_notifies", - Pg_notifies, - (ClientData) cd, (Tcl_CmdDeleteProc *) NULL); - - Tcl_PkgProvide(interp, "Pgtcl", "1.0"); - - return TCL_OK; + + /* finish off the ChannelType struct. Much easier to do it here then + * to guess where it might be by position in the struct. This is needed + * for Tcl7.6 and beyond, which have the getfileproc. + */ +#if (TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION == 6) + Pg_ConnType.getFileProc = PgGetFileProc; +#endif + + /* register all pgtcl commands */ + Tcl_CreateCommand(interp, + "pg_conndefaults", + Pg_conndefaults, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_connect", + Pg_connect, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_disconnect", + Pg_disconnect, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_exec", + Pg_exec, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_select", + Pg_select, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_result", + Pg_result, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_open", + Pg_lo_open, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_close", + Pg_lo_close, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_read", + Pg_lo_read, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_write", + Pg_lo_write, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_lseek", + Pg_lo_lseek, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_creat", + Pg_lo_creat, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_tell", + Pg_lo_tell, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_unlink", + Pg_lo_unlink, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_import", + Pg_lo_import, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_lo_export", + Pg_lo_export, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_listen", + Pg_listen, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_CreateCommand(interp, + "pg_notifies", + Pg_notifies, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + + Tcl_PkgProvide(interp, "Pgtcl", "1.1"); + + return TCL_OK; } int -Pgtcl_SafeInit(Tcl_Interp * interp) +Pgtcl_SafeInit (Tcl_Interp *interp) { - return Pgtcl_Init(interp); + return Pgtcl_Init(interp); } |