~ubuntu-branches/ubuntu/precise/apr-util/precise

« back to all changes in this revision

Viewing changes to dbd/apr_dbd_pgsql.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Fritsch
  • Date: 2008-01-12 10:17:09 UTC
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20080112101709-svfgyi40u41za6v2
ImportĀ upstreamĀ versionĀ 1.2.12+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
2
 
 * applicable.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
 
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
 
2
 * contributor license agreements.  See the NOTICE file distributed with
 
3
 * this work for additional information regarding copyright ownership.
 
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
5
 * (the "License"); you may not use this file except in compliance with
 
6
 * the License.  You may obtain a copy of the License at
7
7
 *
8
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
9
 *
18
18
 
19
19
#if APU_HAVE_PGSQL
20
20
 
 
21
#include "apu_config.h"
 
22
 
21
23
#include <ctype.h>
22
24
#include <stdlib.h>
23
25
 
 
26
#ifdef HAVE_LIBPQ_FE_H
24
27
#include <libpq-fe.h>
 
28
#elif defined(HAVE_POSTGRESQL_LIBPQ_FE_H)
 
29
#include <postgresql/libpq-fe.h>
 
30
#endif
25
31
 
26
32
#include "apr_strings.h"
27
33
#include "apr_time.h"
57
63
struct apr_dbd_prepared_t {
58
64
    const char *name;
59
65
    int prepared;
 
66
    int nargs;
60
67
};
61
68
 
62
69
#define dbd_pgsql_is_success(x) (((x) == PGRES_EMPTY_QUERY) \
63
70
                                 || ((x) == PGRES_COMMAND_OK) \
64
71
                                 || ((x) == PGRES_TUPLES_OK))
65
72
 
 
73
static apr_status_t clear_result(void *data)
 
74
{
 
75
    PQclear(data);
 
76
    return APR_SUCCESS;
 
77
}
 
78
 
66
79
static int dbd_pgsql_select(apr_pool_t *pool, apr_dbd_t *sql,
67
80
                            apr_dbd_results_t **results,
68
81
                            const char *query, int seek)
97
110
        (*results)->ntuples = PQntuples(res);
98
111
        (*results)->sz = PQnfields(res);
99
112
        (*results)->random = seek;
100
 
        apr_pool_cleanup_register(pool, res, (void*)PQclear,
 
113
        apr_pool_cleanup_register(pool, res, clear_result,
101
114
                                  apr_pool_cleanup_null);
102
115
    }
103
116
    else {
140
153
    if (res->random) {
141
154
        if (row->n >= res->ntuples) {
142
155
            *rowp = NULL;
143
 
            apr_pool_cleanup_kill(pool, res->res, (void*)PQclear);
144
 
            PQclear(res->res);
 
156
            apr_pool_cleanup_run(pool, res->res, clear_result);
145
157
            res->res = NULL;
146
158
            return -1;
147
159
        }
221
233
                                    apr_dbd_t *sql)
222
234
{
223
235
    size_t len = strlen(arg);
224
 
    char *ret = apr_palloc(pool, len + 1);
 
236
    char *ret = apr_palloc(pool, 2*(len + 1));
225
237
    PQescapeString(ret, arg, len);
226
238
    return ret;
227
239
}
236
248
    size_t i = 0;
237
249
    const char *args[QUERY_MAX_ARGS];
238
250
    size_t alen;
239
 
    int nargs = 0;
240
251
    int ret;
241
252
    PGresult *res;
242
253
    char *pgquery;
245
256
    if (!*statement) {
246
257
        *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t));
247
258
    }
 
259
    (*statement)->nargs = 0;
248
260
    /* Translate from apr_dbd to native query format */
249
261
    for (sqlptr = (char*)query; *sqlptr; ++sqlptr) {
250
262
        if (sqlptr[0] == '%') {
251
263
            if (isalpha(sqlptr[1])) {
252
 
                ++nargs;
 
264
                ++(*statement)->nargs;
253
265
            }
254
266
            else if (sqlptr[1] == '%') {
255
267
                ++sqlptr;
257
269
        }
258
270
    }
259
271
    length = strlen(query) + 1;
260
 
    if (nargs > 8) {
261
 
        length += nargs - 8;
 
272
    if ((*statement)->nargs > 8) {
 
273
        length += (*statement)->nargs - 8;
262
274
    }
263
275
    pgptr = pgquery = apr_palloc(pool, length) ;
264
276
 
313
325
    length = strlen(label);
314
326
    memcpy(sqlptr, label, length);
315
327
    sqlptr += length;
316
 
    if (nargs > 0) {
 
328
    if ((*statement)->nargs > 0) {
317
329
        memcpy(sqlptr, " (",2);
318
330
        sqlptr += 2;
319
 
        for (i=0; i<nargs; ++i) {
 
331
        for (i=0; i < (*statement)->nargs; ++i) {
320
332
            alen = strlen(args[i]);
321
333
            memcpy(sqlptr, args[i], alen);
322
334
            sqlptr += alen;
353
365
{
354
366
    int ret;
355
367
    PGresult *res;
 
368
 
 
369
    if (sql->trans && sql->trans->errnum) {
 
370
        return sql->trans->errnum;
 
371
    }
 
372
 
356
373
    if (statement->prepared) {
357
374
        res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0, 0,
358
375
                             0);
366
383
        if (dbd_pgsql_is_success(ret)) {
367
384
            ret = 0;
368
385
        }
 
386
        *nrows = atoi(PQcmdTuples(res));
369
387
        PQclear(res);
370
388
    }
371
389
    else {
382
400
                             int *nrows, apr_dbd_prepared_t *statement,
383
401
                             va_list args)
384
402
{
385
 
    const char *arg;
386
 
    int nargs = 0;
387
 
    const char *values[QUERY_MAX_ARGS];
 
403
    const char **values;
 
404
    int i;
388
405
 
389
406
    if (sql->trans && sql->trans->errnum) {
390
407
        return sql->trans->errnum;
391
408
    }
392
 
    while ( arg = va_arg(args, const char*), arg ) {
393
 
        if ( nargs >= QUERY_MAX_ARGS) {
394
 
            va_end(args);
395
 
            return -1;
396
 
        }
397
 
        values[nargs++] = apr_pstrdup(pool, arg);
 
409
 
 
410
    values = apr_palloc(pool, sizeof(*values) * statement->nargs);
 
411
 
 
412
    for (i = 0; i < statement->nargs; i++) {
 
413
        values[i] = apr_pstrdup(pool, va_arg(args, const char*));
398
414
    }
399
 
    values[nargs] = NULL;
400
 
    return dbd_pgsql_pquery(pool, sql, nrows, statement, nargs, values);
 
415
 
 
416
    return dbd_pgsql_pquery(pool, sql, nrows, statement,
 
417
                            statement->nargs, values);
401
418
}
402
419
 
403
420
static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql,
408
425
    PGresult *res;
409
426
    int rv;
410
427
    int ret = 0;
 
428
 
 
429
    if (sql->trans && sql->trans->errnum) {
 
430
        return sql->trans->errnum;
 
431
    }
 
432
 
411
433
    if (seek) { /* synchronous query */
412
434
        if (statement->prepared) {
413
435
            res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0,
442
464
        (*results)->ntuples = PQntuples(res);
443
465
        (*results)->sz = PQnfields(res);
444
466
        (*results)->random = seek;
445
 
        apr_pool_cleanup_register(pool, res, (void*)PQclear,
 
467
        apr_pool_cleanup_register(pool, res, clear_result,
446
468
                                  apr_pool_cleanup_null);
447
469
    }
448
470
    else {
478
500
                              apr_dbd_prepared_t *statement,
479
501
                              int seek, va_list args)
480
502
{
481
 
    const char *arg;
482
 
    int nargs = 0;
483
 
    const char *values[QUERY_MAX_ARGS];
 
503
    const char **values;
 
504
    int i;
484
505
 
485
506
    if (sql->trans && sql->trans->errnum) {
486
507
        return sql->trans->errnum;
487
508
    }
488
509
 
489
 
    while (arg = va_arg(args, const char*), arg) {
490
 
        if ( nargs >= QUERY_MAX_ARGS) {
491
 
            va_end(args);
492
 
            return -1;
493
 
        }
494
 
        values[nargs++] = apr_pstrdup(pool, arg);
 
510
    values = apr_palloc(pool, sizeof(*values) * statement->nargs);
 
511
 
 
512
    for (i = 0; i < statement->nargs; i++) {
 
513
        values[i] = apr_pstrdup(pool, va_arg(args, const char*));
495
514
    }
 
515
 
496
516
    return dbd_pgsql_pselect(pool, sql, results, statement,
497
 
                             seek, nargs, values) ;
 
517
                             seek, statement->nargs, values) ;
498
518
}
499
519
 
500
520
static int dbd_pgsql_start_transaction(apr_pool_t *pool, apr_dbd_t *handle,