/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Developed initially by Nick Kew and Chris Darroch.
 * Contributed to the APR project by kind permission of
 * Pearson Education Core Technology Group (CTG),
 * formerly Central Media Group (CMG).
 */

/* apr_dbd_oracle - a painful attempt
 *
 * Based first on the documentation at
 * http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96584/toc.htm
 *
 * Those docs have a lot of internal inconsistencies, contradictions, etc
 * So I've snarfed the demo programs (from Oracle 8, not included in
 * the current downloadable oracle), and used code from them.
 *
 * Why do cdemo81.c and cdemo82.c do the same thing in very different ways?
 * e.g. cdemo82 releases all its handle on shutdown; cdemo81 doesn't
 *
 * All the ORA* functions return a "sword".  Some of them are documented;
 * others aren't.  So I've adopted a policy of using switch statements
 * everywhere, even when we're not doing anything with the return values.
 *
 * This makes no attempt at performance tuning, such as setting
 * prefetch cache size.  We need some actual performance data
 * to make that meaningful.  Input from someone with experience
 * as a sysop using oracle would be a good start.
 */

/* shut compiler up */
#ifdef DEBUG
#define int_errorcode int errorcode
#else
#define int_errorcode
#endif

#include "apu.h"
#include "apr_private.h"

#if APU_HAVE_ORACLE

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>

#include <oci.h>

#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_time.h"
#include "apr_hash.h"
#include "apr_buckets.h"

#define TRANS_TIMEOUT 30
#define MAX_ARG_LEN 256 /* in line with other apr_dbd drivers.  We alloc this
                         * lots of times, so a large value gets hungry.
                         * Should really make it configurable
                         */
#define DEFAULT_LONG_SIZE 4096
#define DBD_ORACLE_MAX_COLUMNS 256
#define NUMERIC_FIELD_SIZE 32

#define CHECK_CONN_QUERY "SELECT 1 FROM dual"

#define ERR_BUF_SIZE 200

#ifdef DEBUG
#include <stdio.h>
#endif

#include "apr_dbd_internal.h"

/* declarations */
static const char *dbd_oracle_error(apr_dbd_t *sql, int n);
static int dbd_oracle_prepare(apr_pool_t *pool, apr_dbd_t *sql,
                              const char *query, const char *label,
                              int nargs, int nvals, apr_dbd_type_e *types,
                              apr_dbd_prepared_t **statement);
static int outputParams(apr_dbd_t*, apr_dbd_prepared_t*);
static int dbd_oracle_pselect(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **results,
                              apr_dbd_prepared_t *statement,
                              int seek, const char **values);
static int dbd_oracle_pquery(apr_pool_t *pool, apr_dbd_t *sql,
                             int *nrows, apr_dbd_prepared_t *statement,
                             const char **values);
static int dbd_oracle_start_transaction(apr_pool_t *pool, apr_dbd_t *sql,
                                        apr_dbd_transaction_t **trans);
static int dbd_oracle_end_transaction(apr_dbd_transaction_t *trans);

struct apr_dbd_transaction_t {
    int mode;
    enum { TRANS_NONE, TRANS_ERROR, TRANS_1, TRANS_2 } status;
    apr_dbd_t *handle;
    OCITrans *trans;
    OCISnapshot *snapshot1;
    OCISnapshot *snapshot2;
};

struct apr_dbd_results_t {
    apr_pool_t *pool;
    apr_dbd_t* handle;
    unsigned int rownum;
    int seek;
    int nrows;
    apr_dbd_prepared_t *statement;
};

struct apr_dbd_t {
    sword status;
    OCIError *err;
    OCIServer *svr;
    OCISvcCtx *svc;
    OCISession *auth;
    apr_dbd_transaction_t* trans;
    apr_pool_t *pool;
    char buf[ERR_BUF_SIZE]; /* for error messages */
    apr_size_t long_size;
    apr_dbd_prepared_t *check_conn_stmt;
};

struct apr_dbd_row_t {
    int n;
    apr_dbd_results_t *res;
    apr_pool_t *pool;
};

typedef struct {
    apr_dbd_type_e type;
    sb2 ind;
    sb4 len;
    OCIBind *bind;
    union {
        void *raw;
        char *sval;
        int ival;
        unsigned int uval;
        double fval;
        OCILobLocator *lobval;
    } value;
} bind_arg;

typedef struct {
    int type;
    sb2 ind;
    ub2 len;         /* length of actual output */
    OCIDefine *defn;
    apr_size_t sz;   /* length of buf for output */
    union {
        void *raw;
        char *sval;
        OCILobLocator *lobval;
    } buf;
    const char *name;
} define_arg;

struct apr_dbd_prepared_t {
    OCIStmt *stmt;
    int nargs;
    int nvals;
    bind_arg *args;
    int nout;
    define_arg *out;
    apr_dbd_t *handle;
    apr_pool_t *pool;
    ub2 type;
};

/* AFAICT from the docs, the OCIEnv thingey can be used async
 * across threads, so lets have a global one.
 *
 * We'll need shorter-lived envs to deal with requests and connections
 *
 * Hmmm, that doesn't work: we don't have a usermem framework.
 * OK, forget about using APR pools here, until we figure out
 * the right way to do it (if such a thing exists).
 */
static OCIEnv *dbd_oracle_env = NULL;

/* Oracle specific bucket for BLOB/CLOB types */
typedef struct apr_bucket_lob apr_bucket_lob;
/**
 * A bucket referring to a Oracle BLOB/CLOB
 */
struct apr_bucket_lob {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The row this bucket refers to */
    const apr_dbd_row_t *row;
    /** The column this bucket refers to */
    int col;
    /** The pool into which any needed structures should
     *  be created while reading from this bucket */
    apr_pool_t *readpool;
};

static void lob_bucket_destroy(void *data);
static apr_status_t lob_bucket_read(apr_bucket *e, const char **str,
                                    apr_size_t *len, apr_read_type_e block);
static apr_bucket *apr_bucket_lob_make(apr_bucket *b,
                                       const apr_dbd_row_t *row, int col,
                                       apr_off_t offset, apr_size_t len,
                                       apr_pool_t *p);
static apr_bucket *apr_bucket_lob_create(const apr_dbd_row_t *row, int col,
                                         apr_off_t offset,
                                         apr_size_t len, apr_pool_t *p,
                                         apr_bucket_alloc_t *list);

static const apr_bucket_type_t apr_bucket_type_lob = {
    "LOB", 5, APR_BUCKET_DATA,
    lob_bucket_destroy,
    lob_bucket_read,
    apr_bucket_setaside_notimpl,
    apr_bucket_shared_split,
    apr_bucket_shared_copy
};

static void lob_bucket_destroy(void *data)
{
    apr_bucket_lob *f = data;

    if (apr_bucket_shared_destroy(f)) {
        /* no need to destroy database objects here; it will get
         * done automatically when the pool gets cleaned up */
        apr_bucket_free(f);
    }
}

