typedef struct PGconn PGconn; #define PG_FUNCS \ X(PQconnectdb, PGconn *, const char *) \ X(PQerrorMessage, char *, const PGconn *) \ X(PQfinish, void, PGconn *) \ X(PQlibVersion, int, void) \ X(PQserverVersion, int, const PGconn *) \ X(PQstatus, int, const PGconn *) #define X(n, r, ...) static r (*n)(__VA_ARGS__); PG_FUNCS #undef X static void fupg_load() { void *handle = dlopen("libpq.so", RTLD_LAZY); if (!handle) croak("Unable to load libpq: %s", dlerror()); #define X(n, ...) if (!(n = dlsym(handle, #n))) croak("Unable to load libpq: %s", dlerror()); PG_FUNCS #undef X } #undef PG_FUNCS typedef struct { PGconn *conn; } fupg_conn; fupg_conn *fupg_connect(pTHX_ const char *str) { SV *sv; PGconn *conn = PQconnectdb(str); if (PQstatus(conn) != 0) { sv = newSVpvf("FU::PG connection error: %s", PQerrorMessage(conn)); PQfinish(conn); croak_sv(sv); } fupg_conn *c = safecalloc(1, sizeof(fupg_conn)); c->conn = conn; return c; } static void fupg_destroy(fupg_conn *c) { PQfinish(c->conn); safefree(c); }