Commit b5164666 authored by Marc G. Fournier's avatar Marc G. Fournier

someone added pg_listen and pg_notifies to libpgtcl. But first

    these routines try to use the old pointer casting stuff to get
    the connection id, second the notification hash table should
    be part of the cliendData. Otherwise, one interpreter might
    eat up the notifies for another one.

    Please apply the patch below to the current 6.0 tree.

Submitted by: wieck@sapserv.debis.de
parent 9d81f529
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.6 1996/12/19 05:02:47 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.7 1997/01/03 18:48:28 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -49,6 +49,7 @@ Pgtcl_AtExit (ClientData cData) ...@@ -49,6 +49,7 @@ Pgtcl_AtExit (ClientData cData)
Tcl_DeleteHashTable(&(cd->dbh_hash)); Tcl_DeleteHashTable(&(cd->dbh_hash));
Tcl_DeleteHashTable(&(cd->res_hash)); Tcl_DeleteHashTable(&(cd->res_hash));
Tcl_DeleteHashTable(&(cd->notify_hash));
Tcl_DeleteExitHandler(Pgtcl_AtExit, cData); Tcl_DeleteExitHandler(Pgtcl_AtExit, cData);
} }
...@@ -71,6 +72,7 @@ Pgtcl_Init (Tcl_Interp *interp) ...@@ -71,6 +72,7 @@ Pgtcl_Init (Tcl_Interp *interp)
cd = (Pg_clientData *)ckalloc(sizeof(Pg_clientData)); cd = (Pg_clientData *)ckalloc(sizeof(Pg_clientData));
Tcl_InitHashTable(&(cd->dbh_hash), TCL_STRING_KEYS); Tcl_InitHashTable(&(cd->dbh_hash), TCL_STRING_KEYS);
Tcl_InitHashTable(&(cd->res_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->dbh_count = 0L;
cd->res_count = 0L; cd->res_count = 0L;
...@@ -162,12 +164,12 @@ Pgtcl_Init (Tcl_Interp *interp) ...@@ -162,12 +164,12 @@ Pgtcl_Init (Tcl_Interp *interp)
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_listen", "pg_listen",
Pg_listen, Pg_listen,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_CreateCommand(interp, Tcl_CreateCommand(interp,
"pg_notifies", "pg_notifies",
Pg_notifies, Pg_notifies,
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
Tcl_PkgProvide(interp, "Pgtcl", "1.0"); Tcl_PkgProvide(interp, "Pgtcl", "1.0");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.8 1996/12/19 05:02:49 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.9 1997/01/03 18:48:30 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include "pgtclCmds.h" #include "pgtclCmds.h"
#include "pgtclId.h" #include "pgtclId.h"
static Tcl_HashTable notifyTable = { NULL };
#ifdef TCL_ARRAYS #ifdef TCL_ARRAYS
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) #define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
#define DIGIT(c) ((c) - '0') #define DIGIT(c) ((c) - '0')
...@@ -1215,6 +1213,7 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv) ...@@ -1215,6 +1213,7 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
int int
Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
int new; int new;
char *relname; char *relname;
char *callback = NULL; char *callback = NULL;
...@@ -1228,22 +1227,15 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1228,22 +1227,15 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
/*
* Initialize the notify hash table if not already done.
*/
if (notifyTable.buckets == NULL) {
Tcl_InitHashTable(&notifyTable, TCL_STRING_KEYS);
}
/* /*
* Get the command arguments. Note that relname will copied by * Get the command arguments. Note that relname will copied by
* Tcl_CreateHashEntry while callback must be allocated. * Tcl_CreateHashEntry while callback must be allocated.
*/ */
if (!PgValidId(argv[1])) { conn = (PGconn*)PgGetConnectionId(cd, argv[1]);
Tcl_AppendResult(interp, "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(argv[1]);
relname = argv[2]; relname = argv[2];
if ((argc > 3) && *argv[3]) { if ((argc > 3) && *argv[3]) {
callback = (char *) ckalloc((unsigned) (strlen(argv[3])+1)); callback = (char *) ckalloc((unsigned) (strlen(argv[3])+1));
...@@ -1254,7 +1246,7 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1254,7 +1246,7 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
* Set or update a callback for a relation; * Set or update a callback for a relation;
*/ */
if (callback) { if (callback) {
entry = Tcl_CreateHashEntry(&notifyTable, relname, &new); entry = Tcl_CreateHashEntry(&(cd->notify_hash), relname, &new);
if (new) { if (new) {
/* New callback, execute a listen command on the relation */ /* New callback, execute a listen command on the relation */
char *cmd = (char *) ckalloc((unsigned) (strlen(argv[2])+8)); char *cmd = (char *) ckalloc((unsigned) (strlen(argv[2])+8));
...@@ -1284,7 +1276,7 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1284,7 +1276,7 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
* the notify hash table. * the notify hash table.
*/ */
if (callback == NULL) { if (callback == NULL) {
entry = Tcl_FindHashEntry(&notifyTable, relname); entry = Tcl_FindHashEntry(&(cd->notify_hash), relname);
if (entry == NULL) { if (entry == NULL) {
Tcl_AppendResult(interp, "not listening on ", relname, 0); Tcl_AppendResult(interp, "not listening on ", relname, 0);
return TCL_ERROR; return TCL_ERROR;
...@@ -1296,11 +1288,12 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1296,11 +1288,12 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_OK; return TCL_OK;
} }
int
Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
{ {
Pg_clientData *cd = (Pg_clientData *)cData;
int count; int count;
char buff[12]; char buff[12];
char *relname;
char *callback; char *callback;
Tcl_HashEntry *entry; Tcl_HashEntry *entry;
PGconn *conn; PGconn *conn;
...@@ -1313,21 +1306,14 @@ Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1313,21 +1306,14 @@ Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR; return TCL_ERROR;
} }
/*
* Initialize the notify hash table if not already done.
*/
if (notifyTable.buckets == NULL) {
Tcl_InitHashTable(&notifyTable, TCL_STRING_KEYS);
}
/* /*
* Get the connection argument. * Get the connection argument.
*/ */
if (!PgValidId(argv[1])) { conn = (PGconn*)PgGetConnectionId(cd, argv[1]);
Tcl_AppendResult(interp, "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(argv[1]);
/* Execute an empty command to retrieve asynchronous notifications */ /* Execute an empty command to retrieve asynchronous notifications */
result = PQexec(conn, " "); result = PQexec(conn, " ");
...@@ -1347,7 +1333,7 @@ Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[]) ...@@ -1347,7 +1333,7 @@ Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
if (notify == NULL) { if (notify == NULL) {
break; break;
} }
entry = Tcl_FindHashEntry(&notifyTable, notify->relname); entry = Tcl_FindHashEntry(&(cd->notify_hash), notify->relname);
if (entry != NULL) { if (entry != NULL) {
callback = Tcl_GetHashValue(entry); callback = Tcl_GetHashValue(entry);
if (callback) { if (callback) {
......
...@@ -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.5 1996/12/19 05:02:51 scrappy Exp $ * $Id: pgtclCmds.h,v 1.6 1997/01/03 18:48:31 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
typedef struct Pg_clientData_s { typedef struct Pg_clientData_s {
Tcl_HashTable dbh_hash; Tcl_HashTable dbh_hash;
Tcl_HashTable res_hash; Tcl_HashTable res_hash;
Tcl_HashTable notify_hash;
long dbh_count; long dbh_count;
long res_count; long res_count;
} Pg_clientData; } Pg_clientData;
......
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