static apr_status_t lob_bucket_read(apr_bucket *e, const char **str,
                                    apr_size_t *len, apr_read_type_e block)
{
    apr_bucket_lob *a = e->data;
    const apr_dbd_row_t *row = a->row;
    apr_dbd_results_t *res = row->res;
    int col = a->col;
    apr_bucket *b = NULL;
    apr_size_t blength = e->length;  /* bytes remaining in file past offset */
    apr_off_t boffset = e->start;
    define_arg *val = &res->statement->out[col];
    apr_dbd_t *sql = res->handle;
/* Only with 10g, unfortunately
    oraub8 length = APR_BUCKET_BUFF_SIZE;
*/
    ub4 length = APR_BUCKET_BUFF_SIZE;
    char *buf = NULL;

    *str = NULL;  /* in case we die prematurely */

    /* fetch from offset if not at the beginning */
    buf = apr_palloc(row->pool, APR_BUCKET_BUFF_SIZE);
    sql->status = OCILobRead(sql->svc, sql->err, val->buf.lobval,
                             &length, 1 + (size_t)boffset,
                             (dvoid*) buf, APR_BUCKET_BUFF_SIZE,
                             NULL, NULL, 0, SQLCS_IMPLICIT);
/* Only with 10g, unfortunately
    sql->status = OCILobRead2(sql->svc, sql->err, val->buf.lobval,
                              &length, NULL, 1 + boffset,
                              (dvoid*) buf, APR_BUCKET_BUFF_SIZE,
                              OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT);
*/
    if (sql->status != OCI_SUCCESS) {
        return APR_EGENERAL;
    }
    blength -= length;
    *len = length;
    *str = buf;

    /*
     * Change the current bucket to refer to what we read,
     * even if we read nothing because we hit EOF.
     */
    apr_bucket_pool_make(e, *str, *len, res->pool);

    /* If we have more to read from the field, then create another bucket */
    if (blength > 0) {
        /* for efficiency, we can just build a new apr_bucket struct
         * to wrap around the existing LOB bucket */
        b = apr_bucket_alloc(sizeof(*b), e->list);
        b->start  = boffset + *len;
        b->length = blength;
        b->data   = a;
        b->type   = &apr_bucket_type_lob;
        b->free   = apr_bucket_free;
        b->list   = e->list;
        APR_BUCKET_INSERT_AFTER(e, b);
    }
    else {
        lob_bucket_destroy(a);
    }

    return APR_SUCCESS;
}

static apr_bucket *apr_bucket_lob_make(apr_bucket *b,
                                       const apr_dbd_row_t *row, int col,
                                       apr_off_t offset, apr_size_t len,
                                       apr_pool_t *p)
{
    apr_bucket_lob *f;

    f = apr_bucket_alloc(sizeof(*f), b->list);
    f->row = row;
    f->col = col;
    f->readpool = p;

    b = apr_bucket_shared_make(b, f, offset, len);
    b->type = &apr_bucket_type_lob;

    return b;
}

static apr_bucket *apr_bucket_lob_create(const apr_dbd_row_t *row, int col,
                                         apr_off_t offset,
                                         apr_size_t len, apr_pool_t *p,
                                         apr_bucket_alloc_t *list)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    return apr_bucket_lob_make(b, row, col, offset, len, p);
}

static apr_status_t dbd_free_lobdesc(void *lob)
{
    switch (OCIDescriptorFree(lob, OCI_DTYPE_LOB)) {
    case OCI_SUCCESS:
        return APR_SUCCESS;
    default:
        return APR_EGENERAL;
    }
}

static apr_status_t dbd_free_snapshot(void *snap)
{
    switch (OCIDescriptorFree(snap, OCI_DTYPE_SNAP)) {
    case OCI_SUCCESS:
        return APR_SUCCESS;
    default:
        return APR_EGENERAL;
    }
}

static void dbd_oracle_init(apr_pool_t *pool)
{
    if (dbd_oracle_env == NULL) {
        /* Sadly, OCI_SHARED seems to be impossible to use, due to
         * various Oracle bugs.  See, for example, Oracle MetaLink bug 2972890
         * and PHP bug http://bugs.php.net/bug.php?id=23733
         */
#ifdef OCI_NEW_LENGTH_SEMANTICS
        OCIEnvCreate(&dbd_oracle_env, OCI_THREADED|OCI_NEW_LENGTH_SEMANTICS,
                     NULL, NULL, NULL, NULL, 0, NULL);
#else
        OCIEnvCreate(&dbd_oracle_env, OCI_THREADED,
                     NULL, NULL, NULL, NULL, 0, NULL);
#endif
    }
}

static apr_dbd_t *dbd_oracle_open(apr_pool_t *pool, const char *params,
                                  const char **error)
{
    apr_dbd_t *ret = apr_pcalloc(pool, sizeof(apr_dbd_t));
    int errorcode;

    char *BLANK = "";
    struct {
        const char *field;
        char *value;
    } fields[] = {
        {"user", BLANK},
        {"pass", BLANK},
        {"dbname", BLANK},
        {"server", BLANK},
        {NULL, NULL}
    };
    int i;
    const char *ptr;
    const char *key;
    size_t klen;
    const char *value;
    size_t vlen;
    static const char *const delims = " \r\n\t;|,";

    ret->pool = pool;
    ret->long_size = DEFAULT_LONG_SIZE;

    /* snitch parsing from the MySQL driver */
    for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) {
        /* don't dereference memory that may not belong to us */
        if (ptr == params) {
            ++ptr;
            continue;
        }
        for (key = ptr-1; apr_isspace(*key); --key);
        klen = 0;
        while (apr_isalpha(*key)) {
            if (key == params) {
                /* Don't parse off the front of the params */
                --key;
                ++klen;
                break;
            }
            --key;
            ++klen;
        }
        ++key;
        for (value = ptr+1; apr_isspace(*value); ++value);
        vlen = strcspn(value, delims);
        for (i=0; fields[i].field != NULL; ++i) {
            if (!strncasecmp(fields[i].field, key, klen)) {
                fields[i].value = apr_pstrndup(pool, value, vlen);
                break;
            }
        }
        ptr = value+vlen;
    }

    ret->status = OCIHandleAlloc(dbd_oracle_env, (dvoid**)&ret->err,
                                 OCI_HTYPE_ERROR, 0, NULL);
    switch (ret->status) {
    default:
#ifdef DEBUG
        printf("ret->status is %d\n", ret->status);
        break;
#else
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }

    ret->status = OCIHandleAlloc(dbd_oracle_env, (dvoid**)&ret->svr,
                                 OCI_HTYPE_SERVER, 0, NULL);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (alloc svr): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }

    ret->status = OCIHandleAlloc(dbd_oracle_env, (dvoid**)&ret->svc,
                                 OCI_HTYPE_SVCCTX, 0, NULL);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (alloc svc): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }

/* All the examples use the #else */
#if CAN_DO_LOGIN
    ret->status = OCILogon(dbd_oracle_env, ret->err, &ret->svc, fields[0].value,
                     strlen(fields[0].value), fields[1].value,
                     strlen(fields[1].value), fields[2].value,
                     strlen(fields[2].value));
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR: %s\n", ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
#else
    ret->status = OCIServerAttach(ret->svr, ret->err, (text*) fields[3].value,
                                  strlen(fields[3].value), OCI_DEFAULT);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (server attach): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCIAttrSet(ret->svc, OCI_HTYPE_SVCCTX, ret->svr, 0,
                        OCI_ATTR_SERVER, ret->err);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (attr set): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCIHandleAlloc(dbd_oracle_env, (dvoid**)&ret->auth,
                            OCI_HTYPE_SESSION, 0, NULL);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (alloc auth): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCIAttrSet(ret->auth, OCI_HTYPE_SESSION, fields[0].value,
                        strlen(fields[0].value), OCI_ATTR_USERNAME, ret->err);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (attr username): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCIAttrSet(ret->auth, OCI_HTYPE_SESSION, fields[1].value,
                        strlen(fields[1].value), OCI_ATTR_PASSWORD, ret->err);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (attr password): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCISessionBegin(ret->svc, ret->err, ret->auth,
                             OCI_CRED_RDBMS, OCI_DEFAULT);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (session begin): %s\n", ret->status, ret->buf);
        break;
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
    case OCI_SUCCESS:
        break;
    }
    ret->status = OCIAttrSet(ret->svc, OCI_HTYPE_SVCCTX, ret->auth, 0,
                        OCI_ATTR_SESSION, ret->err);
    switch (ret->status) {
    default:
#ifdef DEBUG
        OCIErrorGet(ret->err, 1, NULL, &errorcode, ret->buf,
                    sizeof(ret->buf), OCI_HTYPE_ERROR);
        printf("OPEN ERROR %d (attr session): %s\n", ret->status, ret->buf);
#else
        if (error) {
            *error = apr_pcalloc(pool, ERR_BUF_SIZE);
            OCIErrorGet(ret->err, 1, NULL, &errorcode, (unsigned char*)(*error),
                        ERR_BUF_SIZE, OCI_HTYPE_ERROR);
        }
        return NULL;
#endif
        break;
    case OCI_SUCCESS:
        break;
    }
