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

Commit8c8aa53

Browse files
committed
pg_on_connection_loss command for libpgtcl. Patch from
Gerhard Hintermayer, revised and documented by Tom Lane.This patch also fixes a 'must fix' bug: libpgtcl's LISTEN/NOTIFYsupport was broken by the recent changes to the PGnotify structure.Guess that change wasn't quite so safe as we thought.
1 parentb356b96 commit8c8aa53

File tree

6 files changed

+310
-35
lines changed

6 files changed

+310
-35
lines changed

‎doc/src/sgml/libpgtcl.sgml

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@
7272
<ENTRY><function>pg_listen</function></ENTRY>
7373
<ENTRY>establish a callback for NOTIFY messages</ENTRY>
7474
</ROW>
75+
<ROW>
76+
<ENTRY><function>pg_on_connection_loss</function></ENTRY>
77+
<ENTRY>establish a callback for unexpected connection loss</ENTRY>
78+
</ROW>
7579

7680
<ROW>
7781
<ENTRY><function>pg_lo_creat</function></ENTRY>
@@ -1245,7 +1249,7 @@ pg_listen <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLA
12451249
<REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
12461250
</TERM>
12471251
<LISTITEM>
1248-
<PARA>If present and not empty, provides the command string to execute
1252+
<PARA>If present, provides the command string to execute
12491253
when a matching notification arrives.
12501254
</PARA>
12511255
</LISTITEM>
@@ -1312,6 +1316,105 @@ invoke the SQL NOTIFY statement using <FUNCTION>pg_exec</FUNCTION>.
13121316

13131317
<!-- ********************************************************** -->
13141318

1319+
<REFENTRY ID="PGTCL-PGON_CONNECTION_LOSS">
1320+
<REFMETA>
1321+
<REFENTRYTITLE>pg_on_connection_loss</REFENTRYTITLE>
1322+
<REFMISCINFO>PGTCL - Asynchronous Notify</REFMISCINFO>
1323+
</REFMETA>
1324+
<REFNAMEDIV>
1325+
<REFNAME>pg_on_connection_loss
1326+
</REFNAME>
1327+
<REFPURPOSE>set or change a callback for unexpected connection loss
1328+
</REFPURPOSE>
1329+
<INDEXTERM
1330+
ID="IX-PGTCL-PGON_CONNECTION_LOSS-1"><PRIMARY>pgtcl</PRIMARY><SECONDARY>connection loss</SECONDARY></INDEXTERM>
1331+
<INDEXTERM ID="IX-PGTCL-PGON_CONNECTION_LOSS-2"><PRIMARY>connection loss</PRIMARY></INDEXTERM>
1332+
</REFNAMEDIV>
1333+
<REFSYNOPSISDIV>
1334+
<REFSYNOPSISDIVINFO>
1335+
<DATE>2002-09-02</DATE>
1336+
</REFSYNOPSISDIVINFO>
1337+
<SYNOPSIS>
1338+
pg_on_connection_loss <REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE> <REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
1339+
</SYNOPSIS>
1340+
1341+
<REFSECT2 ID="R2-PGTCL-PGON_CONNECTION_LOSS-1">
1342+
<REFSECT2INFO>
1343+
<DATE>2002-09-02</DATE>
1344+
</REFSECT2INFO>
1345+
<TITLE>Inputs
1346+
</TITLE>
1347+
<VARIABLELIST>
1348+
<VARLISTENTRY>
1349+
<TERM>
1350+
<REPLACEABLE CLASS="PARAMETER">dbHandle</REPLACEABLE>
1351+
</TERM>
1352+
<LISTITEM>
1353+
<PARA>Specifies a valid database handle.
1354+
</PARA>
1355+
</LISTITEM>
1356+
</VARLISTENTRY>
1357+
<VARLISTENTRY>
1358+
<TERM>
1359+
<REPLACEABLE CLASS="PARAMETER">callbackCommand</REPLACEABLE>
1360+
</TERM>
1361+
<LISTITEM>
1362+
<PARA>If present, provides the command string to execute
1363+
when connection loss is detected.
1364+
</PARA>
1365+
</LISTITEM>
1366+
</VARLISTENTRY>
1367+
</VARIABLELIST>
1368+
</REFSECT2>
1369+
1370+
<REFSECT2 ID="R2-PGTCL-PGON_CONNECTION_LOSS-2">
1371+
<REFSECT2INFO>
1372+
<DATE>2002-09-02</DATE>
1373+
</REFSECT2INFO>
1374+
<TITLE>Outputs
1375+
</TITLE>
1376+
<VARIABLELIST>
1377+
<VARLISTENTRY>
1378+
<TERM>
1379+
None
1380+
</TERM>
1381+
<LISTITEM>
1382+
<PARA>
1383+
</PARA>
1384+
</LISTITEM>
1385+
</VARLISTENTRY>
1386+
</VARIABLELIST>
1387+
</REFSECT2>
1388+
</REFSYNOPSISDIV>
1389+
1390+
<REFSECT1 ID="R1-PGTCL-PGON_CONNECTION_LOSS-1">
1391+
<REFSECT1INFO>
1392+
<DATE>2002-09-02</DATE>
1393+
</REFSECT1INFO>
1394+
<TITLE>Description
1395+
</TITLE>
1396+
<PARA><FUNCTION>pg_on_connection_loss</FUNCTION> creates, changes, or cancels
1397+
a request to execute a callback command if an unexpected loss of connection
1398+
to the database occurs.
1399+
With a <parameter>callbackCommand</>
1400+
parameter, the request is established, or the command string of an already
1401+
existing request is replaced. With no <parameter>callbackCommand</>
1402+
parameter, a prior request is canceled.
1403+
</PARA>
1404+
1405+
<para>
1406+
The callback command string is executed from the Tcl idle loop. That is the
1407+
normal idle state of an application written with Tk. In non-Tk Tcl shells,
1408+
you can
1409+
execute <FUNCTION>update</FUNCTION> or <FUNCTION>vwait</FUNCTION> to cause
1410+
the idle loop to be entered.
1411+
</Para>
1412+
</REFSECT1>
1413+
1414+
</REFENTRY>
1415+
1416+
<!-- ********************************************************** -->
1417+
13151418
<REFENTRY ID="PGTCL-PGLOCREAT">
13161419
<REFMETA>
13171420
<REFENTRYTITLE>pg_lo_creat</REFENTRYTITLE>

‎src/interfaces/libpgtcl/pgtcl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.25 2002/06/20 20:29:53 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.26 2002/09/02 21:51:47 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -151,8 +151,13 @@ Pgtcl_Init(Tcl_Interp *interp)
151151
"pg_listen",
152152
Pg_listen,
153153
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
154+
155+
Tcl_CreateCommand(interp,
156+
"pg_on_connection_loss",
157+
Pg_on_connection_loss,
158+
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
154159

155-
Tcl_PkgProvide(interp,"Pgtcl","1.3");
160+
Tcl_PkgProvide(interp,"Pgtcl","1.4");
156161

157162
returnTCL_OK;
158163
}

‎src/interfaces/libpgtcl/pgtclCmds.c

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.65 2002/09/0206:11:43 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.66 2002/09/0221:51:47 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1876,6 +1876,7 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
18761876
notifies= (Pg_TclNotifies*)ckalloc(sizeof(Pg_TclNotifies));
18771877
notifies->interp=interp;
18781878
Tcl_InitHashTable(&notifies->notify_hash,TCL_STRING_KEYS);
1879+
notifies->conn_loss_cmd=NULL;
18791880
notifies->next=connid->notify_list;
18801881
connid->notify_list=notifies;
18811882
Tcl_CallWhenDeleted(interp,PgNotifyInterpDelete,
@@ -1970,3 +1971,84 @@ Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
19701971
ckfree(caserelname);
19711972
returnTCL_OK;
19721973
}
1974+
1975+
/***********************************
1976+
Pg_on_connection_loss
1977+
create or remove a callback request for unexpected connection loss
1978+
1979+
syntax:
1980+
pg_on_connection_loss conn ?callbackcommand?
1981+
1982+
With a third arg, creates or changes the callback command for
1983+
connection loss; without, cancels the callback request.
1984+
1985+
Callbacks can occur whenever Tcl is executing its event loop.
1986+
This is the normal idle loop in Tk; in plain tclsh applications,
1987+
vwait or update can be used to enter the Tcl event loop.
1988+
***********************************/
1989+
int
1990+
Pg_on_connection_loss(ClientDatacData,Tcl_Interp*interp,intargc,char*argv[])
1991+
{
1992+
char*callback=NULL;
1993+
Pg_TclNotifies*notifies;
1994+
Pg_ConnectionId*connid;
1995+
PGconn*conn;
1996+
1997+
if (argc<2||argc>3)
1998+
{
1999+
Tcl_AppendResult(interp,"wrong # args, should be \"",
2000+
argv[0]," connection ?callback?\"",0);
2001+
returnTCL_ERROR;
2002+
}
2003+
2004+
/*
2005+
* Get the command arguments.
2006+
*/
2007+
conn=PgGetConnectionId(interp,argv[1],&connid);
2008+
if (conn== (PGconn*)NULL)
2009+
returnTCL_ERROR;
2010+
2011+
if ((argc>2)&&*argv[2])
2012+
{
2013+
callback= (char*)ckalloc((unsigned) (strlen(argv[2])+1));
2014+
strcpy(callback,argv[2]);
2015+
}
2016+
2017+
/* Find or make a Pg_TclNotifies struct for this interp and connection */
2018+
2019+
for (notifies=connid->notify_list;notifies;notifies=notifies->next)
2020+
{
2021+
if (notifies->interp==interp)
2022+
break;
2023+
}
2024+
if (notifies==NULL)
2025+
{
2026+
notifies= (Pg_TclNotifies*)ckalloc(sizeof(Pg_TclNotifies));
2027+
notifies->interp=interp;
2028+
Tcl_InitHashTable(&notifies->notify_hash,TCL_STRING_KEYS);
2029+
notifies->conn_loss_cmd=NULL;
2030+
notifies->next=connid->notify_list;
2031+
connid->notify_list=notifies;
2032+
Tcl_CallWhenDeleted(interp,PgNotifyInterpDelete,
2033+
(ClientData)notifies);
2034+
}
2035+
2036+
/* Store new callback setting */
2037+
2038+
if (notifies->conn_loss_cmd)
2039+
ckfree((void*)notifies->conn_loss_cmd);
2040+
notifies->conn_loss_cmd=callback;
2041+
2042+
if (callback)
2043+
{
2044+
/*
2045+
* Start the notify event source if it isn't already running.
2046+
* The notify source will cause Tcl to watch read-ready on the
2047+
* connection socket, so that we find out quickly if the connection
2048+
* drops.
2049+
*/
2050+
PgStartNotifyEventSource(connid);
2051+
}
2052+
2053+
returnTCL_OK;
2054+
}

