summaryrefslogtreecommitdiff
path: root/srclib/apr-util/dbd/apr_dbd_pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to 'srclib/apr-util/dbd/apr_dbd_pgsql.c')
-rw-r--r--srclib/apr-util/dbd/apr_dbd_pgsql.c84
1 files changed, 52 insertions, 32 deletions
diff --git a/srclib/apr-util/dbd/apr_dbd_pgsql.c b/srclib/apr-util/dbd/apr_dbd_pgsql.c
index a15c24d5..76bfa0c1 100644
--- a/srclib/apr-util/dbd/apr_dbd_pgsql.c
+++ b/srclib/apr-util/dbd/apr_dbd_pgsql.c
@@ -18,10 +18,16 @@
#if APU_HAVE_PGSQL
+#include "apu_config.h"
+
#include <ctype.h>
#include <stdlib.h>
+#ifdef HAVE_LIBPQ_FE_H
#include <libpq-fe.h>
+#elif defined(HAVE_POSTGRESQL_LIBPQ_FE_H)
+#include <postgresql/libpq-fe.h>
+#endif
#include "apr_strings.h"
#include "apr_time.h"
@@ -57,12 +63,19 @@ struct apr_dbd_row_t {
struct apr_dbd_prepared_t {
const char *name;
int prepared;
+ int nargs;
};
#define dbd_pgsql_is_success(x) (((x) == PGRES_EMPTY_QUERY) \
|| ((x) == PGRES_COMMAND_OK) \
|| ((x) == PGRES_TUPLES_OK))
+static apr_status_t clear_result(void *data)
+{
+ PQclear(data);
+ return APR_SUCCESS;
+}
+
static int dbd_pgsql_select(apr_pool_t *pool, apr_dbd_t *sql,
apr_dbd_results_t **results,
const char *query, int seek)
@@ -97,7 +110,7 @@ static int dbd_pgsql_select(apr_pool_t *pool, apr_dbd_t *sql,
(*results)->ntuples = PQntuples(res);
(*results)->sz = PQnfields(res);
(*results)->random = seek;
- apr_pool_cleanup_register(pool, res, (void*)PQclear,
+ apr_pool_cleanup_register(pool, res, clear_result,
apr_pool_cleanup_null);
}
else {
@@ -140,8 +153,7 @@ static int dbd_pgsql_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
if (res->random) {
if (row->n >= res->ntuples) {
*rowp = NULL;
- apr_pool_cleanup_kill(pool, res->res, (void*)PQclear);
- PQclear(res->res);
+ apr_pool_cleanup_run(pool, res->res, clear_result);
res->res = NULL;
return -1;
}
@@ -221,7 +233,7 @@ static const char *dbd_pgsql_escape(apr_pool_t *pool, const char *arg,
apr_dbd_t *sql)
{
size_t len = strlen(arg);
- char *ret = apr_palloc(pool, len + 1);
+ char *ret = apr_palloc(pool, 2*(len + 1));
PQescapeString(ret, arg, len);
return ret;
}
@@ -236,7 +248,6 @@ static int dbd_pgsql_prepare(apr_pool_t *pool, apr_dbd_t *sql,
size_t i = 0;
const char *args[QUERY_MAX_ARGS];
size_t alen;
- int nargs = 0;
int ret;
PGresult *res;
char *pgquery;
@@ -245,11 +256,12 @@ static int dbd_pgsql_prepare(apr_pool_t *pool, apr_dbd_t *sql,
if (!*statement) {
*statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t));
}
+ (*statement)->nargs = 0;
/* Translate from apr_dbd to native query format */
for (sqlptr = (char*)query; *sqlptr; ++sqlptr) {
if (sqlptr[0] == '%') {
if (isalpha(sqlptr[1])) {
- ++nargs;
+ ++(*statement)->nargs;
}
else if (sqlptr[1] == '%') {
++sqlptr;
@@ -257,8 +269,8 @@ static int dbd_pgsql_prepare(apr_pool_t *pool, apr_dbd_t *sql,
}
}
length = strlen(query) + 1;
- if (nargs > 8) {
- length += nargs - 8;
+ if ((*statement)->nargs > 8) {
+ length += (*statement)->nargs - 8;
}
pgptr = pgquery = apr_palloc(pool, length) ;
@@ -313,10 +325,10 @@ static int dbd_pgsql_prepare(apr_pool_t *pool, apr_dbd_t *sql,
length = strlen(label);
memcpy(sqlptr, label, length);
sqlptr += length;
- if (nargs > 0) {
+ if ((*statement)->nargs > 0) {
memcpy(sqlptr, " (",2);
sqlptr += 2;
- for (i=0; i<nargs; ++i) {
+ for (i=0; i < (*statement)->nargs; ++i) {
alen = strlen(args[i]);
memcpy(sqlptr, args[i], alen);
sqlptr += alen;
@@ -353,6 +365,11 @@ static int dbd_pgsql_pquery(apr_pool_t *pool, apr_dbd_t *sql,
{
int ret;
PGresult *res;
+
+ if (sql->trans && sql->trans->errnum) {
+ return sql->trans->errnum;
+ }
+
if (statement->prepared) {
res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0, 0,
0);
@@ -366,6 +383,7 @@ static int dbd_pgsql_pquery(apr_pool_t *pool, apr_dbd_t *sql,
if (dbd_pgsql_is_success(ret)) {
ret = 0;
}
+ *nrows = atoi(PQcmdTuples(res));
PQclear(res);
}
else {
@@ -382,22 +400,21 @@ static int dbd_pgsql_pvquery(apr_pool_t *pool, apr_dbd_t *sql,
int *nrows, apr_dbd_prepared_t *statement,
va_list args)
{
- const char *arg;
- int nargs = 0;
- const char *values[QUERY_MAX_ARGS];
+ const char **values;
+ int i;
if (sql->trans && sql->trans->errnum) {
return sql->trans->errnum;
}
- while ( arg = va_arg(args, const char*), arg ) {
- if ( nargs >= QUERY_MAX_ARGS) {
- va_end(args);
- return -1;
- }
- values[nargs++] = apr_pstrdup(pool, arg);
+
+ values = apr_palloc(pool, sizeof(*values) * statement->nargs);
+
+ for (i = 0; i < statement->nargs; i++) {
+ values[i] = apr_pstrdup(pool, va_arg(args, const char*));
}
- values[nargs] = NULL;
- return dbd_pgsql_pquery(pool, sql, nrows, statement, nargs, values);
+
+ return dbd_pgsql_pquery(pool, sql, nrows, statement,
+ statement->nargs, values);
}
static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql,
@@ -408,6 +425,11 @@ static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql,
PGresult *res;
int rv;
int ret = 0;
+
+ if (sql->trans && sql->trans->errnum) {
+ return sql->trans->errnum;
+ }
+
if (seek) { /* synchronous query */
if (statement->prepared) {
res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0,
@@ -442,7 +464,7 @@ static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql,
(*results)->ntuples = PQntuples(res);
(*results)->sz = PQnfields(res);
(*results)->random = seek;
- apr_pool_cleanup_register(pool, res, (void*)PQclear,
+ apr_pool_cleanup_register(pool, res, clear_result,
apr_pool_cleanup_null);
}
else {
@@ -478,23 +500,21 @@ static int dbd_pgsql_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
apr_dbd_prepared_t *statement,
int seek, va_list args)
{
- const char *arg;
- int nargs = 0;
- const char *values[QUERY_MAX_ARGS];
+ const char **values;
+ int i;
if (sql->trans && sql->trans->errnum) {
return sql->trans->errnum;
}
- while (arg = va_arg(args, const char*), arg) {
- if ( nargs >= QUERY_MAX_ARGS) {
- va_end(args);
- return -1;
- }
- values[nargs++] = apr_pstrdup(pool, arg);
+ values = apr_palloc(pool, sizeof(*values) * statement->nargs);
+
+ for (i = 0; i < statement->nargs; i++) {
+ values[i] = apr_pstrdup(pool, va_arg(args, const char*));
}
+
return dbd_pgsql_pselect(pool, sql, results, statement,
- seek, nargs, values) ;
+ seek, statement->nargs, values) ;
}
static int dbd_pgsql_start_transaction(apr_pool_t *pool, apr_dbd_t *handle,