#endif

    if(dbd_oracle_prepare(pool, ret, CHECK_CONN_QUERY, NULL, 0, 0, NULL,
                          &ret->check_conn_stmt) != 0) {
        return NULL;
    }

    return ret;
}

#ifdef EXPORT_NATIVE_FUNCS
static apr_size_t dbd_oracle_long_size_set(apr_dbd_t *sql,
                                           apr_size_t long_size)
{
    apr_size_t old_size = sql->long_size;
    sql->long_size = long_size;
    return old_size;
}
#endif

static const char *dbd_oracle_get_name(const apr_dbd_results_t *res, int n)
{
    define_arg *val = &res->statement->out[n];

    if ((n < 0) || (n >= res->statement->nout)) {
        return NULL;
    }
    return val->name;
}

static int dbd_oracle_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
                              apr_dbd_row_t **rowp, int rownum)
{
    apr_dbd_row_t *row = *rowp;
    apr_dbd_t *sql = res->handle;
    int_errorcode;

    if (row == NULL) {
        row = apr_palloc(pool, sizeof(apr_dbd_row_t));
        *rowp = row;
        row->res = res;
        /* Oracle starts counting at 1 according to the docs */
        row->n = res->seek ? rownum : 1;
        row->pool = pool;
    }
    else {
        if (res->seek) {
            row->n = rownum;
        }
        else {
            ++row->n;
        }
    }

    if (res->seek) {
        sql->status = OCIStmtFetch2(res->statement->stmt, res->handle->err, 1,
                                    OCI_FETCH_ABSOLUTE, row->n, OCI_DEFAULT);
    }
    else {
        sql->status = OCIStmtFetch2(res->statement->stmt, res->handle->err, 1,
                                    OCI_FETCH_NEXT, 0, OCI_DEFAULT);
    }
    switch (sql->status) {
    case OCI_SUCCESS:
        (*rowp)->res = res;
        return 0;
    case OCI_NO_DATA:
        return -1;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Execute error %d: %s\n", sql->status, sql->buf);
#endif
        /* fallthrough */
    default:
        return 1;
    }
    return 0;
}

static const char *dbd_oracle_error(apr_dbd_t *sql, int n)
{
    /* This is ugly.  Needs us to pass in a buffer of unknown size.
     * Either we put it on the handle, or we have to keep allocing/copying
     */
    sb4 errorcode;

    switch (sql->status) {
    case OCI_SUCCESS:
        return "OCI_SUCCESS";
    case OCI_SUCCESS_WITH_INFO:
        return "OCI_SUCCESS_WITH_INFO";
    case OCI_NEED_DATA:
        return "OCI_NEED_DATA";
    case OCI_NO_DATA:
        return "OCI_NO_DATA";
    case OCI_INVALID_HANDLE:
        return "OCI_INVALID_HANDLE";
    case OCI_STILL_EXECUTING:
        return "OCI_STILL_EXECUTING";
    case OCI_CONTINUE:
        return "OCI_CONTINUE";
    }

    switch (OCIErrorGet(sql->err, 1, NULL, &errorcode,
                        (text*) sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR)) {
    case OCI_SUCCESS:
        return sql->buf; 
    default:
        return "internal error: OCIErrorGet failed";
    }
}

static apr_status_t freeStatement(void *statement)
{
    int rv = APR_SUCCESS;
    OCIStmt *stmt = ((apr_dbd_prepared_t*)statement)->stmt;

#ifdef PREPARE2
    OCIError *err;

    if (OCIHandleAlloc(dbd_oracle_env, (dvoid**)&err, OCI_HTYPE_ERROR,
                       0, NULL) != OCI_SUCCESS) {
        return APR_EGENERAL;
    }
    if (OCIStmtRelease(stmt, err, NULL, 0, OCI_DEFAULT) != OCI_SUCCESS) {
        rv = APR_EGENERAL;
    }
    if (OCIHandleFree(err, OCI_HTYPE_ERROR) != OCI_SUCCESS) {
        rv = APR_EGENERAL;
    }
#else
    if (OCIHandleFree(stmt, OCI_HTYPE_STMT) != OCI_SUCCESS) {
        rv = APR_EGENERAL;
    }
#endif

    return rv;
}

static int dbd_oracle_select(apr_pool_t *pool, apr_dbd_t *sql,
                             apr_dbd_results_t **results,
                             const char *query, int seek)
{
    int ret = 0;
    apr_dbd_prepared_t *statement = NULL;

    ret = dbd_oracle_prepare(pool, sql, query, NULL, 0, 0, NULL, &statement);
    if (ret != 0) {
        return ret;
    }

    ret = dbd_oracle_pselect(pool, sql, results, statement, seek, NULL);
    if (ret != 0) {
        return ret;
    }

    return ret;
}

static int dbd_oracle_query(apr_dbd_t *sql, int *nrows, const char *query)
{
    int ret = 0;
    apr_pool_t *pool;
    apr_dbd_prepared_t *statement = NULL;

    if (sql->trans && sql->trans->status == TRANS_ERROR) {
        return 1;
    }

    /* make our own pool so that APR allocations don't linger and so that
     * both Stmt and LOB handles are cleaned up (LOB handles may be
     * allocated when preparing APR_DBD_TYPE_CLOB/BLOBs)
     */
    apr_pool_create(&pool, sql->pool);

    ret = dbd_oracle_prepare(pool, sql, query, NULL, 0, 0, NULL, &statement);
    if (ret == 0) {
        ret = dbd_oracle_pquery(pool, sql, nrows, statement, NULL);
        if (ret == 0) {
            sql->status = OCIAttrGet(statement->stmt, OCI_HTYPE_STMT,
                                     nrows, 0, OCI_ATTR_ROW_COUNT,
                                     sql->err);
        }
    }

    apr_pool_destroy(pool);

    return ret;
}

static const char *dbd_oracle_escape(apr_pool_t *pool, const char *arg,
                                     apr_dbd_t *sql)
{
    return arg;        /* OCI has no concept of string escape */
}

static int dbd_oracle_prepare(apr_pool_t *pool, apr_dbd_t *sql,
                              const char *query, const char *label,
                              int nargs, int nvals, apr_dbd_type_e *types,
                              apr_dbd_prepared_t **statement)
{
    int ret = 0;
    int i;
    apr_dbd_prepared_t *stmt ;

    if (*statement == NULL) {
        *statement = apr_pcalloc(pool, sizeof(apr_dbd_prepared_t));
    }
    stmt = *statement;
    stmt->handle = sql;
    stmt->pool = pool;
    stmt->nargs = nargs;
    stmt->nvals = nvals;

    /* populate our own args, if any */
    if (nargs > 0) {
        stmt->args = apr_pcalloc(pool, nargs*sizeof(bind_arg));
        for (i = 0; i < nargs; i++) {
            stmt->args[i].type = types[i];
        }
    }

    sql->status = OCIHandleAlloc(dbd_oracle_env, (dvoid**) &stmt->stmt,
                                 OCI_HTYPE_STMT, 0, NULL);
    if (sql->status != OCI_SUCCESS) {
        return 1;
    }

    sql->status = OCIStmtPrepare(stmt->stmt, sql->err, (text*) query,
                                 strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT);
    if (sql->status != OCI_SUCCESS) {
        OCIHandleFree(stmt->stmt, OCI_HTYPE_STMT);
        return 1;
    }

    apr_pool_cleanup_register(pool, stmt, freeStatement,
                              apr_pool_cleanup_null);

    /* Perl gets statement type here */
    sql->status = OCIAttrGet(stmt->stmt, OCI_HTYPE_STMT, &stmt->type, 0,
                             OCI_ATTR_STMT_TYPE, sql->err);
    if (sql->status != OCI_SUCCESS) {
        return 1;
    }

/* Perl sets PREFETCH_MEMORY here, but the docs say there's a working default */
#if 0
    sql->status = OCIAttrSet(stmt->stmt, OCI_HTYPE_STMT, &prefetch_size,
                             sizeof(prefetch_size), OCI_ATTR_PREFETCH_MEMORY,
                             sql->err);
    if (sql->status != OCI_SUCCESS) {
        return 1;
    }
#endif

    if (stmt->type == OCI_STMT_SELECT) {
        ret = outputParams(sql, stmt);
    }
    return ret;
}

static void dbd_oracle_bind(apr_dbd_prepared_t *statement, const char **values)
{
    OCIStmt *stmt = statement->stmt;
    apr_dbd_t *sql = statement->handle;
    int i, j;
    sb2 null_ind = -1;

    for (i = 0, j = 0; i < statement->nargs; i++, j++) {
        if (values[j] == NULL) {
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       NULL, 0, SQLT_STR,
                                       &null_ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
        }
        else {
            switch (statement->args[i].type) {
            case APR_DBD_TYPE_BLOB:
                {
                char *data = (char *)values[j];
                int size = atoi((char*)values[++j]);

                /* skip table and column for now */
                j += 2;

                sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                           sql->err, i + 1,
                                           data, size, SQLT_LBI,
                                           &statement->args[i].ind,
                                           NULL,
                                           (ub2) 0, (ub4) 0,
                                           (ub4 *) 0, OCI_DEFAULT);
                }
                break;
            case APR_DBD_TYPE_CLOB:
                {
                char *data = (char *)values[j];
                int size = atoi((char*)values[++j]);

                /* skip table and column for now */
                j += 2;

                sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                           sql->err, i + 1,
                                           data, size, SQLT_LNG,
                                           &statement->args[i].ind,
                                           NULL,
                                           (ub2) 0, (ub4) 0,
                                           (ub4 *) 0, OCI_DEFAULT);
                }
                break;
            default:
                sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                           sql->err, i + 1,
                                           (dvoid*) values[j],
                                           strlen(values[j]) + 1,
                                           SQLT_STR,
                                           &statement->args[i].ind,
                                           NULL,
                                           (ub2) 0, (ub4) 0,
                                           (ub4 *) 0, OCI_DEFAULT);
                break;
            }
        }

        if (sql->status != OCI_SUCCESS) {
            return;
        }
    }

    return;
}

static int outputParams(apr_dbd_t *sql, apr_dbd_prepared_t *stmt)
{
    OCIParam *parms;
    int i;
    ub2 paramtype[DBD_ORACLE_MAX_COLUMNS];
    ub2 paramsize[DBD_ORACLE_MAX_COLUMNS];
    char *paramname[DBD_ORACLE_MAX_COLUMNS];
    ub4 paramnamelen[DBD_ORACLE_MAX_COLUMNS];
    int_errorcode;

    /* Perl uses 0 where we used 1 */
    sql->status = OCIStmtExecute(sql->svc, stmt->stmt, sql->err, 0, 0,
                                 NULL, NULL, OCI_DESCRIBE_ONLY);
    switch (sql->status) {
    case OCI_SUCCESS:
    case OCI_SUCCESS_WITH_INFO:
        break;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Describing prepared statement: %s\n", sql->buf);
#endif
    default:
        return 1;
    }
    while (sql->status == OCI_SUCCESS) {
        sql->status = OCIParamGet(stmt->stmt, OCI_HTYPE_STMT,
                                  sql->err, (dvoid**)&parms, stmt->nout+1);
        switch (sql->status) {
        case OCI_SUCCESS:
            sql->status = OCIAttrGet(parms, OCI_DTYPE_PARAM,
                                     &paramtype[stmt->nout],
                                     0, OCI_ATTR_DATA_TYPE, sql->err);
            sql->status = OCIAttrGet(parms, OCI_DTYPE_PARAM,
                                     &paramsize[stmt->nout],
                                     0, OCI_ATTR_DATA_SIZE, sql->err);
            sql->status = OCIAttrGet(parms, OCI_DTYPE_PARAM,
                                     &paramname[stmt->nout],
                                     &paramnamelen[stmt->nout],
                                     OCI_ATTR_NAME, sql->err);
            ++stmt->nout;
        }
    }
    switch (sql->status) {
    case OCI_SUCCESS:
        break;
    case OCI_ERROR:
        break;        /* this is what we expect at end-of-loop */
    default:
        return 1;
    }

    /* OK, the above works.  We have the params; now OCIDefine them */
    stmt->out = apr_palloc(stmt->pool, stmt->nout*sizeof(define_arg));
    for (i=0; i<stmt->nout; ++i) {
        stmt->out[i].type = paramtype[i];
        stmt->out[i].len = stmt->out[i].sz = paramsize[i];
        stmt->out[i].name = apr_pstrmemdup(stmt->pool,
                                           paramname[i], paramnamelen[i]);
        switch (stmt->out[i].type) {
        default:
            switch (stmt->out[i].type) {
            case SQLT_NUM:           /* 2: numeric, Perl worst case=130+38+3 */
                stmt->out[i].sz = 171;
                break;
            case SQLT_CHR:           /* 1: char */
            case SQLT_AFC:           /* 96: ANSI fixed char */
                stmt->out[i].sz *= 4; /* ugh, wasteful UCS-4 handling */
                break;
            case SQLT_DAT:           /* 12: date, depends on NLS date format */
                stmt->out[i].sz = 75;
                break;
            case SQLT_BIN:           /* 23: raw binary, perhaps UTF-16? */
                stmt->out[i].sz *= 2;
                break;
            case SQLT_RID:           /* 11: rowid */
            case SQLT_RDD:           /* 104: rowid descriptor */
                stmt->out[i].sz = 20;
                break;
            case SQLT_TIMESTAMP:     /* 187: timestamp */
            case SQLT_TIMESTAMP_TZ:  /* 188: timestamp with time zone */
            case SQLT_INTERVAL_YM:   /* 189: interval year-to-month */
            case SQLT_INTERVAL_DS:   /* 190: interval day-to-second */
            case SQLT_TIMESTAMP_LTZ: /* 232: timestamp with local time zone */
                stmt->out[i].sz = 75;
                break;
            default:
#ifdef DEBUG
                printf("Unsupported data type: %d\n", stmt->out[i].type);
#endif
                break;
            }
            ++stmt->out[i].sz;
            stmt->out[i].buf.raw = apr_palloc(stmt->pool, stmt->out[i].sz);
            sql->status = OCIDefineByPos(stmt->stmt, &stmt->out[i].defn,
                                         sql->err, i+1,
                                         stmt->out[i].buf.sval,
                                         stmt->out[i].sz, SQLT_STR,
                                         &stmt->out[i].ind, &stmt->out[i].len,
                                         0, OCI_DEFAULT);
            break;
        case SQLT_LNG: /* 8: long */
            stmt->out[i].sz = sql->long_size * 4 + 4; /* ugh, UCS-4 handling */
            stmt->out[i].buf.raw = apr_palloc(stmt->pool, stmt->out[i].sz);
            sql->status = OCIDefineByPos(stmt->stmt, &stmt->out[i].defn,
                                         sql->err, i+1,
                                         stmt->out[i].buf.raw,
                                         stmt->out[i].sz, SQLT_LVC,
                                         &stmt->out[i].ind, NULL,
                                         0, OCI_DEFAULT);
            break;
        case SQLT_LBI: /* 24: long binary, perhaps UTF-16? */
            stmt->out[i].sz = sql->long_size * 2 + 4; /* room for int prefix */
            stmt->out[i].buf.raw = apr_palloc(stmt->pool, stmt->out[i].sz);
            sql->status = OCIDefineByPos(stmt->stmt, &stmt->out[i].defn,
                                         sql->err, i+1,
                                         stmt->out[i].buf.raw,
                                         stmt->out[i].sz, SQLT_LVB,
                                         &stmt->out[i].ind, NULL,
                                         0, OCI_DEFAULT);
            break;
        case SQLT_BLOB: /* 113 */
        case SQLT_CLOB: /* 112 */
/*http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96584/oci05bnd.htm#434937*/
            sql->status = OCIDescriptorAlloc(dbd_oracle_env,
                                             (dvoid**)&stmt->out[i].buf.lobval,
                                             OCI_DTYPE_LOB, 0, NULL);
            apr_pool_cleanup_register(stmt->pool, stmt->out[i].buf.lobval,
                                      dbd_free_lobdesc,
                                      apr_pool_cleanup_null);
            sql->status = OCIDefineByPos(stmt->stmt, &stmt->out[i].defn,
                                         sql->err, i+1,
                                         (dvoid*) &stmt->out[i].buf.lobval,
                                         -1, stmt->out[i].type,
                                         &stmt->out[i].ind, &stmt->out[i].len,
                                         0, OCI_DEFAULT);
            break;
        }
        switch (sql->status) {
        case OCI_SUCCESS:
            break;
        default:
            return 1;
        }
    }
    return 0;
}

static int dbd_oracle_pquery(apr_pool_t *pool, apr_dbd_t *sql,
                             int *nrows, apr_dbd_prepared_t *statement,
                             const char **values)
{
    OCISnapshot *oldsnapshot = NULL;
    OCISnapshot *newsnapshot = NULL;
    apr_dbd_transaction_t* trans = sql->trans;
    int exec_mode;
    int_errorcode;

    if (trans) {
        switch (trans->status) {
        case TRANS_ERROR:
            return -1;
        case TRANS_NONE:
            trans = NULL;
            break;
        case TRANS_1:
            oldsnapshot = trans->snapshot1;
            newsnapshot = trans->snapshot2;
            trans->status = TRANS_2;
            break;
        case TRANS_2:
            oldsnapshot = trans->snapshot2;
            newsnapshot = trans->snapshot1;
            trans->status = TRANS_1;
            break;
        }
        exec_mode = OCI_DEFAULT;
    }
    else {
        exec_mode = OCI_COMMIT_ON_SUCCESS;
    }

    dbd_oracle_bind(statement, values);

    sql->status = OCIStmtExecute(sql->svc, statement->stmt, sql->err, 1, 0,
                                 oldsnapshot, newsnapshot, exec_mode);
    switch (sql->status) {
    case OCI_SUCCESS:
        break;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Execute error %d: %s\n", sql->status, sql->buf);
#endif
        /* fallthrough */
    default:
        if (TXN_NOTICE_ERRORS(trans)) {
            trans->status = TRANS_ERROR;
        }
        return 1;
    }

    sql->status = OCIAttrGet(statement->stmt, OCI_HTYPE_STMT, nrows, 0,
                             OCI_ATTR_ROW_COUNT, sql->err);
    return 0;
}

static int dbd_oracle_pvquery(apr_pool_t *pool, apr_dbd_t *sql,
                              int *nrows, apr_dbd_prepared_t *statement,
                              va_list args)
{
    const char **values;
    int i;

    if (sql->trans && sql->trans->status == TRANS_ERROR) {
        return -1;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);

    for (i = 0; i < statement->nvals; i++) {
        values[i] = va_arg(args, const char*);
    }

    return dbd_oracle_pquery(pool, sql, nrows, statement, values);
}

static int dbd_oracle_pselect(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **results,
                              apr_dbd_prepared_t *statement,
                              int seek, const char **values)
{
    int exec_mode = seek ? OCI_STMT_SCROLLABLE_READONLY : OCI_DEFAULT;
    OCISnapshot *oldsnapshot = NULL;
    OCISnapshot *newsnapshot = NULL;
    apr_dbd_transaction_t* trans = sql->trans;
    int_errorcode;

    if (trans) {
        switch (trans->status) {
        case TRANS_ERROR:
            return 1;
        case TRANS_NONE:
            trans = NULL;
            break;
        case TRANS_1:
            oldsnapshot = trans->snapshot1;
            newsnapshot = trans->snapshot2;
            trans->status = TRANS_2;
            break;
        case TRANS_2:
            oldsnapshot = trans->snapshot2;
            newsnapshot = trans->snapshot1;
            trans->status = TRANS_1;
            break;
        }
    }

    dbd_oracle_bind(statement, values);

    sql->status = OCIStmtExecute(sql->svc, statement->stmt, sql->err, 0, 0,
                                 oldsnapshot, newsnapshot, exec_mode);
    switch (sql->status) {
    case OCI_SUCCESS:
        break;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Executing prepared statement: %s\n", sql->buf);
#endif
        /* fallthrough */
    default:
        if (TXN_NOTICE_ERRORS(trans)) {
            trans->status = TRANS_ERROR;
        }
        return 1;
    }

    if (!*results) {
        *results = apr_palloc(pool, sizeof(apr_dbd_results_t));
    }
    (*results)->handle = sql;
    (*results)->statement = statement;
    (*results)->seek = seek;
    (*results)->rownum = seek ? 0 : -1;
    (*results)->pool = pool;

    return 0;
}

static int dbd_oracle_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
                               apr_dbd_results_t **results,
                               apr_dbd_prepared_t *statement,
                               int seek, va_list args)
{
    const char **values;
    int i;

    if (sql->trans && sql->trans->status == TRANS_ERROR) {
        return -1;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);

    for (i = 0; i < statement->nvals; i++) {
        values[i] = va_arg(args, const char*);
    }

    return dbd_oracle_pselect(pool, sql, results, statement, seek, values);
}

static void dbd_oracle_bbind(apr_dbd_prepared_t * statement,
                             const void **values)
{
    OCIStmt *stmt = statement->stmt;
    apr_dbd_t *sql = statement->handle;
    int i, j;
    sb2 null_ind = -1;
    apr_dbd_type_e type;

    for (i = 0, j = 0; i < statement->nargs; i++, j++) {
        type = (values[j] == NULL ? APR_DBD_TYPE_NULL
                                  : statement->args[i].type);

        switch (type) {
        case APR_DBD_TYPE_TINY:
            statement->args[i].value.ival = *(char*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.ival,
                                       sizeof(statement->args[i].value.ival),
                                       SQLT_INT,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_UTINY:
            statement->args[i].value.uval = *(unsigned char*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.uval,
                                       sizeof(statement->args[i].value.uval),
                                       SQLT_UIN,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_SHORT:
            statement->args[i].value.ival = *(short*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.ival,
                                       sizeof(statement->args[i].value.ival),
                                       SQLT_INT,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_USHORT:
            statement->args[i].value.uval = *(unsigned short*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.uval,
                                       sizeof(statement->args[i].value.uval),
                                       SQLT_UIN,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_INT:
            statement->args[i].value.ival = *(int*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.ival,
                                       sizeof(statement->args[i].value.ival),
                                       SQLT_INT,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_UINT:
            statement->args[i].value.uval = *(unsigned int*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.uval,
                                       sizeof(statement->args[i].value.uval),
                                       SQLT_UIN,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_LONG:
            statement->args[i].value.sval =
                apr_psprintf(statement->pool, "%ld", *(long*)values[j]);
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       statement->args[i].value.sval,
                                       strlen(statement->args[i].value.sval)+1,
                                       SQLT_STR,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_ULONG:
            statement->args[i].value.sval =
                apr_psprintf(statement->pool, "%lu",
                                              *(unsigned long*)values[j]);
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       statement->args[i].value.sval,
                                       strlen(statement->args[i].value.sval)+1,
                                       SQLT_STR,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_LONGLONG:
            statement->args[i].value.sval =
                apr_psprintf(statement->pool, "%" APR_INT64_T_FMT,
                                              *(apr_int64_t*)values[j]);
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       statement->args[i].value.sval,
                                       strlen(statement->args[i].value.sval)+1,
                                       SQLT_STR,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_ULONGLONG:
            statement->args[i].value.sval =
                apr_psprintf(statement->pool, "%" APR_UINT64_T_FMT,
                                              *(apr_uint64_t*)values[j]);
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       statement->args[i].value.sval,
                                       strlen(statement->args[i].value.sval)+1,
                                       SQLT_UIN,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_FLOAT:
            statement->args[i].value.fval = *(float*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.fval,
                                       sizeof(statement->args[i].value.fval),
                                       SQLT_FLT,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_DOUBLE:
            statement->args[i].value.fval = *(double*)values[j];
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       &statement->args[i].value.fval,
                                       sizeof(statement->args[i].value.fval),
                                       SQLT_FLT,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_STRING:
        case APR_DBD_TYPE_TEXT:
        case APR_DBD_TYPE_TIME:
        case APR_DBD_TYPE_DATE:
        case APR_DBD_TYPE_DATETIME:
        case APR_DBD_TYPE_TIMESTAMP:
        case APR_DBD_TYPE_ZTIMESTAMP:
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       (dvoid*) values[j],
                                       strlen(values[j]) + 1,
                                       SQLT_STR,
                                       &statement->args[i].ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        case APR_DBD_TYPE_BLOB:
            {
            char *data = (char *)values[j];
            apr_size_t size = *(apr_size_t*)values[++j];

            /* skip table and column for now */
            j += 2;

            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       data, size, SQLT_LBI,
                                       &statement->args[i].ind,
                                       NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            }
            break;
        case APR_DBD_TYPE_CLOB:
            {
            char *data = (char *)values[j];
            apr_size_t size = *(apr_size_t*)values[++j];

            /* skip table and column for now */
            j += 2;

            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       data, size, SQLT_LNG,
                                       &statement->args[i].ind,
                                       NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            }
            break;
        case APR_DBD_TYPE_NULL:
        default:
            sql->status = OCIBindByPos(stmt, &statement->args[i].bind,
                                       sql->err, i + 1,
                                       NULL, 0, SQLT_STR,
                                       &null_ind, NULL,
                                       (ub2) 0, (ub4) 0,
                                       (ub4 *) 0, OCI_DEFAULT);
            break;
        }

        if (sql->status != OCI_SUCCESS) {
            return;
        }
    }

    return;
}

static int dbd_oracle_pbquery(apr_pool_t * pool, apr_dbd_t * sql,
                              int *nrows, apr_dbd_prepared_t * statement,
                              const void **values)
{
    OCISnapshot *oldsnapshot = NULL;
    OCISnapshot *newsnapshot = NULL;
    apr_dbd_transaction_t* trans = sql->trans;
    int exec_mode;
    int_errorcode;

    if (trans) {
        switch (trans->status) {
        case TRANS_ERROR:
            return -1;
        case TRANS_NONE:
            trans = NULL;
            break;
        case TRANS_1:
            oldsnapshot = trans->snapshot1;
            newsnapshot = trans->snapshot2;
            trans->status = TRANS_2;
            break;
        case TRANS_2:
            oldsnapshot = trans->snapshot2;
            newsnapshot = trans->snapshot1;
            trans->status = TRANS_1;
            break;
        }
        exec_mode = OCI_DEFAULT;
    }
    else {
        exec_mode = OCI_COMMIT_ON_SUCCESS;
    }

    dbd_oracle_bbind(statement, values);

    sql->status = OCIStmtExecute(sql->svc, statement->stmt, sql->err, 1, 0,
                                 oldsnapshot, newsnapshot, exec_mode);
    switch (sql->status) {
    case OCI_SUCCESS:
        break;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Execute error %d: %s\n", sql->status, sql->buf);
#endif
        /* fallthrough */
    default:
        if (TXN_NOTICE_ERRORS(trans)) {
            trans->status = TRANS_ERROR;
        }
        return 1;
    }

    sql->status = OCIAttrGet(statement->stmt, OCI_HTYPE_STMT, nrows, 0,
                             OCI_ATTR_ROW_COUNT, sql->err);
    return 0;
}

static int dbd_oracle_pvbquery(apr_pool_t * pool, apr_dbd_t * sql,
                               int *nrows, apr_dbd_prepared_t * statement,
                               va_list args)
{
    const void **values;
    int i;

    if (sql->trans && sql->trans->status == TRANS_ERROR) {
        return -1;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);

    for (i = 0; i < statement->nvals; i++) {
        values[i] = va_arg(args, const void*);
    }

    return dbd_oracle_pbquery(pool, sql, nrows, statement, values);
}

static int dbd_oracle_pbselect(apr_pool_t * pool, apr_dbd_t * sql,
                               apr_dbd_results_t ** results,
                               apr_dbd_prepared_t * statement,
                               int seek, const void **values)
{
    int exec_mode = seek ? OCI_STMT_SCROLLABLE_READONLY : OCI_DEFAULT;
    OCISnapshot *oldsnapshot = NULL;
    OCISnapshot *newsnapshot = NULL;
    apr_dbd_transaction_t* trans = sql->trans;
    int_errorcode;

    if (trans) {
        switch (trans->status) {
        case TRANS_ERROR:
            return 1;
        case TRANS_NONE:
            trans = NULL;
            break;
        case TRANS_1:
            oldsnapshot = trans->snapshot1;
            newsnapshot = trans->snapshot2;
            trans->status = TRANS_2;
            break;
        case TRANS_2:
            oldsnapshot = trans->snapshot2;
            newsnapshot = trans->snapshot1;
            trans->status = TRANS_1;
            break;
        }
    }

    dbd_oracle_bbind(statement, values);

    sql->status = OCIStmtExecute(sql->svc, statement->stmt, sql->err, 0, 0,
                                 oldsnapshot, newsnapshot, exec_mode);
    switch (sql->status) {
    case OCI_SUCCESS:
        break;
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode,
                    sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Executing prepared statement: %s\n", sql->buf);
#endif
        /* fallthrough */
    default:
        if (TXN_NOTICE_ERRORS(trans)) {
            trans->status = TRANS_ERROR;
        }
        return 1;
    }

    if (!*results) {
        *results = apr_palloc(pool, sizeof(apr_dbd_results_t));
    }
    (*results)->handle = sql;
    (*results)->statement = statement;
    (*results)->seek = seek;
    (*results)->rownum = seek ? 0 : -1;
    (*results)->pool = pool;

    return 0;
}

static int dbd_oracle_pvbselect(apr_pool_t * pool, apr_dbd_t * sql,
                                apr_dbd_results_t ** results,
                                apr_dbd_prepared_t * statement, int seek,
                                va_list args)
{
    const void **values;
    int i;

    if (sql->trans && sql->trans->status == TRANS_ERROR) {
        return -1;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);

    for (i = 0; i < statement->nvals; i++) {
        values[i] = va_arg(args, const void*);
    }

    return dbd_oracle_pbselect(pool, sql, results, statement, seek, values);
}

static int dbd_oracle_start_transaction(apr_pool_t *pool, apr_dbd_t *sql,
                                        apr_dbd_transaction_t **trans)
{
    int ret = 0;
    int_errorcode;
    if (*trans) {
        dbd_oracle_end_transaction(*trans);
    }
    else {
        *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
        OCIHandleAlloc(dbd_oracle_env, (dvoid**)&(*trans)->trans,
                       OCI_HTYPE_TRANS, 0, 0);
        OCIAttrSet(sql->svc, OCI_HTYPE_SVCCTX, (*trans)->trans, 0,
                   OCI_ATTR_TRANS, sql->err);
    }


    sql->status = OCITransStart(sql->svc, sql->err, TRANS_TIMEOUT,
                                OCI_TRANS_NEW);
    switch (sql->status) {
    case OCI_ERROR:
#ifdef DEBUG
        OCIErrorGet(sql->err, 1, NULL, &errorcode, sql->buf,
                    sizeof(sql->buf), OCI_HTYPE_ERROR);
        printf("Transaction: %s\n", sql->buf);
#endif
        ret = 1;
        break;
    case OCI_SUCCESS:
        (*trans)->handle = sql;
        (*trans)->status = TRANS_1;
        sql->trans = *trans;
        switch (OCIDescriptorAlloc(dbd_oracle_env,
                                   (dvoid**)&(*trans)->snapshot1,
                                   OCI_DTYPE_SNAP, 0, NULL)) {
        case OCI_SUCCESS:
            apr_pool_cleanup_register(pool, (*trans)->snapshot1,
                                      dbd_free_snapshot, apr_pool_cleanup_null);
            break;
        case OCI_INVALID_HANDLE:
            ret = 1;
            break;
        }
        switch (OCIDescriptorAlloc(dbd_oracle_env,
                                   (dvoid**)&(*trans)->snapshot2,
                                   OCI_DTYPE_SNAP, 0, NULL)) {
        case OCI_SUCCESS:
            apr_pool_cleanup_register(pool, (*trans)->snapshot2,
                                      dbd_free_snapshot, apr_pool_cleanup_null);
            break;
        case OCI_INVALID_HANDLE:
            ret = 1;
            break;
        }
        break;
    default:
        ret = 1;
        break;
    }
    return ret;
}

static int dbd_oracle_end_transaction(apr_dbd_transaction_t *trans)
{
    int ret = 1;             /* no transaction is an error cond */
    sword status;
    if (trans) {
        apr_dbd_t *handle = trans->handle;
        switch (trans->status) {
        case TRANS_NONE:     /* No trans is an error here */
            status = OCI_ERROR;
            break;
        case TRANS_ERROR:
            status = OCITransRollback(handle->svc, handle->err, OCI_DEFAULT);
            break;
        default:
            /* rollback on explicit rollback request */
            if (TXN_DO_ROLLBACK(trans)) {
                status = OCITransRollback(handle->svc, handle->err, OCI_DEFAULT);
            } else {
                status = OCITransCommit(handle->svc, handle->err, OCI_DEFAULT);
            }
            break;
        }

        handle->trans = NULL;

        switch (status) {
        case OCI_SUCCESS:
            ret = 0;
            break;
        default:
            ret = 3;
            break;
        }
    }
    return ret;
}

static int dbd_oracle_transaction_mode_get(apr_dbd_transaction_t *trans)
{
    if (!trans)
        return APR_DBD_TRANSACTION_COMMIT;

    return trans->mode;
}

static int dbd_oracle_transaction_mode_set(apr_dbd_transaction_t *trans,
                                           int mode)
{
    if (!trans)
        return APR_DBD_TRANSACTION_COMMIT;

    return trans->mode = (mode & TXN_MODE_BITS);
}

/* This doesn't work for BLOB because of NULLs, but it can fake it
 * if the BLOB is really a string
 */
static const char *dbd_oracle_get_entry(const apr_dbd_row_t *row, int n)
{
    ub4 len = 0;
    ub1 csform = 0;
    ub2 csid = 0;
    apr_size_t buflen = 0;
    char *buf = NULL;
    define_arg *val = &row->res->statement->out[n];
    apr_dbd_t *sql = row->res->handle;
    int_errorcode;

    if ((n < 0) || (n >= row->res->statement->nout) || (val->ind == -1)) {
        return NULL;
    }

    switch (val->type) {
    case SQLT_BLOB:
    case SQLT_CLOB:
        sql->status = OCILobGetLength(sql->svc, sql->err, val->buf.lobval,
                                      &len);
        switch (sql->status) {
        case OCI_SUCCESS:
        case OCI_SUCCESS_WITH_INFO:
            if (len == 0) {
                buf = "";
            }
            break;
        case OCI_ERROR:
#ifdef DEBUG
            OCIErrorGet(sql->err, 1, NULL, &errorcode,
                        sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
            printf("Finding LOB length: %s\n", sql->buf);
            break;
#endif
        default:
            break;
        }

        if (len == 0) {
            break;
        }

        if (val->type == APR_DBD_TYPE_CLOB) {
#if 1
            /* Is this necessary, or can it be defaulted? */
            sql->status = OCILobCharSetForm(dbd_oracle_env, sql->err,
                                            val->buf.lobval, &csform);
            if (sql->status == OCI_SUCCESS) {
                sql->status = OCILobCharSetId(dbd_oracle_env, sql->err,
                                              val->buf.lobval, &csid);
            }
            switch (sql->status) {
            case OCI_SUCCESS:
            case OCI_SUCCESS_WITH_INFO:
                buflen = (len+1) * 4; /* ugh, wasteful UCS-4 handling */
                /* zeroise all - where the string ends depends on charset */
                buf = apr_pcalloc(row->pool, buflen);
                break;
#ifdef DEBUG
            case OCI_ERROR:
                OCIErrorGet(sql->err, 1, NULL, &errorcode,
                            sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
                printf("Reading LOB character set: %s\n", sql->buf);
                break; /*** XXX?? ***/
#endif
            default:
                break; /*** XXX?? ***/
            }
#else   /* ignore charset */
            buflen = (len+1) * 4; /* ugh, wasteful UCS-4 handling */
            /* zeroise all - where the string ends depends on charset */
            buf = apr_pcalloc(row->pool, buflen);
#endif
        } else {
            /* BUG: this'll only work if the BLOB looks like a string */
            buflen = len;
            buf = apr_palloc(row->pool, buflen+1);
            buf[buflen] = 0;
        }

        if (!buf) {
            break;
        }

        sql->status = OCILobRead(sql->svc, sql->err, val->buf.lobval,
                                 &len, 1, (dvoid*) buf, buflen,
                                 NULL, NULL, csid, csform);
        switch (sql->status) {
        case OCI_SUCCESS:
        case OCI_SUCCESS_WITH_INFO:
            break;
#ifdef DEBUG
        case OCI_ERROR:
            OCIErrorGet(sql->err, 1, NULL, &errorcode,
                        sql->buf, sizeof(sql->buf), OCI_HTYPE_ERROR);
            printf("Reading LOB: %s\n", sql->buf);
            buf = NULL; /*** XXX?? ***/
            break;
#endif
        default:
            buf = NULL; /*** XXX?? ***/
            break;
        }

        break;
    case SQLT_LNG:
    case SQLT_LBI:
        /* raw is struct { ub4 len; char *buf; } */
        len = *(ub4*) val->buf.raw;
        buf = apr_pstrndup(row->pool, val->buf.sval + sizeof(ub4), len);
        break;
    default:
        buf = apr_pstrndup(row->pool, val->buf.sval, val->len);
        break;
    }
    return (const char*) buf;
}

/* XXX Should this use Oracle proper API instead of calling get_entry()? */
static apr_status_t dbd_oracle_datum_get(const apr_dbd_row_t *row, int n,
                                         apr_dbd_type_e type, void *data)
{
    define_arg *val = &row->res->statement->out[n];
    const char *entry;

    if ((n < 0) || (n >= row->res->statement->nout)) {
        return APR_EGENERAL;
    }

    if(val->ind == -1) {
        return APR_ENOENT;
    }

    switch (type) {
    case APR_DBD_TYPE_TINY:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(char*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_UTINY:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(unsigned char*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_SHORT:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(short*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_USHORT:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(unsigned short*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_INT:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(int*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_UINT:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(unsigned int*)data = atoi(entry);
        break;
    case APR_DBD_TYPE_LONG:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(long*)data = atol(entry);
        break;
    case APR_DBD_TYPE_ULONG:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(unsigned long*)data = atol(entry);
        break;
    case APR_DBD_TYPE_LONGLONG:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(apr_int64_t*)data = apr_atoi64(entry);
        break;
    case APR_DBD_TYPE_ULONGLONG:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(apr_uint64_t*)data = apr_atoi64(entry);
        break;
    case APR_DBD_TYPE_FLOAT:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(float*)data = (float)atof(entry);
        break;
    case APR_DBD_TYPE_DOUBLE:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(double*)data = atof(entry);
        break;
    case APR_DBD_TYPE_STRING:
    case APR_DBD_TYPE_TEXT:
    case APR_DBD_TYPE_TIME:
    case APR_DBD_TYPE_DATE:
    case APR_DBD_TYPE_DATETIME:
    case APR_DBD_TYPE_TIMESTAMP:
    case APR_DBD_TYPE_ZTIMESTAMP:
        entry = dbd_oracle_get_entry(row, n);
        if (entry == NULL) {
            return APR_ENOENT;
        }
        *(char**)data = (char*)entry;
        break;
    case APR_DBD_TYPE_BLOB:
    case APR_DBD_TYPE_CLOB:
        {
        apr_bucket *e;
        apr_bucket_brigade *b = (apr_bucket_brigade*)data;
        apr_dbd_t *sql = row->res->handle;
        ub4 len = 0;

        switch (val->type) {
        case SQLT_BLOB:
        case SQLT_CLOB:
            sql->status = OCILobGetLength(sql->svc, sql->err,
                                          val->buf.lobval, &len);
            switch(sql->status) {
            case OCI_SUCCESS:
            case OCI_SUCCESS_WITH_INFO:
                if (len == 0) {
                    e = apr_bucket_eos_create(b->bucket_alloc);
                }
                else {
                    e = apr_bucket_lob_create(row, n, 0, len,
                                              row->pool, b->bucket_alloc);
                }
                break;
            default:
                return APR_ENOENT;
            }
            break;
        default:
            entry = dbd_oracle_get_entry(row, n);
            if (entry == NULL) {
                return APR_ENOENT;
            }
            e = apr_bucket_pool_create(entry, strlen(entry),
                                       row->pool, b->bucket_alloc);
            break;
        }
        APR_BRIGADE_INSERT_TAIL(b, e);
        }
        break;
    case APR_DBD_TYPE_NULL:
        *(void**)data = NULL;
        break;
    default:
        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

static apr_status_t dbd_oracle_close(apr_dbd_t *handle)
{
    /* FIXME: none of the oracle docs/examples say anything about
     * closing/releasing handles.  Which seems unlikely ...
     */

    /* OK, let's grab from cdemo again.
     * cdemo81 does nothing; cdemo82 does OCIHandleFree on the handles
     */
    switch (OCISessionEnd(handle->svc, handle->err, handle->auth,
            (ub4)OCI_DEFAULT)) {
    default:
        break;
    }
    switch (OCIServerDetach(handle->svr, handle->err, (ub4) OCI_DEFAULT )) {
    default:
        break;
    }
    /* does OCISessionEnd imply this? */
    switch (OCIHandleFree((dvoid *) handle->auth, (ub4) OCI_HTYPE_SESSION)) {
    default:
        break;
    }
    switch (OCIHandleFree((dvoid *) handle->svr, (ub4) OCI_HTYPE_SERVER)) {
    default:
        break;
    }
    switch (OCIHandleFree((dvoid *) handle->svc, (ub4) OCI_HTYPE_SVCCTX)) {
    default:
        break;
    }
    switch (OCIHandleFree((dvoid *) handle->err, (ub4) OCI_HTYPE_ERROR)) {
    default:
        break;
    }
    return APR_SUCCESS;
}

static apr_status_t dbd_oracle_check_conn(apr_pool_t *pool, apr_dbd_t *sql)
{
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    
    if(dbd_oracle_pselect(pool, sql, &res, sql->check_conn_stmt,
                          0, NULL) != 0) {
        return APR_EGENERAL;
    }
    
    if(dbd_oracle_get_row(pool, res, &row, -1) != 0) {
        return APR_EGENERAL;
    }
    
    if(dbd_oracle_get_row(pool, res, &row, -1) != -1) {
        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

static int dbd_oracle_select_db(apr_pool_t *pool, apr_dbd_t *handle,
                                const char *name)
{
    /* FIXME: need to find this in the docs */
    return APR_ENOTIMPL;
}

static void *dbd_oracle_native(apr_dbd_t *handle)
{
    /* FIXME: can we do anything better?  Oracle doesn't seem to have
     * a concept of a handle in the sense we use it.
     */
    return dbd_oracle_env;
}

static int dbd_oracle_num_cols(apr_dbd_results_t* res)
{
    return res->statement->nout;
}

static int dbd_oracle_num_tuples(apr_dbd_results_t* res)
{
    if (!res->seek) {
        return -1;
    }
    if (res->nrows >= 0) {
        return res->nrows;
    }
    res->handle->status = OCIAttrGet(res->statement->stmt, OCI_HTYPE_STMT,
                                     &res->nrows, 0, OCI_ATTR_ROW_COUNT,
                                     res->handle->err);
    return res->nrows;
}

APR_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_oracle_driver = {
    "oracle",
    dbd_oracle_init,
    dbd_oracle_native,
    dbd_oracle_open,
    dbd_oracle_check_conn,
    dbd_oracle_close,
    dbd_oracle_select_db,
    dbd_oracle_start_transaction,
    dbd_oracle_end_transaction,
    dbd_oracle_query,
    dbd_oracle_select,
    dbd_oracle_num_cols,
    dbd_oracle_num_tuples,
    dbd_oracle_get_row,
    dbd_oracle_get_entry,
    dbd_oracle_error,
    dbd_oracle_escape,
    dbd_oracle_prepare,
    dbd_oracle_pvquery,
    dbd_oracle_pvselect,
    dbd_oracle_pquery,
    dbd_oracle_pselect,
    dbd_oracle_get_name,
    dbd_oracle_transaction_mode_get,
    dbd_oracle_transaction_mode_set,
    ":apr%d",
    dbd_oracle_pvbquery,
    dbd_oracle_pvbselect,
    dbd_oracle_pbquery,
    dbd_oracle_pbselect,
    dbd_oracle_datum_get
};
#endif
