pg.ddx.io  pgsql-patches@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andrew Chernow <ac@esilo.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alvaro Herrera <alvherre@commandprompt.com>
Cc: PostgreSQL-development <pgsql-hackers@postgresql.org>
Cc: Merlin Moncure <mmoncure@gmail.com>
Subject: Re: [PATCHES] libpq events patch (with sgml docs)
Date: Fri, 19 Sep 2008 14:14:04 -0400
Message-ID: <48D3EBEC.1040503@esilo.com> (raw)
In-Reply-To: <28666.1221840662@sss.pgh.pa.us>
References: <48C18533.2000204@esilo.com>
	<20080905192215.GK4353@alvh.no-ip.org>
	<48C18B48.509@esilo.com>
	<20080905194853.GL4353@alvh.no-ip.org>
	<48C191A7.3000205@esilo.com>
	<20080905201504.GM4353@alvh.no-ip.org>
	<48C19759.90402@esilo.com>
	<27615.1221619326@sss.pgh.pa.us>
	<48D072E3.6010703@esilo.com>
	<28673.1221622817@sss.pgh.pa.us>
	<48D080B0.6070104@esilo.com>
	<454.1221626213@sss.pgh.pa.us>
	<48D0DFBE.9050900@esilo.com>
	<8872.1221653812@sss.pgh.pa.us>
	<48D1041D.5070808@esilo.com>
	<10839.1221658586@sss.pgh.pa.us>
	<48D11443.4010608@esilo.com>
	<48D11631.8070709@esilo.com>
	<28666.1221840662@sss.pgh.pa.us>

Tom Lane wrote:
> 
> I'll go ahead and apply this patch in a little bit, but if you concur
> with the above reasoning, please put together a followon patch to add
> such a function.
> 
> 			regards, tom lane
> 
> 

I attached a patch.  You have to copy the events in PQmakeEmptyPGResult 
because there is no where else to do this, other than copyresult but 
that is different because it copies from a result not a conn.

PQmakeEmptyPGResult - must copy events here
PQsetResultAttrs - set attributes
PQsetvalue - set tuple values
PQfireResultCreateEvents(conn,res) - now fire resultcreate event

PQgetResult now calls PQfireResultCreateEvents.

BTW, the event system might be an alternative solution for PGNoticeHooks 
(PGEVT_NOTICE).

-- 
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

Attachments:

