We have put up a new version of our extensions to the libpq api, here: http://www.esilo.com/projects/postgresql/libpq/typesys-beta-0.9.tar.gz
Four functions are getting dropped and will be replaced with a generic version taking a va_list. Also, in some functions result format is being moved to the end in order to be more compatible with existing functions. These functions are getting dropped: PQexecParamsf (conn, resfmt, query, ...) PQexecPreparedf(conn, resfmt, stmt, typespec, ...) PQsendQueryParamsf(conn, resfmt, query, ...) PQsendQueryPreparedf(conn, resfmt, stmt, typespec, ...) The goal of the 'f' functions was to be able to execute a parameterized query in one line. They had some downsides: *) four functions added to API that did essentially the same thing *) awkward to wrap, doesn't take a va_list (most large projects will wrap PQ functions for error handling, etc) *) prevents some low hanging efficiency fruit, by not allowing the PGparam to be reused *) taking the above, didn't meet the main goal (easiness). In the end, they were not useful enough to justify their inclusion into the api (we determined this from practical use). And 'PQputvf' is being added; int PQputvf( PGparam *param, char *stmtBuf, /* If not NULL, replaces %int4 with $1 syntax */ size_t stmtBufLen, /* If stmtbuf is too small, this errors out */ const char *spec, /* specifier string, with ir without SQL */ va_list ap); This function, while low level, is designed to be used with high level wrappers since it takes a va_list...after some reflection, we thought it better to provide the basic tools for writing high level wrappers rather than trying to make them all. Consider the following user-land wrapper...connection and error handling can be handled to the requirements of the application, and the query can be executed with the method of choice (exec/send). PQputvf stacks the param object from arguments passed through the va_list and optionally rewrites (%int4->$1) the query passed into 'buf' which can be NULL. /* User application wrapper */ PGresult *myexec(PGconn *conn, const char *cmdSpec, ...) { int n; PGresult *res; va_list ap; static char stmt[8192]; /* app specific buffer size */ static PQparam *param = NULL; /* param reused */ if(!param) param = PQparamCreate(conn); va_start(ap, stmt); n = PQputvf(param, stmt, sizeof(stmt), cmdSpec, ap); va_end(ap); /* put failed... (error is in param object) */ if(!n) return NULL; /* always return binary */ res = PQparamExec(conn, param, stmt, 1); return res; } /* usage, puts two int4 and executes "SELECT $1 + $2" */ PGresult *res = myexec(conn, "SELECT %int4 + %int4", 1234, 5678); In our applications, we often push error handling and connection management into a wrapper function like the above...to do this properly required a va_list style put function. The f versions were too abstracted to do these kinds of things. Merlin & Andrew eSilo ---------------------------(end of broadcast)--------------------------- TIP 4: Have you searched our list archives? http://archives.postgresql.org