From 3290e6180fcd4b73ea1badb2d10e9bf44496cd91 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 19 Sep 2008 20:06:13 +0000 Subject: [PATCH] Add a PQfireResultCreateEvents function to allow applications to mimic the sequence of operations that libpq goes through while creating a PGresult. Also, remove ill-considered "const" decoration on parameters passed to event procedures. --- doc/src/sgml/libpq.sgml | 59 ++++++++++++++++++++++++----- src/interfaces/libpq/exports.txt | 3 +- src/interfaces/libpq/libpq-events.c | 34 ++++++++++++++++- src/interfaces/libpq/libpq-events.h | 15 +++++--- 4 files changed, 94 insertions(+), 17 deletions(-) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index c5da033a33..06c9b3849d 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1,4 +1,4 @@ - + <application>libpq</application> - C Library @@ -4592,10 +4592,11 @@ char *pg_encoding_to_char(int encoding_id); conn is not null and status indicates an error, the current error message of the specified connection is copied into the PGresult. - Also, if conn is not null, any event handlers + Also, if conn is not null, any event procedures registered in the connection are copied into the - PGresult (but they don't get - PGEVT_RESULTCREATE calls). + PGresult. (They do not get + PGEVT_RESULTCREATE calls, but see + PQfireResultCreateEvents.) Note that PQclear should eventually be called on the object, just as with a PGresult returned by libpq itself. @@ -4603,6 +4604,46 @@ char *pg_encoding_to_char(int encoding_id); + + + PQfireResultCreateEvents + + PQfireResultCreateEvents + + + + + Fires a PGEVT_RESULTCREATE event (see ) for each event procedure registered in the + PGresult object. Returns non-zero for success, + zero if any event procedure fails. + + + int PQfireResultCreateEvents(PGconn *conn, PGresult *res); + + + + + The conn argument is passed through to event procedures + but not used directly. It can be NULL if the event + procedures won't use it. + + + + Event procedures that have already received a + PGEVT_RESULTCREATE or PGEVT_RESULTCOPY event + for this object are not fired again. + + + + The main reason that this function is separate from + PQmakeEmptyPGResult is that it is often appropriate + to create a PGresult and fill it with data + before invoking the event procedures. + + + + PQcopyResult @@ -4904,7 +4945,7 @@ defaultNoticeProcessor(void *arg, const char *message) typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventRegister; @@ -4937,7 +4978,7 @@ typedef struct typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventConnReset; @@ -4967,7 +5008,7 @@ typedef struct typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventConnDestroy; @@ -4995,7 +5036,7 @@ typedef struct typedef struct { - const PGconn *conn; + PGconn *conn; PGresult *result; } PGEventResultCreate; @@ -5063,7 +5104,7 @@ typedef struct typedef struct { - const PGresult *result; + PGresult *result; } PGEventResultDestroy; diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt index c720efce4b..eeabe40671 100644 --- a/src/interfaces/libpq/exports.txt +++ b/src/interfaces/libpq/exports.txt @@ -1,4 +1,4 @@ -# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.20 2008/09/17 04:31:08 tgl Exp $ +# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.21 2008/09/19 20:06:13 tgl Exp $ # Functions to be exported by libpq DLLs PQconnectdb 1 PQsetdbLogin 2 @@ -150,3 +150,4 @@ PQinstanceData 147 PQsetInstanceData 148 PQresultInstanceData 149 PQresultSetInstanceData 150 +PQfireResultCreateEvents 151 diff --git a/src/interfaces/libpq/libpq-events.c b/src/interfaces/libpq/libpq-events.c index 9f46336a58..8ce3f3e81c 100644 --- a/src/interfaces/libpq/libpq-events.c +++ b/src/interfaces/libpq/libpq-events.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.c,v 1.2 2008/09/19 16:40:40 tgl Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.c,v 1.3 2008/09/19 20:06:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -175,3 +175,35 @@ PQresultInstanceData(const PGresult *result, PGEventProc proc) return NULL; } + +/* + * Fire RESULTCREATE events for an application-created PGresult. + * + * The conn argument can be NULL if event procedures won't use it. + */ +int +PQfireResultCreateEvents(PGconn *conn, PGresult *res) +{ + int i; + + if (!res) + return FALSE; + + for (i = 0; i < res->nEvents; i++) + { + if (!res->events[i].resultInitialized) + { + PGEventResultCreate evt; + + evt.conn = conn; + evt.result = res; + if (!res->events[i].proc(PGEVT_RESULTCREATE, &evt, + res->events[i].passThrough)) + return FALSE; + + res->events[i].resultInitialized = TRUE; + } + } + + return TRUE; +} diff --git a/src/interfaces/libpq/libpq-events.h b/src/interfaces/libpq/libpq-events.h index 33e2d5b046..ae708307cf 100644 --- a/src/interfaces/libpq/libpq-events.h +++ b/src/interfaces/libpq/libpq-events.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.h,v 1.1 2008/09/17 04:31:08 tgl Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.h,v 1.2 2008/09/19 20:06:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,22 +36,22 @@ typedef enum typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventRegister; typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventConnReset; typedef struct { - const PGconn *conn; + PGconn *conn; } PGEventConnDestroy; typedef struct { - const PGconn *conn; + PGconn *conn; PGresult *result; } PGEventResultCreate; @@ -63,7 +63,7 @@ typedef struct typedef struct { - const PGresult *result; + PGresult *result; } PGEventResultDestroy; typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); @@ -84,6 +84,9 @@ extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *dat /* Gets the PGresult instance data for the provided proc. */ extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); +/* Fires RESULTCREATE events for an application-created PGresult. */ +extern int PQfireResultCreateEvents(PGconn *conn, PGresult *res); + #ifdef __cplusplus } #endif