pgevents.patch (text/plain, 7.3K) download Index: doc/src/sgml/libpq.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/libpq.sgml,v retrieving revision 1.262 diff -C6 -r1.262 libpq.sgml *** doc/src/sgml/libpq.sgml 19 Sep 2008 16:40:40 -0000 1.262 --- doc/src/sgml/libpq.sgml 19 Sep 2008 18:05:55 -0000 *************** *** 4592,4604 **** <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 registered in the connection are copied into the <structname>PGresult</structname> (but they don't get ! <literal>PGEVT_RESULTCREATE</> calls). 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. </para> </listitem> </varlistentry> --- 4592,4606 ---- <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 registered in the connection are copied into the <structname>PGresult</structname> (but they don't get ! <literal>PGEVT_RESULTCREATE</> calls). Although, ! <function>PQfireResultCreateEvents</function> can be used to fire ! <literal>PGEVT_RESULTCREATE</> events. 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. </para> </listitem> </varlistentry> *************** *** 5242,5253 **** --- 5244,5279 ---- void *PQresultInstanceData(const PGresult *res, PGEventProc proc); </synopsis> </para> </listitem> </varlistentry> </variablelist> + + <varlistentry> + <term> + <function>PQfireResultCreateEvents</function> + <indexterm> + <primary>PQfireResultCreateEvents</primary> + </indexterm> + </term> + <listitem> + <para> + Manually fires a <literal>PGEVT_RESULTCREATE</literal> event. This is + useful for applications that create a result using + <function>PQmakeEmptyPGResult</function>, which does not fire a + <literal>PGEVT_RESULTCREATE</literal> event. It allows an application + to create the result, fill it and then fire the creation event. This + returns non-zero for success and zero for failure. + + <synopsis> + int PQfireResultCreateEvents(const PGconn conn, PGresult *res); + </synopsis> + </para> + </listitem> + </varlistentry> + </variablelist> </sect2> <sect2 id="libpq-events-example"> <title>Event Example</title> <para> Index: src/interfaces/libpq/exports.txt =================================================================== RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/exports.txt,v retrieving revision 1.20 diff -C6 -r1.20 exports.txt *** src/interfaces/libpq/exports.txt 17 Sep 2008 04:31:08 -0000 1.20 --- src/interfaces/libpq/exports.txt 19 Sep 2008 18:05:55 -0000 *************** *** 147,152 **** --- 147,153 ---- PQresultAlloc 145 PQregisterEventProc 146 PQinstanceData 147 PQsetInstanceData 148 PQresultInstanceData 149 PQresultSetInstanceData 150 + PQfireResultCreateEvents 151 Index: src/interfaces/libpq/fe-exec.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v retrieving revision 1.199 diff -C6 -r1.199 fe-exec.c *** src/interfaces/libpq/fe-exec.c 19 Sep 2008 16:40:40 -0000 1.199 --- src/interfaces/libpq/fe-exec.c 19 Sep 2008 18:05:55 -0000 *************** *** 1595,1630 **** libpq_gettext("unexpected asyncStatus: %d\n"), (int) conn->asyncStatus); res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); break; } ! if (res) ! { ! int i; ! ! for (i = 0; i < res->nEvents; i++) ! { ! PGEventResultCreate evt; ! ! evt.conn = conn; ! evt.result = res; ! if (!res->events[i].proc(PGEVT_RESULTCREATE, &evt, ! res->events[i].passThrough)) ! { ! printfPQExpBuffer(&conn->errorMessage, ! libpq_gettext("PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n"), ! res->events[i].name); ! pqSetResultError(res, conn->errorMessage.data); ! res->resultStatus = PGRES_FATAL_ERROR; ! break; ! } ! res->events[i].resultInitialized = TRUE; ! } ! } ! return res; } /* * PQexec --- 1595,1608 ---- libpq_gettext("unexpected asyncStatus: %d\n"), (int) conn->asyncStatus); res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); break; } ! /* Function performs error handling: message and resultStatus. */ ! (void) PQfireResultCreateEvents(conn, res); return res; } /* * PQexec Index: src/interfaces/libpq/libpq-events.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/libpq-events.c,v retrieving revision 1.2 diff -C6 -r1.2 libpq-events.c *** src/interfaces/libpq/libpq-events.c 19 Sep 2008 16:40:40 -0000 1.2 --- src/interfaces/libpq/libpq-events.c 19 Sep 2008 18:05:55 -0000 *************** *** 172,177 **** --- 172,209 ---- for (i = 0; i < result->nEvents; i++) if (result->events[i].proc == proc) return result->events[i].data; return NULL; } + + int + PQfireResultCreateEvents(const PGconn *conn, PGresult *res) + { + int i; + + if (!conn || !res) + return FALSE; + + for (i = 0; i < res->nEvents; i++) + { + PGEventResultCreate evt; + + evt.conn = conn; + evt.result = res; + if (!res->events[i].proc(PGEVT_RESULTCREATE, &evt, + res->events[i].passThrough)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n"), + res->events[i].name); + pqSetResultError(res, conn->errorMessage.data); + res->resultStatus = PGRES_FATAL_ERROR; + return FALSE; + } + + res->events[i].resultInitialized = TRUE; + } + + return TRUE; + } + Index: src/interfaces/libpq/libpq-events.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/libpq-events.h,v retrieving revision 1.1 diff -C6 -r1.1 libpq-events.h *** src/interfaces/libpq/libpq-events.h 17 Sep 2008 04:31:08 -0000 1.1 --- src/interfaces/libpq/libpq-events.h 19 Sep 2008 18:05:55 -0000 *************** *** 81,91 **** --- 81,93 ---- /* Sets the PGresult instance data for the provided proc to data. */ extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data); /* Gets the PGresult instance data for the provided proc. */ extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); + extern int PQfireResultCreateEvents(const PGconn *conn, PGresult *res); + #ifdef __cplusplus } #endif #endif /* LIBPQ_EVENTS_H */

view thread (31+ messages)  latest in thread

Message-ID: <48D3EBEC.1040503@esilo.com>
Permalink:  ../48D3EBEC.1040503@esilo.com/
Also on:    postgresql.org/message-id/48D3EBEC.1040503@esilo.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-patches@postgresql.org
  Cc: ac@esilo.com, tgl@sss.pgh.pa.us, alvherre@commandprompt.com, pgsql-hackers@postgresql.org, mmoncure@gmail.com
  Subject: Re: [PATCHES] libpq events patch (with sgml docs)
  In-Reply-To: <48D3EBEC.1040503@esilo.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox