On Tue, 2006-06-13 at 10:25 +1000, Bojan Smojver wrote:
> It is easy to make that change in PostgreSQL and SQLite drivers (i.e. to
> remember the number of args parsed in _prepare). People can keep passing
> NULL as the last argument in pvquery/pvselect - they shouldn't get hurt.
> If nobody objects, I can take it upon myself to do this.
Something like the attached, maybe?
--
Bojan
Index: dbd/apr_dbd_sqlite3.c
===================================================================
--- dbd/apr_dbd_sqlite3.c (revision 413780)
+++ dbd/apr_dbd_sqlite3.c (working copy)
@@ -31,8 +31,6 @@
#define MAX_RETRY_COUNT 15
#define MAX_RETRY_SLEEP 100000
-#define QUERY_MAX_ARGS 40
-
struct apr_dbd_transaction_t {
int errnum;
apr_dbd_t *handle;
@@ -403,21 +401,18 @@
static int dbd_sqlite3_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
apr_dbd_prepared_t *statement, va_list args)
{
- const char *arg, *values[QUERY_MAX_ARGS];
- int nargs = 0;
+ const char **values;
+ int i, nargs = sqlite3_bind_parameter_count(statement->stmt);
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) * nargs);
+
+ for (i = 0; i < nargs; i++) {
+ values[i] = apr_pstrdup(pool, va_arg(args, const char*));
}
- values[nargs] = NULL;
return dbd_sqlite3_pquery(pool, sql, nrows, statement, nargs, values);
}
@@ -541,21 +536,18 @@
apr_dbd_prepared_t *statement, int seek,
va_list args)
{
- const char *arg, *values[QUERY_MAX_ARGS];
- int nargs = 0;
+ const char **values;
+ int i, nargs = sqlite3_bind_parameter_count(statement->stmt);
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) * nargs);
+
+ for (i = 0; i < nargs; i++) {
+ values[i] = apr_pstrdup(pool, va_arg(args, const char*));
}
- values[nargs] = NULL;
return dbd_sqlite3_pselect(pool, sql, results, statement,
seek, nargs, values);
Index: dbd/apr_dbd_pgsql.c
===================================================================
--- dbd/apr_dbd_pgsql.c (revision 413780)
+++ dbd/apr_dbd_pgsql.c (working copy)
@@ -63,6 +63,7 @@
struct apr_dbd_prepared_t {
const char *name;
int prepared;
+ int nargs;
};
#define dbd_pgsql_is_success(x) (((x) == PGRES_EMPTY_QUERY) \
@@ -252,7 +253,6 @@
size_t i = 0;
const char *args[QUERY_MAX_ARGS];
size_t alen;
- int nargs = 0;
int ret;
PGresult *res;
char *pgquery;
@@ -261,11 +261,12 @@
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;
@@ -273,8 +274,8 @@
}
}
length = strlen(query) + 1;
- if (nargs > 8) {
- length += nargs - 8;
+ if ((*statement)->nargs > 8) {
+ length += (*statement)->nargs - 8;
}
pgptr = pgquery = apr_palloc(pool, length) ;
@@ -329,10 +330,10 @@
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;
@@ -404,22 +405,21 @@
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,
@@ -505,23 +505,21 @@
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,