terom@12: #ifndef EVPQ_H terom@12: #define EVPQ_H terom@12: terom@12: /* terom@12: * Convenience functions for using libpq (the PostgreSQL client library) with libevent. terom@12: */ terom@12: terom@12: #include terom@12: #include terom@12: terom@12: /* terom@12: * Our PGconn context wrapper. terom@12: */ terom@12: struct evpq_conn; terom@12: terom@12: /* terom@12: * Callback functions used terom@12: */ terom@12: struct evpq_callback_info { terom@12: /* terom@12: * This evpq_conn has connected succesfully \o/ terom@12: */ terom@12: void (*fn_connected)(struct evpq_conn *conn, void *arg); terom@12: terom@12: /* terom@12: * Got a result. terom@12: */ terom@12: void (*fn_result)(struct evpq_conn *conn, PGresult *result, void *arg); terom@12: terom@12: /* terom@12: * No more results for the query terom@12: */ terom@12: void (*fn_done)(struct evpq_conn *conn, void *arg); terom@12: terom@12: /* terom@12: * Something caused this evpq_conn to fail :( terom@12: * terom@12: * XXX: add a `what` arg? terom@12: */ terom@12: void (*fn_failure)(struct evpq_conn *conn, void *arg); terom@12: terom@12: /* terom@12: * Arg to pass through to all callbacks. terom@12: */ terom@12: void *cb_arg; terom@12: }; terom@12: terom@12: /* terom@12: * evpq_conn states terom@12: */ terom@12: enum evpq_state { terom@12: EVPQ_INIT, terom@12: terom@12: EVPQ_CONNECT, terom@12: EVPQ_CONNECTED, terom@12: terom@12: EVPQ_QUERY, terom@12: terom@12: EVPQ_FAILURE, terom@12: }; terom@12: terom@12: /* terom@12: * Create a new evpq connection. terom@12: * terom@12: * This corresponds directly to PQconnectStart, and handles all the libevent setup/polling needed. terom@12: * terom@12: * The connection will initially be in the EVPQ_CONNECT state, and will then either callback via fn_connected terom@12: * (EVPQ_CONNECTED) or fn_failure (EVPQ_FAILURE). terom@12: * terom@12: * cb_info contains the callback functions (and the user argument) to use. terom@12: */ terom@12: struct evpq_conn *evpq_connect (struct event_base *ev_base, const char *conninfo, const struct evpq_callback_info cb_info); terom@12: terom@12: /* terom@12: * Execute a query. terom@12: * terom@12: * This corresponds directly to PQsendQuery. This evpq must be in the EVPQ_CONNECTED state, so you must wait after terom@12: * calling evpq_connect, and you may not run two queries at the same time. terom@12: * terom@12: * The query will result in a series of fn_result (EVPQ_RESULT) calls (if multiple queries in the query string), terom@12: * followed by a fn_done (EVPQ_CONNECTED). terom@12: */ terom@12: int evpq_query (struct evpq_conn *conn, const char *command); terom@12: terom@12: /* terom@12: * Get the actual PGconn. terom@12: * terom@12: * This can safely be used to access all of the normal PQ functions. terom@12: */ terom@12: const PGconn *evpq_pgconn (struct evpq_conn *conn); terom@12: terom@12: // convenience wrappers terom@12: #define evpq_error_message(conn) PQerrorMessage(evpq_pgconn(conn)) terom@12: terom@12: terom@12: #endif /* EVPQ_H */