1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
8
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
10
HREF="mailto:pgsql-docs@postgresql.org"><LINK
12
TITLE="PostgreSQL 9.1beta1 Documentation"
13
HREF="index.html"><LINK
15
TITLE="libpq - C Library"
16
HREF="libpq.html"><LINK
18
TITLE="Notice Processing"
19
HREF="libpq-notice-processing.html"><LINK
21
TITLE="Environment Variables"
22
HREF="libpq-envars.html"><LINK
25
HREF="stylesheet.css"><META
26
HTTP-EQUIV="Content-Type"
27
CONTENT="text/html; charset=ISO-8859-1"><META
29
CONTENT="2011-04-27T21:20:33"></HEAD
35
SUMMARY="Header navigation table"
47
>PostgreSQL 9.1beta1 Documentation</A
56
TITLE="Notice Processing"
57
HREF="libpq-notice-processing.html"
66
TITLE="libpq - C Library"
83
TITLE="libpq - C Library"
92
TITLE="Environment Variables"
93
HREF="libpq-envars.html"
108
>31.12. Event System</A
114
>'s event system is designed to notify
115
registered event handlers about interesting
119
> events, such as the creation or
127
> objects. A principal use case is that
128
this allows applications to associate their own data with a
136
and ensure that that data is freed at an appropriate time.
139
> Each registered event handler is associated with two pieces of data,
147
pointers. There is a <I
150
> pointer that is provided
151
by the application when the event handler is registered with a
155
>. The passthrough pointer never changes for the
163
generated from it; so if used, it must point to long-lived data.
164
In addition there is an <I
167
> pointer, which starts
178
This pointer can be manipulated using the
181
>PQinstanceData</CODE
185
>PQsetInstanceData</CODE
189
>PQresultInstanceData</CODE
193
>PQsetResultInstanceData</CODE
194
> functions. Note that
195
unlike the passthrough pointer, instance data of a <TT
199
is not automatically inherited by <TT
206
> does not know what passthrough
207
and instance data pointers point to (if anything) and will never attempt
208
to free them — that is the responsibility of the event handler.
215
NAME="LIBPQ-EVENTS-TYPES"
216
>31.12.1. Event Types</A
222
> names the types of events handled by
223
the event system. All its values have names beginning with
227
>. For each event type, there is a corresponding
228
event info structure that carries the parameters passed to the event
229
handlers. The event types are:
238
NAME="LIBPQ-PGEVT-REGISTER"
246
> The register event occurs when <CODE
248
>PQregisterEventProc</CODE
250
is called. It is the ideal time to initialize any
254
> an event procedure may need. Only one
255
register event will be fired per event handler per connection. If the
256
event procedure fails, the registration is aborted.
263
} PGEventRegister;</PRE
269
> event is received, the
273
> pointer should be cast to a
276
>PGEventRegister *</TT
277
>. This structure contains a
281
> that should be in the
285
> status; guaranteed if one calls
288
>PQregisterEventProc</CODE
289
> right after obtaining a good
293
>. When returning a failure code, all
294
cleanup must be performed as no <TT
296
>PGEVT_CONNDESTROY</TT
303
NAME="LIBPQ-PGEVT-CONNRESET"
311
> The connection reset event is fired on completion of
319
both cases, the event is only fired if the reset was successful. If
320
the event procedure fails, the entire connection reset will fail; the
335
>PGRES_POLLING_FAILED</TT
343
} PGEventConnReset;</PRE
349
> event is received, the
353
> pointer should be cast to a
356
>PGEventConnReset *</TT
357
>. Although the contained
361
> was just reset, all event data remains
362
unchanged. This event should be used to reset/reload/requery any
366
>. Note that even if the
367
event procedure fails to process <TT
373
>PGEVT_CONNDESTROY</TT
374
> event when the connection
380
NAME="LIBPQ-PGEVT-CONNDESTROY"
384
>PGEVT_CONNDESTROY</TT
388
> The connection destroy event is fired in response to
392
>. It is the event procedure's
393
responsibility to properly clean up its event data as libpq has no
394
ability to manage this memory. Failure to clean up will lead
402
} PGEventConnDestroy;</PRE
407
>PGEVT_CONNDESTROY</TT
408
> event is received, the
412
> pointer should be cast to a
415
>PGEventConnDestroy *</TT
416
>. This event is fired
420
> performing any other cleanup.
421
The return value of the event procedure is ignored since there is no
422
way of indicating a failure from <CODE
426
an event procedure failure should not abort the process of cleaning up
432
NAME="LIBPQ-PGEVT-RESULTCREATE"
436
>PGEVT_RESULTCREATE</TT
440
> The result creation event is fired in response to any query execution
441
function that generates a result, including
445
>. This event will only be fired after
446
the result has been created successfully.
454
} PGEventResultCreate;</PRE
459
>PGEVT_RESULTCREATE</TT
460
> event is received, the
464
> pointer should be cast to a
467
>PGEventResultCreate *</TT
472
> is the connection used to generate the
473
result. This is the ideal place to initialize any
477
> that needs to be associated with the
478
result. If the event procedure fails, the result will be cleared and
479
the failure will be propagated. The event procedure must not try to
483
> the result object for itself. When returning a
484
failure code, all cleanup must be performed as no
487
>PGEVT_RESULTDESTROY</TT
488
> event will be sent.
493
NAME="LIBPQ-PGEVT-RESULTCOPY"
497
>PGEVT_RESULTCOPY</TT
501
> The result copy event is fired in response to
505
>. This event will only be fired after
506
the copy is complete. Only event procedures that have
507
successfully handled the <TT
509
>PGEVT_RESULTCREATE</TT
513
>PGEVT_RESULTCOPY</TT
514
> event for the source result
517
>PGEVT_RESULTCOPY</TT
526
} PGEventResultCopy;</PRE
531
>PGEVT_RESULTCOPY</TT
532
> event is received, the
536
> pointer should be cast to a
539
>PGEventResultCopy *</TT
544
> result is what was copied while the
548
> result is the copy destination. This event
549
can be used to provide a deep copy of <TT
556
> cannot do that. If the event
557
procedure fails, the entire copy operation will fail and the
561
> result will be cleared. When returning a
562
failure code, all cleanup must be performed as no
565
>PGEVT_RESULTDESTROY</TT
566
> event will be sent for the
572
NAME="LIBPQ-PGEVT-RESULTDESTROY"
576
>PGEVT_RESULTDESTROY</TT
580
> The result destroy event is fired in response to a
584
>. It is the event procedure's
585
responsibility to properly clean up its event data as libpq has no
586
ability to manage this memory. Failure to clean up will lead
594
} PGEventResultDestroy;</PRE
599
>PGEVT_RESULTDESTROY</TT
600
> event is received, the
604
> pointer should be cast to a
607
>PGEventResultDestroy *</TT
608
>. This event is fired
612
> performing any other cleanup.
613
The return value of the event procedure is ignored since there is no
614
way of indicating a failure from <CODE
618
an event procedure failure should not abort the process of cleaning up
630
NAME="LIBPQ-EVENTS-PROC"
631
>31.12.2. Event Callback Procedure</A
640
NAME="LIBPQ-PGEVENTPROC"
652
> is a typedef for a pointer to an
653
event procedure, that is, the user callback function that receives
654
events from libpq. The signature of an event procedure must be
658
>int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)</PRE
664
> parameter indicates which
668
> event occurred. The
672
> pointer must be cast to the appropriate
673
structure type to obtain further information about the event.
677
> parameter is the pointer
680
>PQregisterEventProc</CODE
682
procedure was registered. The function should return a non-zero value
683
if it succeeds and zero if it fails.
686
> A particular event procedure can be registered only once in any
690
>. This is because the address of the procedure
691
is used as a lookup key to identify the associated instance data.
712
> On Windows, functions can have two different addresses: one visible
713
from outside a DLL and another visible from inside the DLL. One
714
should be careful that only one of these addresses is used with
718
>'s event-procedure functions, else confusion will
719
result. The simplest rule for writing code that will work is to
720
ensure that event procedures are declared <TT
724
procedure's address must be available outside its own source file,
725
expose a separate function to return the address.
740
NAME="LIBPQ-EVENTS-FUNCS"
741
>31.12.3. Event Support Functions</A
750
NAME="LIBPQ-PQREGISTEREVENTPROC"
754
>PQregisterEventProc</CODE
759
> Registers an event callback procedure with libpq.
763
>int PQregisterEventProc(PGconn *conn, PGEventProc proc,
764
const char *name, void *passThrough);</PRE
768
> An event procedure must be registered once on each
772
> you want to receive events about. There is no
773
limit, other than memory, on the number of event procedures that
774
can be registered with a connection. The function returns a non-zero
775
value if it succeeds and zero if it fails.
781
> argument will be called when a libpq
782
event is fired. Its memory address is also used to lookup
790
argument is used to refer to the event procedure in error messages.
791
This value cannot be <TT
794
> or a zero-length string. The name string is
798
>, so what is passed need not be
806
> whenever an event occurs. This
815
NAME="LIBPQ-PQSETINSTANCEDATA"
819
>PQsetInstanceData</CODE
824
> Sets the connection <TT
838
returns non-zero for success and zero for failure. (Failure is
842
> has not been properly
850
>int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);</PRE
856
NAME="LIBPQ-PQINSTANCEDATA"
860
>PQinstanceData</CODE
873
associated with procedure <TT
884
>void *PQinstanceData(const PGconn *conn, PGEventProc proc);</PRE
890
NAME="LIBPQ-PQRESULTSETINSTANCEDATA"
894
>PQresultSetInstanceData</CODE
899
> Sets the result's <TT
910
non-zero for success and zero for failure. (Failure is only
914
> has not been properly registered
919
>int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);</PRE
925
NAME="LIBPQ-PQRESULTINSTANCEDATA"
929
>PQresultInstanceData</CODE
934
> Returns the result's <TT
937
> associated with <TT
948
>void *PQresultInstanceData(const PGresult *res, PGEventProc proc);</PRE
960
NAME="LIBPQ-EVENTS-EXAMPLE"
961
>31.12.4. Event Example</A
964
> Here is a skeleton example of managing private data associated with
965
libpq connections and results.
968
CLASS="PROGRAMLISTING"
969
>/* required header for libpq events (note: includes libpq-fe.h) */
970
#include <libpq-events.h>
972
/* The instanceData */
980
static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough);
987
PGconn *conn = PQconnectdb("dbname = postgres");
989
if (PQstatus(conn) != CONNECTION_OK)
991
fprintf(stderr, "Connection to database failed: %s",
992
PQerrorMessage(conn));
997
/* called once on any connection that should receive events.
998
* Sends a PGEVT_REGISTER to myEventProc.
1000
if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL))
1002
fprintf(stderr, "Cannot register PGEventProc\n");
1007
/* conn instanceData is available */
1008
data = PQinstanceData(conn, myEventProc);
1010
/* Sends a PGEVT_RESULTCREATE to myEventProc */
1011
res = PQexec(conn, "SELECT 1 + 1");
1013
/* result instanceData is available */
1014
data = PQresultInstanceData(res, myEventProc);
1016
/* If PG_COPYRES_EVENTS is used, sends a PGEVT_RESULTCOPY to myEventProc */
1017
res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);
1019
/* result instanceData is available if PG_COPYRES_EVENTS was
1020
* used during the PQcopyResult call.
1022
data = PQresultInstanceData(res_copy, myEventProc);
1024
/* Both clears send a PGEVT_RESULTDESTROY to myEventProc */
1028
/* Sends a PGEVT_CONNDESTROY to myEventProc */
1035
myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
1039
case PGEVT_REGISTER:
1041
PGEventRegister *e = (PGEventRegister *)evtInfo;
1042
mydata *data = get_mydata(e->conn);
1044
/* associate app specific data with connection */
1045
PQsetInstanceData(e->conn, myEventProc, data);
1049
case PGEVT_CONNRESET:
1051
PGEventConnReset *e = (PGEventConnReset *)evtInfo;
1052
mydata *data = PQinstanceData(e->conn, myEventProc);
1055
memset(data, 0, sizeof(mydata));
1059
case PGEVT_CONNDESTROY:
1061
PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
1062
mydata *data = PQinstanceData(e->conn, myEventProc);
1064
/* free instance data because the conn is being destroyed */
1070
case PGEVT_RESULTCREATE:
1072
PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
1073
mydata *conn_data = PQinstanceData(e->conn, myEventProc);
1074
mydata *res_data = dup_mydata(conn_data);
1076
/* associate app specific data with result (copy it from conn) */
1077
PQsetResultInstanceData(e->result, myEventProc, res_data);
1081
case PGEVT_RESULTCOPY:
1083
PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
1084
mydata *src_data = PQresultInstanceData(e->src, myEventProc);
1085
mydata *dest_data = dup_mydata(src_data);
1087
/* associate app specific data with result (copy it from a result) */
1088
PQsetResultInstanceData(e->dest, myEventProc, dest_data);
1092
case PGEVT_RESULTDESTROY:
1094
PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
1095
mydata *data = PQresultInstanceData(e->result, myEventProc);
1097
/* free instance data because the result is being destroyed */
1103
/* unknown event id, just return TRUE. */
1108
return TRUE; /* event processing succeeded */
1117
SUMMARY="Footer navigation table"
1128
HREF="libpq-notice-processing.html"
1146
HREF="libpq-envars.html"
1156
>Notice Processing</TD
1170
>Environment Variables</TD
b'\\ No newline at end of file'