]> granicus.if.org Git - postgresql/commitdiff
Add a PQfireResultCreateEvents function to allow applications to mimic the
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 19 Sep 2008 20:06:13 +0000 (20:06 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.262 2008/09/19 16:40:40 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.263 2008/09/19 20:06:13 tgl Exp $ -->
 
 <chapter id="libpq">
  <title><application>libpq</application> - C Library</title>
@@ -4592,10 +4592,11 @@ char *pg_encoding_to_char(int <replaceable>encoding_id</replaceable>);
       <parameter>conn</parameter> is not null and <parameter>status</>
       indicates an error, the current error message of the specified
       connection is copied into the <structname>PGresult</structname>.
-      Also, if <parameter>conn</parameter> is not null, any event handlers
+      Also, if <parameter>conn</parameter> is not null, any event procedures
       registered in the connection are copied into the
-      <structname>PGresult</structname> (but they don't get
-      <literal>PGEVT_RESULTCREATE</> calls).
+      <structname>PGresult</structname>.  (They do not get
+      <literal>PGEVT_RESULTCREATE</> calls, but see
+      <function>PQfireResultCreateEvents</function>.)
       Note that <function>PQclear</function> should eventually be called
       on the object, just as with a <structname>PGresult</structname>
       returned by <application>libpq</application> itself.
@@ -4603,6 +4604,46 @@ char *pg_encoding_to_char(int <replaceable>encoding_id</replaceable>);
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term>
+     <function>PQfireResultCreateEvents</function>
+     <indexterm>
+      <primary>PQfireResultCreateEvents</primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Fires a <literal>PGEVT_RESULTCREATE</literal> event (see <xref
+      linkend="libpq-events">) for each event procedure registered in the
+      <structname>PGresult</structname> object.  Returns non-zero for success,
+      zero if any event procedure fails.
+
+      <synopsis>
+       int PQfireResultCreateEvents(PGconn *conn, PGresult *res);
+      </synopsis>
+     </para>
+
+     <para>
+      The <literal>conn</> argument is passed through to event procedures
+      but not used directly.  It can be <literal>NULL</> if the event
+      procedures won't use it.
+     </para>
+
+     <para>
+      Event procedures that have already received a
+      <literal>PGEVT_RESULTCREATE</> or <literal>PGEVT_RESULTCOPY</> event
+      for this object are not fired again.
+     </para>
+
+     <para>
+      The main reason that this function is separate from
+      <function>PQmakeEmptyPGResult</function> is that it is often appropriate
+      to create a <structname>PGresult</structname> and fill it with data
+      before invoking the event procedures.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term>
      <function>PQcopyResult</function>
@@ -4904,7 +4945,7 @@ defaultNoticeProcessor(void *arg, const char *message)
       <synopsis>
 typedef struct
 {
-    const PGconn *conn;
+    PGconn *conn;
 } PGEventRegister;
       </synopsis>
 
@@ -4937,7 +4978,7 @@ typedef struct
       <synopsis>
 typedef struct
 {
-    const PGconn *conn;
+    PGconn *conn;
 } PGEventConnReset;
       </synopsis>
 
@@ -4967,7 +5008,7 @@ typedef struct
       <synopsis>
 typedef struct
 {
-    const PGconn *conn;
+    PGconn *conn;
 } PGEventConnDestroy;
       </synopsis>
 
@@ -4995,7 +5036,7 @@ typedef struct
       <synopsis>
 typedef struct
 {
-    const PGconn *conn;
+    PGconn *conn;
     PGresult *result;
 } PGEventResultCreate;
       </synopsis>
@@ -5063,7 +5104,7 @@ typedef struct
       <synopsis>
 typedef struct
 {
-    const PGresult *result;
+    PGresult *result;
 } PGEventResultDestroy;
       </synopsis>
 
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