Add a PQfireResultCreateEvents function to allow applications to mimic the
authorTom Lane
Fri, 19 Sep 2008 20:06:13 +0000 (20:06 +0000)
committerTom Lane
Fri, 19 Sep 2008 20:06:13 +0000 (20:06 +0000)
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
src/interfaces/libpq/exports.txt
src/interfaces/libpq/libpq-events.c
src/interfaces/libpq/libpq-events.h

index c5da033a33034196c4041b1866a18d7afb40d5e9..06c9b3849d04d7384e7a20985e89fda5a4d24a53 100644 (file)
@@ -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 
+      linkend="libpq-events">) 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;
       
 
index c720efce4b97994cd28679531b46538228baf6f0..eeabe40671e2b82afa97abaeb8c94b0edee4e21a 100644 (file)
@@ -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
index 9f46336a58bc937a10b9f1009be8e57a68454a8d..8ce3f3e81c5c64f247738b4a44ba34e3741e6d4c 100644 (file)
@@ -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;
+}
index 33e2d5b046c1f673143d3c40babd151eb51007c8..ae708307cf009d19756b9b5587d331463f3cba41 100644 (file)
@@ -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