‎src/interfaces/libpgtcl/pgtclCmds.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: pgtclCmds.h,v 1.26 2002/06/20 20:29:53 momjian Exp $
9+
* $Id: pgtclCmds.h,v 1.27 2002/09/02 21:51:47 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -21,7 +21,7 @@
2121
#defineRES_START 16
2222

2323
/*
24-
* From Tclverion 8.0 on we can make large object access binary.
24+
* From Tclversion 8.0 on we can make large object access binary.
2525
*/
2626
#ifdefTCL_MAJOR_VERSION
2727
#if (TCL_MAJOR_VERSION >=8)
@@ -36,6 +36,9 @@
3636
* deleted while the connection remains open. A free side benefit is that
3737
* multiple interpreters can be registered to listen for the same notify
3838
* name. (All their callbacks will be called, but in an unspecified order.)
39+
*
40+
* We use the same approach for pg_on_connection_loss callbacks, but they
41+
* are not kept in a hashtable since there's no name associated.
3942
*/
4043

4144
typedefstructPg_TclNotifies_s
@@ -48,6 +51,8 @@ typedef struct Pg_TclNotifies_s
4851
* got round to deleting the Pg_TclNotifies structure.
4952
*/
5053
Tcl_HashTablenotify_hash;/* Active pg_listen requests */
54+
55+
char*conn_loss_cmd;/* pg_on_connection_loss cmd, or NULL */
5156
}Pg_TclNotifies;
5257

5358
typedefstructPg_ConnectionId_s
@@ -128,5 +133,7 @@ extern int Pg_lo_export(
128133
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
129134
externintPg_listen(
130135
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
136+
externintPg_on_connection_loss(
137+
ClientDatacData,Tcl_Interp*interp,intargc,char*argv[]);
131138

132139
#endif/* PGTCLCMDS_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp