- publishing free software manuals
The PostgreSQL 9.0 Reference Manual - Volume 2 - Programming Guide
by The PostgreSQL Global Development Group
Paperback (6"x9"), 478 pages
ISBN 9781906966065
RRP £14.95 ($19.95)

Sales of this book support the PostgreSQL project! Get a printed copy>>>

1.12.4 Event Example

Here is a skeleton example of managing private data associated with libpq connections and results.

/* required header for libpq events (note: includes
   libpq-fe.h) */
#include <libpq-events.h>

/* The instanceData */
typedef struct {
  int n;
  char *str;
} mydata;

/* PGEventProc */
static int myEventProc(PGEventId evtId, void *evtInfo,
                       void *passThrough);

int
main(void)
{
  mydata *data;
  PGresult *res;
  PGconn *conn = PQconnectdb("dbname = postgres");

  if (PQstatus(conn) != CONNECTION_OK) {
    fprintf(stderr, "Connection to database failed: %s",
            PQerrorMessage(conn));
    PQfinish(conn);
    return 1;
  }

  /* called once on any connection that should receive
     events. Sends a PGEVT_REGISTER to myEventProc. */
  if (!PQregisterEventProc
      (conn, myEventProc, "mydata_proc", NULL)) {
    fprintf(stderr, "Cannot register PGEventProc\n");
    PQfinish(conn);
    return 1;
  }

  /* conn instanceData is available */
  data = PQinstanceData(conn, myEventProc);

  /* Sends a PGEVT_RESULTCREATE to myEventProc */
  res = PQexec(conn, "SELECT 1 + 1");

  /* result instanceData is available */
  data = PQresultInstanceData(res, myEventProc);

  /* If PG_COPYRES_EVENTS is used, sends a PGEVT_RESULTCOPY
     to myEventProc */
  res_copy =
      PQcopyResult(res,
                   PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);

  /* result instanceData is available if PG_COPYRES_EVENTS
     was used during the PQcopyResult call. */
  data = PQresultInstanceData(res_copy, myEventProc);

  /* Both clears send a PGEVT_RESULTDESTROY to myEventProc */
  PQclear(res);
  PQclear(res_copy);

  /* Sends a PGEVT_CONNDESTROY to myEventProc */
  PQfinish(conn);

  return 0;
}

static int
myEventProc(PGEventId evtId, void *evtInfo,
            void *passThrough)
{
  switch (evtId) {
  case PGEVT_REGISTER:
    {
      PGEventRegister *e = (PGEventRegister *) evtInfo;
      mydata *data = get_mydata(e->conn);

      /* associate app specific data with connection */
      PQsetInstanceData(e->conn, myEventProc, data);
      break;
    }

  case PGEVT_CONNRESET:
    {
      PGEventConnReset *e = (PGEventConnReset *) evtInfo;
      mydata *data = PQinstanceData(e->conn, myEventProc);

      if (data)
        memset(data, 0, sizeof(mydata));
      break;
    }

  case PGEVT_CONNDESTROY:
    {
      PGEventConnDestroy *e =
          (PGEventConnDestroy *) evtInfo;
      mydata *data = PQinstanceData(e->conn, myEventProc);

      /* free instance data because the conn is being
         destroyed */
      if (data)
        free_mydata(data);
      break;
    }

  case PGEVT_RESULTCREATE:
    {
      PGEventResultCreate *e =
          (PGEventResultCreate *) evtInfo;
      mydata *conn_data =
          PQinstanceData(e->conn, myEventProc);
      mydata *res_data = dup_mydata(conn_data);

      /* associate app specific data with result (copy it
         from conn) */
      PQsetResultInstanceData(e->result, myEventProc,
                              res_data);
      break;
    }

  case PGEVT_RESULTCOPY:
    {
      PGEventResultCopy *e = (PGEventResultCopy *) evtInfo;
      mydata *src_data =
          PQresultInstanceData(e->src, myEventProc);
      mydata *dest_data = dup_mydata(src_data);

      /* associate app specific data with result (copy it
         from a result) */
      PQsetResultInstanceData(e->dest, myEventProc,
                              dest_data);
      break;
    }

  case PGEVT_RESULTDESTROY:
    {
      PGEventResultDestroy *e =
          (PGEventResultDestroy *) evtInfo;
      mydata *data =
          PQresultInstanceData(e->result, myEventProc);

      /* free instance data because the result is being
         destroyed */
      if (data)
        free_mydata(data);
      break;
    }

    /* unknown event id, just return TRUE. */
  default:
    break;
  }

  return TRUE;  /* event processing succeeded */
}
ISBN 9781906966065The PostgreSQL 9.0 Reference Manual - Volume 2 - Programming GuideSee the print edition