Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit56e8243

Browse files
committed
Add two new comments to pglibtcl...
From: Massimo Dal Zotto <dz@cs.unitn.it>
1 parent194ed4e commit56e8243

File tree

3 files changed

+171
-3
lines changed

3 files changed

+171
-3
lines changed

‎src/interfaces/libpgtcl/pgtcl.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.5 1996/11/11 12:14:38 scrappy Exp $
12+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.6 1996/12/19 05:02:47 scrappy Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -159,6 +159,16 @@ Pgtcl_Init (Tcl_Interp *interp)
159159
Pg_lo_export,
160160
(ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
161161

162+
Tcl_CreateCommand(interp,
163+
"pg_listen",
164+
Pg_listen,
165+
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
166+
167+
Tcl_CreateCommand(interp,
168+
"pg_notifies",
169+
Pg_notifies,
170+
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
171+
162172
Tcl_PkgProvide(interp,"Pgtcl","1.0");
163173

164174
returnTCL_OK;

‎src/interfaces/libpgtcl/pgtclCmds.c

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.7 1996/11/11 12:14:42 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.8 1996/12/19 05:02:49 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -24,6 +24,8 @@
2424
#include"pgtclCmds.h"
2525
#include"pgtclId.h"
2626

27+
staticTcl_HashTablenotifyTable= {NULL };
28+
2729
#ifdefTCL_ARRAYS
2830
#defineISOCTAL(c)(((c) >= '0') && ((c) <= '7'))
2931
#defineDIGIT(c)((c) - '0')
@@ -1210,3 +1212,155 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
12101212
returnTCL_OK;
12111213
}
12121214

1215+
int
1216+
Pg_listen(ClientDatacData,Tcl_Interp*interp,intargc,char*argv[])
1217+
{
1218+
intnew;
1219+
char*relname;
1220+
char*callback=NULL;
1221+
Tcl_HashEntry*entry;
1222+
PGconn*conn;
1223+
PGresult*result;
1224+
1225+
if ((argc<3)|| (argc>4)) {
1226+
Tcl_AppendResult(interp,"wrong # args, should be \"",
1227+
argv[0]," connection relname ?callback?\"",0);
1228+
returnTCL_ERROR;
1229+
}
1230+
1231+
/*
1232+
* Initialize the notify hash table if not already done.
1233+
*/
1234+
if (notifyTable.buckets==NULL) {
1235+
Tcl_InitHashTable(&notifyTable,TCL_STRING_KEYS);
1236+
}
1237+
1238+
/*
1239+
* Get the command arguments. Note that relname will copied by
1240+
* Tcl_CreateHashEntry while callback must be allocated.
1241+
*/
1242+
if (!PgValidId(argv[1])) {
1243+
Tcl_AppendResult(interp,"not a valid connection\n",0);
1244+
returnTCL_ERROR;
1245+
}
1246+
conn= (PGconn*)PgGetId(argv[1]);
1247+
relname=argv[2];
1248+
if ((argc>3)&&*argv[3]) {
1249+
callback= (char*)ckalloc((unsigned) (strlen(argv[3])+1));
1250+
strcpy(callback,argv[3]);
1251+
}
1252+
1253+
/*
1254+
* Set or update a callback for a relation;
1255+
*/
1256+
if (callback) {
1257+
entry=Tcl_CreateHashEntry(&notifyTable,relname,&new);
1258+
if (new) {
1259+
/* New callback, execute a listen command on the relation */
1260+
char*cmd= (char*)ckalloc((unsigned) (strlen(argv[2])+8));
1261+
sprintf(cmd,"LISTEN %s",relname);
1262+
result=PQexec(conn,cmd);
1263+
ckfree(cmd);
1264+
if (!result|| (result->resultStatus!=PGRES_COMMAND_OK)) {
1265+
/* Error occurred during the execution of command */
1266+
if (result)PQclear(result);
1267+
ckfree(callback);
1268+
Tcl_DeleteHashEntry(entry);
1269+
Tcl_SetResult(interp,conn->errorMessage,TCL_STATIC);
1270+
returnTCL_ERROR;
1271+
}
1272+
PQclear(result);
1273+
}else {
1274+
/* Free the old callback string */
1275+
ckfree((char*)Tcl_GetHashValue(entry));
1276+
}
1277+
/* Store the new callback command */
1278+
Tcl_SetHashValue(entry,callback);
1279+
}
1280+
1281+
/*
1282+
* Remove a callback for a relation. There is no way to
1283+
* un-listen a relation, simply remove the callback from
1284+
* the notify hash table.
1285+
*/
1286+
if (callback==NULL) {
1287+
entry=Tcl_FindHashEntry(&notifyTable,relname);
1288+
if (entry==NULL) {
1289+
Tcl_AppendResult(interp,"not listening on ",relname,0);
1290+
returnTCL_ERROR;
1291+
}
1292+
ckfree((char*)Tcl_GetHashValue(entry));
1293+
Tcl_DeleteHashEntry(entry);
1294+
}
1295+
1296+
returnTCL_OK;
1297+
}
1298+
1299+
Pg_notifies(ClientDatacData,Tcl_Interp*interp,intargc,char*argv[])
1300+
{
1301+
intcount;
1302+
charbuff[12];
1303+
char*relname;
1304+
char*callback;
1305+
Tcl_HashEntry*entry;
1306+
PGconn*conn;
1307+
PGresult*result;
1308+
PGnotify*notify;
1309+
1310+
if (argc!=2) {
1311+
Tcl_AppendResult(interp,"wrong # args, should be \"",
1312+
argv[0]," connection\"",0);
1313+
returnTCL_ERROR;
1314+
}
1315+
1316+
/*
1317+
* Initialize the notify hash table if not already done.
1318+
*/
1319+
if (notifyTable.buckets==NULL) {
1320+
Tcl_InitHashTable(&notifyTable,TCL_STRING_KEYS);
1321+
}
1322+
1323+
/*
1324+
* Get the connection argument.
1325+
*/
1326+
if (!PgValidId(argv[1])) {
1327+
Tcl_AppendResult(interp,"not a valid connection\n",0);
1328+
returnTCL_ERROR;
1329+
}
1330+
conn= (PGconn*)PgGetId(argv[1]);
1331+
1332+
/* Execute an empty command to retrieve asynchronous notifications */
1333+
result=PQexec(conn," ");
1334+
if (result==NULL) {
1335+
/* Error occurred during the execution of command */
1336+
Tcl_SetResult(interp,conn->errorMessage,TCL_STATIC);
1337+
returnTCL_ERROR;
1338+
}
1339+
PQclear(result);
1340+
1341+
/*
1342+
* Loop while there are pending notifies.
1343+
*/
1344+
for (count=0;count<999;count++) {
1345+
/* See if there is a pending notification */
1346+
notify=PQnotifies(conn);
1347+
if (notify==NULL) {
1348+
break;
1349+
}
1350+
entry=Tcl_FindHashEntry(&notifyTable,notify->relname);
1351+
if (entry!=NULL) {
1352+
callback=Tcl_GetHashValue(entry);
1353+
if (callback) {
1354+
Tcl_Eval(interp,callback);
1355+
}
1356+
}
1357+
free(notify);
1358+
}
1359+
1360+
/*
1361+
* Return the number of notifications processed.
1362+
*/
1363+
sprintf(buff,"%d",count);
1364+
Tcl_SetResult(interp,buff,TCL_VOLATILE);
1365+
returnTCL_OK;
1366+
}

‎src/interfaces/libpgtcl/pgtclCmds.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: pgtclCmds.h,v 1.4 1996/11/09 10:39:42 scrappy Exp $
8+
* $Id: pgtclCmds.h,v 1.5 1996/12/19 05:02:51 scrappy Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -75,6 +75,10 @@ extern int Pg_lo_import(
7575
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
7676
externintPg_lo_export(
7777
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
78+
externintPg_listen(
79+
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
80+
externintPg_notifies(
81+
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
7882

7983

8084
#endif/*PGTCLCMDS_H*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp