/* 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.
 */

#include "apu.h"
#if APU_HAVE_ODBC

#include "apr.h"
#include "apr_strings.h"
#include "apr_buckets.h"
#include "apr_env.h"
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apr_dbd_internal.h"
#include "apr_thread_proc.h"
#include "apu_version.h"
#include "apu_config.h"

#include <stdlib.h>

/* If library is ODBC-V2, use macros for limited ODBC-V2 support 
 * No random access in V2.
 */
#ifdef ODBCV2
#define ODBCVER 0x0200
#include "apr_dbd_odbc_v2.h"
#endif

/* standard ODBC include files */
#ifdef HAVE_SQL_H
#include <sql.h>
#include <sqlext.h>
#elif defined(HAVE_ODBC_SQL_H)
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#endif

 /* Driver name is "odbc" and the entry point is 'apr_dbd_odbc_driver' 
 * unless ODBC_DRIVER_NAME is defined and it is linked with another db library which
 * is ODBC source-compatible. e.g. DB2, Informix, TimesTen, mysql.  
 */
#ifndef ODBC_DRIVER_NAME
#define ODBC_DRIVER_NAME odbc
#endif
#define STRINGIFY(x) #x
#define NAMIFY2(n) apr_dbd_##n##_driver
#define NAMIFY1(n) NAMIFY2(n)
#define ODBC_DRIVER_STRING STRINGIFY(ODBC_DRIVER_NAME)
#define ODBC_DRIVER_ENTRY NAMIFY1(ODBC_DRIVER_NAME)

/* Required APR version for this driver */
#define DRIVER_APU_VERSION_MAJOR APU_MAJOR_VERSION
#define DRIVER_APU_VERSION_MINOR APU_MINOR_VERSION


static SQLHANDLE henv = NULL;           /* ODBC ENV handle is process-wide */

/* Use a CHECK_ERROR macro so we can grab the source line numbers
 * for error reports */
static void check_error(apr_dbd_t *a, const char *step, SQLRETURN rc,
                 SQLSMALLINT type, SQLHANDLE h, int line);
#define CHECK_ERROR(a,s,r,t,h)  check_error(a,s,r,t,h, __LINE__)

#define SOURCE_FILE __FILE__            /* source file for error messages */
#define MAX_ERROR_STRING 1024           /* max length of message in dbc */
#define MAX_COLUMN_NAME 256             /* longest column name recognized */
#define DEFAULT_BUFFER_SIZE 1024        /* value for defaultBufferSize */

#define MAX_PARAMS  20
#define DEFAULTSEPS " \t\r\n,="
#define CSINGLEQUOTE '\''
#define SSINGLEQUOTE "\'"

#define TEXTMODE 1              /* used for text (APR 1.2) mode params */
#define BINARYMODE 0            /* used for binary (APR 1.3+) mode params */

/* Identify datatypes which are LOBs 
 * - DB2 DRDA driver uses undefined types -98 and -99 for CLOB & BLOB */
#define IS_LOB(t)  (t == SQL_LONGVARCHAR \
     || t == SQL_LONGVARBINARY || t == SQL_VARBINARY \
     || t == -98 || t == -99)
/* These types are CLOBs 
 * - DB2 DRDA driver uses undefined type -98 for CLOB */
#define IS_CLOB(t) \
    (t == SQL_LONGVARCHAR || t == -98)

/* Convert a SQL result to an APR result */
#define APR_FROM_SQL_RESULT(rc) \
    (SQL_SUCCEEDED(rc) ? APR_SUCCESS : APR_EGENERAL)

/* DBD opaque structures */
struct apr_dbd_t
{
    SQLHANDLE dbc;              /* SQL connection handle - NULL after close */
    apr_pool_t *pool;           /* connection lifetime pool */
    char *dbname;               /* ODBC datasource */
    int lasterrorcode;
    int lineNumber;
    char lastError[MAX_ERROR_STRING];
    int defaultBufferSize;      /* used for CLOBs in text mode, 
                                 * and when fld size is indeterminate */
    int transaction_mode;
    int dboptions;              /* driver options re SQLGetData */
    int default_transaction_mode;
    int can_commit;             /* controls end_trans behavior */
};

struct apr_dbd_results_t
{
    SQLHANDLE stmt;             /* parent sql statement handle */
    SQLHANDLE dbc;              /* parent sql connection handle */
    apr_pool_t *pool;           /* pool from query or select */
    apr_dbd_t *apr_dbd;         /* parent DBD connection handle */
    int random;                 /* random access requested */
    int ncols;                  /* number of columns */
    int isclosed;               /* cursor has been closed */
    char **colnames;            /* array of column names (NULL until used) */
    SQLPOINTER *colptrs;        /* pointers to column data */
    SQLINTEGER *colsizes;       /* sizes for columns (enough for txt or bin) */
    SQLINTEGER *coltextsizes;   /* max-sizes if converted to text */
    SQLSMALLINT *coltypes;      /* array of SQL data types for columns */
    SQLLEN *colinds;            /* array of SQL data indicator/strlens */
    int *colstate;              /* array of column states
                                 * - avail, bound, present, unavail 
                                 */
    int *all_data_fetched;      /* flags data as all fetched, for LOBs  */
    void *data;                 /* buffer for all data for one row */
};
enum                                /* results column states */
{
    COL_AVAIL,                  /* data may be retrieved with SQLGetData */
    COL_PRESENT,                /* data has been retrieved with SQLGetData */
    COL_BOUND,                  /* column is bound to colptr */
    COL_RETRIEVED,              /* all data from column has been returned */
    COL_UNAVAIL                 /* column is unavailable because ODBC driver
                                 *  requires that columns be retrieved
                                 *  in ascending order and a higher col 
                                 *  was accessed */
};

struct apr_dbd_row_t {
    SQLHANDLE stmt;             /* parent ODBC statement handle */
    SQLHANDLE dbc;              /* parent ODBC connection handle */
    apr_pool_t *pool;           /* pool from get_row */
    apr_dbd_results_t *res;
};

struct apr_dbd_transaction_t {
    SQLHANDLE dbc;              /* parent ODBC connection handle */
    apr_dbd_t *apr_dbd;         /* parent DBD connection handle */
};

struct apr_dbd_prepared_t {
    SQLHANDLE stmt;             /* ODBC statement handle */
    SQLHANDLE dbc;              /* parent ODBC connection handle */
    apr_dbd_t *apr_dbd;
    int nargs;
    int nvals;
    int *types;                 /* array of DBD data types */

};

static void odbc_lob_bucket_destroy(void *data);
static apr_status_t odbc_lob_bucket_setaside(apr_bucket *e, apr_pool_t *pool);
static apr_status_t odbc_lob_bucket_read(apr_bucket *e, const char **str,
                                         apr_size_t *len, apr_read_type_e block);

/* the ODBC LOB bucket type */
static const apr_bucket_type_t odbc_bucket_type = {
    "ODBC_LOB", 5, APR_BUCKET_DATA,
    odbc_lob_bucket_destroy,
    odbc_lob_bucket_read,
    odbc_lob_bucket_setaside,
    apr_bucket_shared_split,
    apr_bucket_shared_copy
};


/* ODBC LOB bucket data */
typedef struct {
    /** Ref count for shared bucket */
    apr_bucket_refcount  refcount;
    const apr_dbd_row_t *row;
    int col;
    SQLSMALLINT type;
} odbc_bucket;


/* SQL datatype mappings to DBD datatypes 
 * These tables must correspond *exactly* to the apr_dbd_type_e enum 
 * in apr_dbd_internal.h 
 */

/* ODBC "C" types to DBD datatypes  */
static SQLSMALLINT const sqlCtype[] = {
    SQL_C_DEFAULT,                  /* APR_DBD_TYPE_NONE              */
    SQL_C_STINYINT,                 /* APR_DBD_TYPE_TINY,       \%hhd */
    SQL_C_UTINYINT,                 /* APR_DBD_TYPE_UTINY,      \%hhu */
    SQL_C_SSHORT,                   /* APR_DBD_TYPE_SHORT,      \%hd  */
    SQL_C_USHORT,                   /* APR_DBD_TYPE_USHORT,     \%hu  */
    SQL_C_SLONG,                    /* APR_DBD_TYPE_INT,        \%d   */
    SQL_C_ULONG,                    /* APR_DBD_TYPE_UINT,       \%u   */
    SQL_C_SLONG,                    /* APR_DBD_TYPE_LONG,       \%ld  */
    SQL_C_ULONG,                    /* APR_DBD_TYPE_ULONG,      \%lu  */
    SQL_C_SBIGINT,                  /* APR_DBD_TYPE_LONGLONG,   \%lld */
    SQL_C_UBIGINT,                  /* APR_DBD_TYPE_ULONGLONG,  \%llu */
    SQL_C_FLOAT,                    /* APR_DBD_TYPE_FLOAT,      \%f   */
    SQL_C_DOUBLE,                   /* APR_DBD_TYPE_DOUBLE,     \%lf  */
    SQL_C_CHAR,                     /* APR_DBD_TYPE_STRING,     \%s   */
    SQL_C_CHAR,                     /* APR_DBD_TYPE_TEXT,       \%pDt */
    SQL_C_CHAR, /*SQL_C_TYPE_TIME,      APR_DBD_TYPE_TIME,       \%pDi */
    SQL_C_CHAR, /*SQL_C_TYPE_DATE,      APR_DBD_TYPE_DATE,       \%pDd */
    SQL_C_CHAR, /*SQL_C_TYPE_TIMESTAMP, APR_DBD_TYPE_DATETIME,   \%pDa */
    SQL_C_CHAR, /*SQL_C_TYPE_TIMESTAMP, APR_DBD_TYPE_TIMESTAMP,  \%pDs */
    SQL_C_CHAR, /*SQL_C_TYPE_TIMESTAMP, APR_DBD_TYPE_ZTIMESTAMP, \%pDz */
    SQL_LONGVARBINARY,              /* APR_DBD_TYPE_BLOB,       \%pDb */
    SQL_LONGVARCHAR,                /* APR_DBD_TYPE_CLOB,       \%pDc */
    SQL_TYPE_NULL                   /* APR_DBD_TYPE_NULL        \%pDn */
};

/*  ODBC Base types to DBD datatypes */
static SQLSMALLINT const sqlBaseType[] = {
    SQL_C_DEFAULT,              /* APR_DBD_TYPE_NONE              */
    SQL_TINYINT,                /* APR_DBD_TYPE_TINY,       \%hhd */
    SQL_TINYINT,                /* APR_DBD_TYPE_UTINY,      \%hhu */
    SQL_SMALLINT,               /* APR_DBD_TYPE_SHORT,      \%hd  */
    SQL_SMALLINT,               /* APR_DBD_TYPE_USHORT,     \%hu  */
    SQL_INTEGER,                /* APR_DBD_TYPE_INT,        \%d   */
    SQL_INTEGER,                /* APR_DBD_TYPE_UINT,       \%u   */
    SQL_INTEGER,                /* APR_DBD_TYPE_LONG,       \%ld  */
    SQL_INTEGER,                /* APR_DBD_TYPE_ULONG,      \%lu  */
    SQL_BIGINT,                 /* APR_DBD_TYPE_LONGLONG,   \%lld */
    SQL_BIGINT,                 /* APR_DBD_TYPE_ULONGLONG,  \%llu */
    SQL_FLOAT,                  /* APR_DBD_TYPE_FLOAT,      \%f   */
    SQL_DOUBLE,                 /* APR_DBD_TYPE_DOUBLE,     \%lf  */
    SQL_CHAR,                   /* APR_DBD_TYPE_STRING,     \%s   */
    SQL_CHAR,                   /* APR_DBD_TYPE_TEXT,       \%pDt */
    SQL_CHAR, /*SQL_TIME,          APR_DBD_TYPE_TIME,       \%pDi */
    SQL_CHAR, /*SQL_DATE,          APR_DBD_TYPE_DATE,       \%pDd */
    SQL_CHAR, /*SQL_TIMESTAMP,     APR_DBD_TYPE_DATETIME,   \%pDa */
    SQL_CHAR, /*SQL_TIMESTAMP,     APR_DBD_TYPE_TIMESTAMP,  \%pDs */
    SQL_CHAR, /*SQL_TIMESTAMP,     APR_DBD_TYPE_ZTIMESTAMP, \%pDz */
    SQL_LONGVARBINARY,          /* APR_DBD_TYPE_BLOB,       \%pDb */
    SQL_LONGVARCHAR,            /* APR_DBD_TYPE_CLOB,       \%pDc */
    SQL_TYPE_NULL               /* APR_DBD_TYPE_NULL        \%pDn */
};

/*  result sizes for DBD datatypes (-1 for null-terminated) */
static int const sqlSizes[] = {
    0,
    sizeof(char),               /**< \%hhd out: char* */
    sizeof(unsigned char),      /**< \%hhu out: unsigned char* */
    sizeof(short),              /**< \%hd  out: short* */
    sizeof(unsigned short),     /**< \%hu  out: unsigned short* */
    sizeof(int),                /**< \%d   out: int* */
    sizeof(unsigned int),       /**< \%u   out: unsigned int* */
    sizeof(long),               /**< \%ld  out: long* */
    sizeof(unsigned long),      /**< \%lu  out: unsigned long* */
    sizeof(apr_int64_t),        /**< \%lld out: apr_int64_t* */
    sizeof(apr_uint64_t),       /**< \%llu out: apr_uint64_t* */
    sizeof(float),              /**< \%f   out: float* */
    sizeof(double),             /**< \%lf  out: double* */
    -1,                         /**< \%s   out: char** */
    -1,                         /**< \%pDt out: char** */
    -1,                         /**< \%pDi out: char** */
    -1,                         /**< \%pDd out: char** */
    -1,                         /**< \%pDa out: char** */
    -1,                         /**< \%pDs out: char** */
    -1,                         /**< \%pDz out: char** */
    sizeof(apr_bucket_brigade), /**< \%pDb out: apr_bucket_brigade* */
    sizeof(apr_bucket_brigade), /**< \%pDc out: apr_bucket_brigade* */
    0                           /**< \%pDn : in: void*, out: void** */
};

/*
*   local functions
*/

/* close any open results for the connection */
static apr_status_t odbc_close_results(void *d)
{   apr_dbd_results_t *dbr = (apr_dbd_results_t *) d;
    SQLRETURN rc = SQL_SUCCESS;
    
    if (dbr && dbr->apr_dbd && dbr->apr_dbd->dbc) {
    	if (!dbr->isclosed) 
        	rc = SQLCloseCursor(dbr->stmt);
    	dbr->isclosed = 1;
    }
    return APR_FROM_SQL_RESULT(rc);
}

/* close the ODBC statement handle from a  prepare */
static apr_status_t odbc_close_pstmt(void *s)
{   
    SQLRETURN rc = APR_SUCCESS;
    apr_dbd_prepared_t *statement = s;
    /* stmt is closed if connection has already been closed */
    if (statement) {
        SQLHANDLE hstmt = statement->stmt;

        if (hstmt && statement->apr_dbd && statement->apr_dbd->dbc) {
            rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
        }
        statement->stmt = NULL;
    }
    return APR_FROM_SQL_RESULT(rc);
}

/* close: close/release a connection obtained from open() */
static apr_status_t odbc_close(apr_dbd_t *handle)
{
    SQLRETURN rc = SQL_SUCCESS;

    if (handle->dbc) {
        rc = SQLDisconnect(handle->dbc);
        CHECK_ERROR(handle, "SQLDisconnect", rc, SQL_HANDLE_DBC, handle->dbc);
        rc = SQLFreeHandle(SQL_HANDLE_DBC, handle->dbc);
        CHECK_ERROR(handle, "SQLFreeHandle (DBC)", rc, SQL_HANDLE_ENV, henv);
        handle->dbc = NULL;
    }
    return APR_FROM_SQL_RESULT(rc);
}

/* odbc_close re-defined for passing to pool cleanup */
static apr_status_t odbc_close_cleanup(void *handle)
{
    return odbc_close( (apr_dbd_t *) handle);
}

/* close the ODBC environment handle at process termination */
static apr_status_t odbc_close_env(SQLHANDLE henv)
{   
    SQLRETURN rc;

    rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
    henv = NULL;
    return APR_FROM_SQL_RESULT(rc);
}

/* setup the arrays in results for all the returned columns */
static SQLRETURN odbc_set_result_column(int icol, apr_dbd_results_t * res, 
                                         SQLHANDLE stmt)
{
    SQLRETURN rc;
    int maxsize, textsize, realsize, type, isunsigned = 1;

     /* discover the sql type */
    rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_UNSIGNED, NULL, 0, NULL,
                         (SQLPOINTER) &isunsigned);
    isunsigned = (isunsigned == SQL_TRUE);

    rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_TYPE, NULL, 0, NULL,
                         (SQLPOINTER) &type);
    if (!SQL_SUCCEEDED(rc) || type == SQL_UNKNOWN_TYPE)
        /* MANY ODBC v2 datasources only supply CONCISE_TYPE */
        rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_CONCISE_TYPE, NULL,
                             0, NULL, (SQLPOINTER) &type);
    if (!SQL_SUCCEEDED(rc))
        /* if still unknown make it CHAR */
        type = SQL_C_CHAR;

    switch (type) {
    case SQL_INTEGER:
    case SQL_SMALLINT:
    case SQL_TINYINT:
    case SQL_BIGINT:
      /* fix these numeric binary types up as signed/unsigned for C types */
      type += (isunsigned) ? SQL_UNSIGNED_OFFSET : SQL_SIGNED_OFFSET;
      break;
    /* LOB types are not changed to C types */
    case SQL_LONGVARCHAR: 
        type = SQL_LONGVARCHAR; 
        break;
    case SQL_LONGVARBINARY: 
        type = SQL_LONGVARBINARY; 
        break;
    case SQL_FLOAT : 
        type = SQL_C_FLOAT; 
        break;
    case SQL_DOUBLE : 
        type = SQL_C_DOUBLE; 
        break;

    /* DBD wants times as strings */
    case SQL_TIMESTAMP:      
    case SQL_DATE:
    case SQL_TIME:
    default:
      type = SQL_C_CHAR;
    }

    res->coltypes[icol] = type;

    /* size if retrieved as text */
    rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0,
                         NULL, (SQLPOINTER) & textsize);
     if (!SQL_SUCCEEDED(rc) || textsize < 0)
        textsize = res->apr_dbd->defaultBufferSize;
    /* for null-term, which sometimes isn't included */
    textsize++;

    /* real size */
    rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_OCTET_LENGTH, NULL, 0,
                         NULL, (SQLPOINTER) & realsize);
    if (!SQL_SUCCEEDED(rc))
        realsize = textsize;

    maxsize = (textsize > realsize) ? textsize : realsize;
    if ( IS_LOB(type) || maxsize <= 0) {
        /* LOB types are never bound and have a NULL colptr for binary.
         * Ingore their real (1-2gb) length & use a default - the larger
         * of defaultBufferSize or APR_BUCKET_BUFF_SIZE.
         * If not a LOB, but simply unknown length - always use defaultBufferSize.
         */
        maxsize = res->apr_dbd->defaultBufferSize;
        if ( IS_LOB(type) && maxsize < APR_BUCKET_BUFF_SIZE )
            maxsize = APR_BUCKET_BUFF_SIZE;

        res->colptrs[icol] =  NULL;
        res->colstate[icol] = COL_AVAIL;
        res->colsizes[icol] = maxsize;
        rc = SQL_SUCCESS;
    }
    else {
        res->colptrs[icol] = apr_pcalloc(res->pool, maxsize);
        res->colsizes[icol] = maxsize;
        if (res->apr_dbd->dboptions & SQL_GD_BOUND) {
            /* we are allowed to call SQLGetData if we need to */
            rc = SQLBindCol(stmt, icol + 1, res->coltypes[icol], 
                            res->colptrs[icol], maxsize, 
                            &(res->colinds[icol]) );
            CHECK_ERROR(res->apr_dbd, "SQLBindCol", rc, SQL_HANDLE_STMT,
                        stmt);
            res->colstate[icol] = SQL_SUCCEEDED(rc) ? COL_BOUND : COL_AVAIL;
        }
        else {
            /* this driver won't allow us to call SQLGetData on bound 
             * columns - so don't bind any */
            res->colstate[icol] = COL_AVAIL;
            rc = SQL_SUCCESS;
        }
    }
    return rc;
}

/* create and populate an apr_dbd_results_t for a select */
static SQLRETURN odbc_create_results(apr_dbd_t * handle, SQLHANDLE hstmt,
                                     apr_pool_t * pool, const int random,
                                     apr_dbd_results_t ** res)
{
    SQLRETURN rc;
    SQLSMALLINT ncols;

    *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
    (*res)->stmt = hstmt;
    (*res)->dbc = handle->dbc;
    (*res)->pool = pool;
    (*res)->random = random;
    (*res)->apr_dbd = handle;
    rc = SQLNumResultCols(hstmt, &ncols);
    CHECK_ERROR(handle, "SQLNumResultCols", rc, SQL_HANDLE_STMT, hstmt);
    (*res)->ncols = ncols;

    if SQL_SUCCEEDED(rc) {
        int i;

        (*res)->colnames = apr_pcalloc(pool, ncols * sizeof(char *));
        (*res)->colptrs = apr_pcalloc(pool, ncols * sizeof(void *));
        (*res)->colsizes = apr_pcalloc(pool, ncols * sizeof(SQLINTEGER));
        (*res)->coltypes = apr_pcalloc(pool, ncols * sizeof(SQLSMALLINT));
        (*res)->colinds = apr_pcalloc(pool, ncols * sizeof(SQLLEN));
        (*res)->colstate = apr_pcalloc(pool, ncols * sizeof(int));
        (*res)->ncols = ncols;

        for (i = 0 ; i < ncols ; i++)
            odbc_set_result_column(i, (*res), hstmt);
        }
    return rc;
}


/* bind a parameter - input params only, does not support output parameters */
static SQLRETURN odbc_bind_param(apr_pool_t * pool,
                                 apr_dbd_prepared_t * statement, const int narg,
                                 const SQLSMALLINT type, int *argp,
                                 const void **args, const int textmode)
{
    SQLRETURN rc;
    SQLSMALLINT baseType, cType;
    void *ptr;
    SQLUINTEGER len;
    SQLINTEGER *indicator;
    static SQLINTEGER nullValue = SQL_NULL_DATA;
    static SQLSMALLINT inOut = SQL_PARAM_INPUT;     /* only input params */

    /* bind a NULL data value */
    if (args[*argp] == NULL || type == APR_DBD_TYPE_NULL) {
        baseType = SQL_CHAR;
        cType = SQL_C_CHAR;
        ptr = &nullValue;
        len = sizeof(SQLINTEGER);
        indicator = &nullValue;
        (*argp)++;
    }
    /* bind a non-NULL data value */
    else {
        baseType = sqlBaseType[type];
        cType = sqlCtype[type];
        indicator = NULL;
        /* LOBs */
        if (IS_LOB(cType)) {
            ptr = (void *) args[*argp];
            len = (SQLUINTEGER) * (apr_size_t *) args[*argp + 1];
            cType = (IS_CLOB(cType)) ? SQL_C_CHAR : SQL_C_DEFAULT;
            (*argp) += 4;  /* LOBs consume 4 args (last two are unused) */
        }
        /* non-LOBs */
        else {
            switch (baseType) {
            case SQL_CHAR:
            case SQL_DATE:
            case SQL_TIME:
            case SQL_TIMESTAMP:
                ptr = (void *) args[*argp];
                len = (SQLUINTEGER) strlen(ptr);
                break;
            case SQL_TINYINT:
                ptr = apr_palloc(pool, sizeof(unsigned char));
                len = sizeof(unsigned char);
                *(unsigned char *) ptr =
                    (textmode ?
                     atoi(args[*argp]) : *(unsigned char *) args[*argp]);
                break;
            case SQL_SMALLINT:
                ptr = apr_palloc(pool, sizeof(short));
                len = sizeof(short);
                *(short *) ptr =
                    (textmode ? atoi(args[*argp]) : *(short *) args[*argp]);
                break;
            case SQL_INTEGER:
                ptr = apr_palloc(pool, sizeof(int));
                len = sizeof(int);
                *(long *) ptr =
                    (textmode ? atol(args[*argp]) : *(long *) args[*argp]);
                break;
            case SQL_FLOAT:
                ptr = apr_palloc(pool, sizeof(float));
                len = sizeof(float);
                *(float *) ptr =
                    (textmode ?
                     (float) atof(args[*argp]) : *(float *) args[*argp]);
                break;
            case SQL_DOUBLE:
                ptr = apr_palloc(pool, sizeof(double));
                len = sizeof(double);
                *(double *) ptr =
                    (textmode ? atof(args[*argp]) : *(double *)
                     args[*argp]);
                break;
            case SQL_BIGINT:
                ptr = apr_palloc(pool, sizeof(apr_int64_t));
                len = sizeof(apr_int64_t);
                *(apr_int64_t *) ptr =
                    (textmode ?
                     apr_atoi64(args[*argp]) : *(apr_int64_t *) args[*argp]);
                break;
            default:
                return APR_EGENERAL;
            }
            (*argp)++;          /* non LOBs consume one argument */
        }
    }
    rc = SQLBindParameter(statement->stmt, narg, inOut, cType, 
                          baseType, len, 0, ptr, len, indicator);
    CHECK_ERROR(statement->apr_dbd, "SQLBindParameter", rc, SQL_HANDLE_STMT,
                statement->stmt);
    return rc;
}

/* LOB / Bucket Brigade functions */



/* bucket type specific destroy */
static void odbc_lob_bucket_destroy(void *data)
{
    odbc_bucket *bd = data;

    if (apr_bucket_shared_destroy(bd))
        apr_bucket_free(bd);
}

/* set aside a bucket if possible */
static apr_status_t odbc_lob_bucket_setaside(apr_bucket *e, apr_pool_t *pool)
{
    odbc_bucket *bd = (odbc_bucket *) e->data;

    /* Unlikely - but if the row pool is ancestor of this pool then it is OK */
    if (apr_pool_is_ancestor(bd->row->pool, pool))
        return APR_SUCCESS;
    
    return apr_bucket_setaside_notimpl(e, pool);
}

/* split a bucket into a heap bucket followed by a LOB bkt w/remaining data */
static apr_status_t odbc_lob_bucket_read(apr_bucket *e, const char **str,
                                         apr_size_t *len, apr_read_type_e block)
{
    SQLRETURN rc;
    SQLINTEGER len_indicator;
    SQLSMALLINT type;
    odbc_bucket *bd = (odbc_bucket *) e->data;
    apr_bucket *nxt;
    void *buf;
    int bufsize = bd->row->res->apr_dbd->defaultBufferSize;
    int eos;
    
    /* C type is CHAR for CLOBs, DEFAULT for BLOBs */
    type = bd->row->res->coltypes[bd->col];
    type = (type == SQL_LONGVARCHAR) ? SQL_C_CHAR : SQL_C_DEFAULT;

    /* LOB buffers are always at least APR_BUCKET_BUFF_SIZE, 
     *   but they may be much bigger per the BUFSIZE parameter.
    */
    if (bufsize < APR_BUCKET_BUFF_SIZE)
            bufsize = APR_BUCKET_BUFF_SIZE;

    buf = apr_bucket_alloc(bufsize, e->list);
    *str = NULL;
    *len = 0;

    rc = SQLGetData(bd->row->res->stmt, bd->col + 1, 
                    type, buf, bufsize, 
                    &len_indicator);

    CHECK_ERROR(bd->row->res->apr_dbd, "SQLGetData", rc, 
                SQL_HANDLE_STMT, bd->row->res->stmt);
    
    if (rc == SQL_NO_DATA || len_indicator == SQL_NULL_DATA || len_indicator < 0)
        len_indicator = 0;

    if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA) {

        if (rc == SQL_SUCCESS_WITH_INFO
            && ( len_indicator == SQL_NO_TOTAL || len_indicator >= bufsize) ) {
            /* not the last read = a full buffer. CLOBs have a null terminator */
            *len = bufsize - (IS_CLOB(bd->type) ? 1 : 0 );

             eos = 0;
        }
        else {
            /* the last read - len_indicator is supposed to be the length, 
             * but some driver get this wrong and return the total length.
             * We try to handle both interpretations.
             */
            *len =  (len_indicator > bufsize 
                     && len_indicator >= (SQLINTEGER) e->start)
                ? (len_indicator - (SQLINTEGER) e->start) : len_indicator;

            eos = 1;
        }

        if (!eos) {
            /* Create a new LOB bucket to append and append it */
            nxt = apr_bucket_alloc(sizeof(apr_bucket *), e->list);
            APR_BUCKET_INIT(nxt);
            nxt->length = -1;
            nxt->data   = e->data;
            nxt->type   = &odbc_bucket_type;
            nxt->free   = apr_bucket_free;
            nxt->list   = e->list;
            nxt->start  = e->start + *len;
            APR_BUCKET_INSERT_AFTER(e, nxt);
        }
        else {
            odbc_lob_bucket_destroy(e->data);
        }
        /* make current bucket into a heap bucket */
        apr_bucket_heap_make(e, buf, *len, apr_bucket_free);
        *str = buf;

        /* No data is success in this context */
        rc = SQL_SUCCESS;
    }
    return APR_FROM_SQL_RESULT(rc);
}

/* Create a bucket brigade on the row pool for a LOB column */
static apr_status_t odbc_create_bucket(const apr_dbd_row_t *row, const int col, 
                                       SQLSMALLINT type, apr_bucket_brigade *bb)
{
    apr_bucket_alloc_t *list = bb->bucket_alloc;
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
    odbc_bucket *bd = apr_bucket_alloc(sizeof(odbc_bucket), list);
    apr_bucket *eos = apr_bucket_eos_create(list);
    

    bd->row = row;
    bd->col = col;
    bd->type = type;


    APR_BUCKET_INIT(b);
    b->type = &odbc_bucket_type;
    b->free = apr_bucket_free;
    b->list = list;
    /* LOB lengths are unknown in ODBC */
    b = apr_bucket_shared_make(b, bd, 0, -1);

    APR_BRIGADE_INSERT_TAIL(bb, b);
    APR_BRIGADE_INSERT_TAIL(bb, eos);

    return APR_SUCCESS;
}

/* returns a data pointer for a column,  returns NULL for NULL value,
 * return -1 if data not available */
static void *odbc_get(const apr_dbd_row_t *row, const int col, 
                      const SQLSMALLINT sqltype)
{
    SQLRETURN rc;
    SQLINTEGER indicator;
    int state = row->res->colstate[col];
    int options = row->res->apr_dbd->dboptions;

    switch (state) {
    case (COL_UNAVAIL) : return (void *) -1;
    case (COL_RETRIEVED) :  return NULL;

    case (COL_BOUND) :
    case (COL_PRESENT) : 
        if (sqltype == row->res->coltypes[col]) {
            /* same type and we already have the data */
            row->res->colstate[col] = COL_RETRIEVED;
            return (row->res->colinds[col] == SQL_NULL_DATA) ? 
                NULL : row->res->colptrs[col];
        }
    }

    /* we need to get the data now */
    if (!(options & SQL_GD_ANY_ORDER)) {
        /* this ODBC driver requires columns to be retrieved in order,
         * so we attempt to get every prior un-gotten non-LOB column */
        int i;
        for (i = 0; i < col; i++) {
            if (row->res->colstate[i] == COL_AVAIL) {
                if (IS_LOB(row->res->coltypes[i]))
                       row->res->colstate[i] = COL_UNAVAIL;
                else {
                    odbc_get(row, i, row->res->coltypes[i]);
                    row->res->colstate[i] = COL_PRESENT;
                }
            }
        }
    }

    if ((state == COL_BOUND && !(options & SQL_GD_BOUND)))
        /* this driver won't let us re-get bound columns */
        return (void *) -1;

    /* a LOB might not have a buffer allocated yet - so create one */
    if (!row->res->colptrs[col])
        row->res->colptrs[col] = apr_pcalloc(row->pool, row->res->colsizes[col]);

    rc = SQLGetData(row->res->stmt, col + 1, sqltype, row->res->colptrs[col],
                    row->res->colsizes[col], &indicator);
    CHECK_ERROR(row->res->apr_dbd, "SQLGetData", rc, SQL_HANDLE_STMT, 
                row->res->stmt);
    if (indicator == SQL_NULL_DATA || rc == SQL_NO_DATA)
        return NULL;

    if (SQL_SUCCEEDED(rc)) {
        /* whatever it was originally, it is now this sqltype */
        row->res->coltypes[col] = sqltype;
        /* this allows getting CLOBs in text mode by calling get_entry
         *   until it returns NULL */
        row->res->colstate[col] = 
            (rc == SQL_SUCCESS_WITH_INFO) ? COL_AVAIL : COL_RETRIEVED;
        return row->res->colptrs[col];
    }
    else  return (void *) -1;
}

/* Parse the parameter string for open */
static apr_status_t odbc_parse_params(apr_pool_t *pool, const char *params,
                               int *connect, SQLCHAR **datasource, 
                               SQLCHAR **user, SQLCHAR **password, 
                               int *defaultBufferSize, int *nattrs,
                               int **attrs, int **attrvals)
{
    char *seps, *last, *name[MAX_PARAMS], *val[MAX_PARAMS];
    int nparams=0, i, j;

    *attrs = apr_pcalloc(pool, MAX_PARAMS * sizeof(char *));
    *attrvals = apr_pcalloc(pool, MAX_PARAMS * sizeof(int));
    *nattrs = 0;
    seps = DEFAULTSEPS;
    name[nparams] = apr_strtok(apr_pstrdup(pool, params), seps, &last);

    /* no params is OK here - let connect return a more useful error msg */
    if (!name[nparams])
        return SQL_SUCCESS;

    do {
        if (last[strspn(last, seps)] == CSINGLEQUOTE) {
            last += strspn(last, seps);
            seps=SSINGLEQUOTE;
        }
        val[nparams] = apr_strtok(NULL, seps, &last);
        seps = DEFAULTSEPS;
        name[++nparams] = apr_strtok(NULL, seps, &last);
    } while ( nparams <= MAX_PARAMS && name[nparams] != NULL);

    for(j=i=0 ; i< nparams ; i++)
    {   if      (!apr_strnatcasecmp(name[i], "CONNECT"))
        {   *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
            *connect=1;
        }
        else if (!apr_strnatcasecmp(name[i], "DATASOURCE"))
        {   *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
            *connect=0;
        }
        else if (!apr_strnatcasecmp(name[i], "USER"))
            *user = (SQLCHAR *)apr_pstrdup(pool, val[i]);
        else if (!apr_strnatcasecmp(name[i], "PASSWORD"))
            *password = (SQLCHAR *)apr_pstrdup(pool, val[i]);
        else if (!apr_strnatcasecmp(name[i], "BUFSIZE"))
            *defaultBufferSize = atoi(val[i]);
        else if (!apr_strnatcasecmp(name[i], "ACCESS"))
        {   if  (!apr_strnatcasecmp(val[i], "READ_ONLY"))
                (*attrvals)[j] = SQL_MODE_READ_ONLY;
            else if (!apr_strnatcasecmp(val[i], "READ_WRITE"))
                (*attrvals)[j] = SQL_MODE_READ_WRITE;
            else return SQL_ERROR;
            (*attrs)[j++] = SQL_ATTR_ACCESS_MODE;
        }
        else if (!apr_strnatcasecmp(name[i], "CTIMEOUT"))
        {   (*attrvals)[j] = atoi(val[i]);
            (*attrs)[j++] = SQL_ATTR_LOGIN_TIMEOUT;
        }
        else if (!apr_strnatcasecmp(name[i], "STIMEOUT"))
        {   (*attrvals)[j] = atoi(val[i]);
            (*attrs)[j++] = SQL_ATTR_CONNECTION_TIMEOUT;
        }
        else if (!apr_strnatcasecmp(name[i], "TXMODE"))
        {   if      (!apr_strnatcasecmp(val[i], "READ_UNCOMMITTED"))
                (*attrvals)[j] = SQL_TXN_READ_UNCOMMITTED;
            else if (!apr_strnatcasecmp(val[i], "READ_COMMITTED"))
                (*attrvals)[j] = SQL_TXN_READ_COMMITTED;
            else if (!apr_strnatcasecmp(val[i], "REPEATABLE_READ"))
                (*attrvals)[j] = SQL_TXN_REPEATABLE_READ;
            else if (!apr_strnatcasecmp(val[i], "SERIALIZABLE"))
                (*attrvals)[j] = SQL_TXN_SERIALIZABLE;
            else if (!apr_strnatcasecmp(val[i], "DEFAULT"))
                continue;
            else return SQL_ERROR;
            (*attrs)[j++] = SQL_ATTR_TXN_ISOLATION;
        }
        else return SQL_ERROR;
    }
    *nattrs = j;
    return (*datasource && *defaultBufferSize) ? APR_SUCCESS : SQL_ERROR;
}

/* common handling after ODBC calls - save error info (code and text) in dbc */
static void check_error(apr_dbd_t *dbc, const char *step, SQLRETURN rc,
                 SQLSMALLINT type, SQLHANDLE h, int line)
{
    SQLCHAR buffer[512];
    SQLCHAR sqlstate[128];
    SQLINTEGER native;
    SQLSMALLINT reslength;
    char *res, *p, *end, *logval=NULL;
    int i;
    apr_status_t r;

    /* set info about last error in dbc  - fast return for SQL_SUCCESS  */
    if (rc == SQL_SUCCESS) {
        char successMsg[] = "[dbd_odbc] SQL_SUCCESS ";
        dbc->lasterrorcode = SQL_SUCCESS;
        strcpy(dbc->lastError, successMsg);
        strcpy(dbc->lastError+sizeof(successMsg)-1, step);
        return;
    }
    switch (rc) {
        case SQL_INVALID_HANDLE     : { res = "SQL_INVALID_HANDLE"; break; }
        case SQL_ERROR              : { res = "SQL_ERROR"; break; }   
        case SQL_SUCCESS_WITH_INFO  : { res = "SQL_SUCCESS_WITH_INFO"; break; }
        case SQL_STILL_EXECUTING    : { res = "SQL_STILL_EXECUTING"; break; }
        case SQL_NEED_DATA          : { res = "SQL_NEED_DATA"; break; }
        case SQL_NO_DATA            : { res = "SQL_NO_DATA"; break; }
        default                     : { res = "unrecognized SQL return code"; }
    }
    /* these two returns are expected during normal execution */
    if (rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA 
        && dbc->can_commit != APR_DBD_TRANSACTION_IGNORE_ERRORS)
    {
        dbc->can_commit = APR_DBD_TRANSACTION_ROLLBACK;
    }
    p = dbc->lastError;
    end = p + sizeof(dbc->lastError);
    dbc->lasterrorcode = rc;
    p += sprintf(p, "[dbd_odbc] %.64s returned %.30s (%d) at %.24s:%d ",
                 step, res, rc, SOURCE_FILE, line-1);
    for (i=1, rc=0 ; rc==0 ; i++) {
        rc = SQLGetDiagRec(type, h, i, sqlstate, &native, buffer, 
                            sizeof(buffer), &reslength);
        if (SQL_SUCCEEDED(rc) && (p < (end-280))) 
            p += sprintf(p, "%.256s %.20s ", buffer, sqlstate);
    }
    r = apr_env_get(&logval, "apr_dbd_odbc_log", dbc->pool);
    /* if env var was set or call was init/open (no dbname) - log to stderr */
    if (logval || !dbc->dbname ) {
        char timestamp[APR_CTIME_LEN];
        apr_file_t *se;
        apr_ctime(timestamp, apr_time_now());
        apr_file_open_stderr(&se, dbc->pool);
        apr_file_printf(se, "[%s] %s\n", timestamp, dbc->lastError);
    }
}

static APR_INLINE int odbc_check_rollback(apr_dbd_t *handle)
{
    if (handle->can_commit == APR_DBD_TRANSACTION_ROLLBACK) {
        handle->lasterrorcode = SQL_ERROR;
        strcpy(handle->lastError, "[dbd_odbc] Rollback pending ");
        return 1;
    }
    return 0;
}
/*
*   public functions per DBD driver API
*/

/** init: allow driver to perform once-only initialisation. **/
static void odbc_init(apr_pool_t *pool)
{
    SQLRETURN rc;
    char *step;
    apr_version_t apuver;
    
    apu_version(&apuver);
    if (apuver.major != DRIVER_APU_VERSION_MAJOR 
        || apuver.minor != DRIVER_APU_VERSION_MINOR) {
            apr_file_t *se;

            apr_file_open_stderr(&se, pool);
            apr_file_printf(se, "Incorrect " ODBC_DRIVER_STRING " dbd driver version\n"
                "Attempt to load APU version %d.%d driver with APU version %d.%d\n",
                DRIVER_APU_VERSION_MAJOR, DRIVER_APU_VERSION_MINOR, 
                apuver.major, apuver.minor);
        abort();
    }

    if (henv) 
        return;

    step = "SQLAllocHandle (SQL_HANDLE_ENV)";
    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    apr_pool_cleanup_register(pool, henv, odbc_close_env, apr_pool_cleanup_null);
    if (SQL_SUCCEEDED(rc))
    {   step = "SQLSetEnvAttr";
        rc = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,
                          (SQLPOINTER) SQL_OV_ODBC3, 0);
    }
    else
    {   apr_dbd_t tmp_dbc;
        SQLHANDLE err_h = henv;

        tmp_dbc.pool = pool;
        tmp_dbc.dbname = NULL;
        CHECK_ERROR(&tmp_dbc, step, rc, SQL_HANDLE_ENV, err_h);
    }
}

/** native_handle: return the native database handle of the underlying db **/
static void* odbc_native_handle(apr_dbd_t *handle)
{   return handle->dbc;
}

/** open: obtain a database connection from the server rec. **/

/* It would be more efficient to allocate a single statement handle 
    here - but SQL_ATTR_CURSOR_SCROLLABLE must be set before
    SQLPrepare, and we don't know whether random-access is
    specified until SQLExecute so we cannot.
*/

static apr_dbd_t* odbc_open(apr_pool_t *pool, const char *params, const char **error)
{
    SQLRETURN   rc;
    SQLHANDLE   hdbc = NULL;
    apr_dbd_t   *handle;
    char *err_step;
    int err_htype, i;
    int defaultBufferSize=DEFAULT_BUFFER_SIZE;
    SQLHANDLE err_h = NULL;
    SQLCHAR  *datasource=(SQLCHAR *)"", *user=(SQLCHAR *)"",
             *password=(SQLCHAR *)"";
    int nattrs=0, *attrs=NULL, *attrvals=NULL, connect=0;

    err_step="SQLAllocHandle (SQL_HANDLE_DBC)";
    err_htype = SQL_HANDLE_ENV;
    err_h = henv;
    rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    if (SQL_SUCCEEDED(rc)) {
        err_step="Invalid DBD Parameters - open";
        err_htype = SQL_HANDLE_DBC;
        err_h = hdbc;
        rc = odbc_parse_params(pool, params, &connect, &datasource, &user,
                               &password, &defaultBufferSize, &nattrs, &attrs,
                               &attrvals);
    }
    if (SQL_SUCCEEDED(rc)) {
        for (i=0 ; i < nattrs && SQL_SUCCEEDED(rc); i++) {
            err_step="SQLSetConnectAttr (from DBD Parameters)";
            err_htype = SQL_HANDLE_DBC;
            err_h = hdbc;
            rc = SQLSetConnectAttr(hdbc, attrs[i], (void *) attrvals[i], 0);
        }
    }
    if (SQL_SUCCEEDED(rc)) {
        if (connect) {
            SQLCHAR out[1024];
            SQLSMALLINT outlen;
            err_step="SQLDriverConnect";
            err_htype = SQL_HANDLE_DBC;
            err_h = hdbc;
            rc = SQLDriverConnect(hdbc, NULL, datasource,
                        (SQLSMALLINT) strlen((char *)datasource),
                        out, sizeof(out), &outlen, SQL_DRIVER_NOPROMPT);
        }
        else {
            err_step="SQLConnect";
            err_htype = SQL_HANDLE_DBC;
            err_h = hdbc;
            rc = SQLConnect(hdbc, datasource,
                        (SQLSMALLINT) strlen((char *)datasource),
                        user, (SQLSMALLINT) strlen((char *)user),
                        password, (SQLSMALLINT) strlen((char *)password));
        }
    }
    if (SQL_SUCCEEDED(rc)) {
        handle = apr_pcalloc(pool, sizeof(apr_dbd_t));
        handle->dbname = apr_pstrdup(pool, (char *)datasource);
        handle->dbc = hdbc;
        handle->pool = pool;
        handle->defaultBufferSize = defaultBufferSize;
        CHECK_ERROR(handle, "SQLConnect", rc, SQL_HANDLE_DBC, handle->dbc);
        handle->default_transaction_mode = 0;
        handle->can_commit = APR_DBD_TRANSACTION_IGNORE_ERRORS;
        SQLGetInfo(hdbc, SQL_DEFAULT_TXN_ISOLATION,
                   &(handle->default_transaction_mode), sizeof(int), NULL);
        handle->transaction_mode = handle->default_transaction_mode;
        SQLGetInfo(hdbc, SQL_GETDATA_EXTENSIONS ,&(handle->dboptions),
                   sizeof(int), NULL);
        apr_pool_cleanup_register(pool, handle, odbc_close_cleanup, apr_pool_cleanup_null);
        return handle;
    }
    else {
        apr_dbd_t tmp_dbc;
        tmp_dbc.pool = pool;
        tmp_dbc.dbname = NULL;
        CHECK_ERROR(&tmp_dbc, err_step, rc, err_htype, err_h);
        if (error)
            *error = apr_pstrdup(pool, tmp_dbc.lastError);
        if (hdbc)
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
        return NULL;
    }
}

/** check_conn: check status of a database connection **/
static apr_status_t odbc_check_conn(apr_pool_t *pool, apr_dbd_t *handle)
{
    SQLUINTEGER isDead;
    SQLRETURN   rc;

    rc = SQLGetConnectAttr(handle->dbc, SQL_ATTR_CONNECTION_DEAD, &isDead,
                            sizeof(SQLUINTEGER), NULL);
    CHECK_ERROR(handle, "SQLGetConnectAttr (SQL_ATTR_CONNECTION_DEAD)", rc,
                SQL_HANDLE_DBC, handle->dbc);
    /* if driver cannot check connection, say so */
    if (rc != SQL_SUCCESS)
        return APR_ENOTIMPL;

    return (isDead == SQL_CD_FALSE) ? APR_SUCCESS : APR_EGENERAL;
}


/** set_dbname: select database name.  May be a no-op if not supported. **/
static int odbc_set_dbname(apr_pool_t* pool, apr_dbd_t *handle,
                           const char *name)
{
    if (apr_strnatcmp(name, handle->dbname)) {
        return APR_EGENERAL;        /* It's illegal to change dbname in ODBC */
    }
    CHECK_ERROR(handle, "set_dbname (no-op)", SQL_SUCCESS, SQL_HANDLE_DBC,
                handle->dbc);
    return APR_SUCCESS;             /* OK if it's the same name */
}

/** transaction: start a transaction.  May be a no-op. **/
static int odbc_start_transaction(apr_pool_t *pool, apr_dbd_t *handle,
                                  apr_dbd_transaction_t **trans)
{
    SQLRETURN rc = SQL_SUCCESS;

    if (handle->transaction_mode) {
        rc = SQLSetConnectAttr(handle->dbc, SQL_ATTR_TXN_ISOLATION, (void *)
                               handle->transaction_mode, 0);
        CHECK_ERROR(handle, "SQLSetConnectAttr (SQL_ATTR_TXN_ISOLATION)", rc,
                    SQL_HANDLE_DBC, handle->dbc);
    }
    if SQL_SUCCEEDED(rc) {
        /* turn off autocommit for transactions */
        rc = SQLSetConnectAttr(handle->dbc, SQL_ATTR_AUTOCOMMIT,
                               SQL_AUTOCOMMIT_OFF, 0);
        CHECK_ERROR(handle, "SQLSetConnectAttr (SQL_ATTR_AUTOCOMMIT)", rc,
                    SQL_HANDLE_DBC, handle->dbc);
    }
    if SQL_SUCCEEDED(rc) {
        *trans = apr_palloc(pool, sizeof(apr_dbd_transaction_t));
        (*trans)->dbc = handle->dbc;
        (*trans)->apr_dbd = handle;
    }
    handle->can_commit = APR_DBD_TRANSACTION_COMMIT;
    return APR_FROM_SQL_RESULT(rc);
};


/** end_transaction: end a transaction **/
static int odbc_end_transaction(apr_dbd_transaction_t *trans)
{
    SQLRETURN rc;
    int action = (trans->apr_dbd->can_commit != APR_DBD_TRANSACTION_ROLLBACK) 
        ? SQL_COMMIT : SQL_ROLLBACK;

    rc = SQLEndTran(SQL_HANDLE_DBC, trans->dbc, action);
    CHECK_ERROR(trans->apr_dbd, "SQLEndTran", rc, SQL_HANDLE_DBC, trans->dbc);
    if SQL_SUCCEEDED(rc) {
        rc = SQLSetConnectAttr(trans->dbc, SQL_ATTR_AUTOCOMMIT,
                               (SQLPOINTER) SQL_AUTOCOMMIT_ON, 0);
        CHECK_ERROR(trans->apr_dbd, "SQLSetConnectAttr (SQL_ATTR_AUTOCOMMIT)",
                    rc, SQL_HANDLE_DBC, trans->dbc);
    }
    trans->apr_dbd->can_commit = APR_DBD_TRANSACTION_IGNORE_ERRORS;
    return APR_FROM_SQL_RESULT(rc);
}

/** query: execute an SQL statement which doesn't return a result set **/
static int odbc_query(apr_dbd_t *handle, int *nrows, const char *statement)
{
    SQLRETURN rc;
    SQLHANDLE hstmt = NULL;
    size_t len = strlen(statement);

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    rc = SQLAllocHandle(SQL_HANDLE_STMT, handle->dbc, &hstmt);
    CHECK_ERROR(handle, "SQLAllocHandle (STMT)", rc, SQL_HANDLE_DBC,
                handle->dbc);
    if (!SQL_SUCCEEDED(rc))
        return APR_FROM_SQL_RESULT(rc);

    rc = SQLExecDirect(hstmt, (SQLCHAR *) statement, (SQLINTEGER) len);
    CHECK_ERROR(handle, "SQLExecDirect", rc, SQL_HANDLE_STMT, hstmt);

    if SQL_SUCCEEDED(rc) {
        rc = SQLRowCount(hstmt,  (SQLINTEGER *) nrows);
        CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT, hstmt);
    }

    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    return APR_FROM_SQL_RESULT(rc);
}

/** select: execute an SQL statement which returns a result set **/
static int odbc_select(apr_pool_t *pool, apr_dbd_t *handle,
                       apr_dbd_results_t **res, const char *statement,
                       int random)
{
    SQLRETURN rc;
    SQLHANDLE hstmt;
    apr_dbd_prepared_t *stmt;
    size_t len = strlen(statement);

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    rc = SQLAllocHandle(SQL_HANDLE_STMT, handle->dbc, &hstmt);
    CHECK_ERROR(handle, "SQLAllocHandle (STMT)", rc, SQL_HANDLE_DBC,
                handle->dbc);
    if (!SQL_SUCCEEDED(rc))
        return APR_FROM_SQL_RESULT(rc);
    /* Prepare an apr_dbd_prepared_t for pool cleanup, even though this
    *  is not a prepared statement.  We want the same cleanup mechanism.
    */
    stmt = apr_pcalloc(pool, sizeof(apr_dbd_prepared_t));
    stmt->apr_dbd = handle;
    stmt->dbc = handle->dbc;
    stmt->stmt = hstmt;
    apr_pool_cleanup_register(pool, stmt, odbc_close_pstmt, apr_pool_cleanup_null);
    if (random) {
        rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_SCROLLABLE,
                            (SQLPOINTER) SQL_SCROLLABLE, 0);
        CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)", rc,
                    SQL_HANDLE_STMT, hstmt);
    }
    if SQL_SUCCEEDED(rc) {
        rc = SQLExecDirect(hstmt, (SQLCHAR *) statement, (SQLINTEGER) len);
        CHECK_ERROR(handle, "SQLExecDirect", rc, SQL_HANDLE_STMT, hstmt);
    }
    if SQL_SUCCEEDED(rc) {
        rc = odbc_create_results(handle, hstmt, pool, random, res);
        apr_pool_cleanup_register(pool, *res, 
                                  odbc_close_results, apr_pool_cleanup_null);
    }
    return APR_FROM_SQL_RESULT(rc);
}

/** num_cols: get the number of columns in a results set **/
static int odbc_num_cols(apr_dbd_results_t *res)
{
    return res->ncols;
}

/** num_tuples: get the number of rows in a results set **/
static int odbc_num_tuples(apr_dbd_results_t *res)
{
    SQLRETURN rc;
    SQLINTEGER  nrows;

    rc = SQLRowCount(res->stmt, &nrows);
    CHECK_ERROR(res->apr_dbd, "SQLRowCount", rc, SQL_HANDLE_STMT, res->stmt);
    return SQL_SUCCEEDED(rc) ? (int) nrows : -1;
}

/** get_row: get a row from a result set **/
static int odbc_get_row(apr_pool_t * pool, apr_dbd_results_t * res,
                        apr_dbd_row_t ** row, int rownum)
{
    SQLRETURN rc;
    char *fetchtype;
    int c;

    *row = apr_pcalloc(pool, sizeof(apr_dbd_row_t));
    (*row)->stmt = res->stmt;
    (*row)->dbc = res->dbc;
    (*row)->res = res;
    (*row)->pool = res->pool;

    /* mark all the columns as needing SQLGetData unless they are bound  */
    for (c = 0; c < res->ncols; c++) {
        if (res->colstate[c] != COL_BOUND)
            res->colstate[c] = COL_AVAIL;
            /* some drivers do not null-term zero-len CHAR data */
            if (res->colptrs[c] )
                * (char *) res->colptrs[c] = 0; 
    }

    if (res->random && (rownum > 0)) {
        fetchtype = "SQLFetchScroll";
        rc = SQLFetchScroll(res->stmt, SQL_FETCH_ABSOLUTE, rownum);
    }
    else {
        fetchtype = "SQLFetch";
        rc = SQLFetch(res->stmt);
    }
    CHECK_ERROR(res->apr_dbd, fetchtype, rc, SQL_HANDLE_STMT, res->stmt);
    (*row)->stmt = res->stmt;
    if (!SQL_SUCCEEDED(rc) && !res->random) {
        /* early close on any error (usually SQL_NO_DATA) if fetching
         * sequentially to release resources ASAP */
        odbc_close_results(res);
        return -1;
    }
    return SQL_SUCCEEDED(rc) ? 0 : -1;
}

/** datum_get: get a binary entry from a row **/
static apr_status_t odbc_datum_get(const apr_dbd_row_t * row, int col,
                                   apr_dbd_type_e dbdtype, void *data)
{
    SQLSMALLINT sqltype;
    void *p;
    int len = sqlSizes[dbdtype];

    if (col >= row->res->ncols)
        return APR_EGENERAL;

    if (dbdtype < 0 || dbdtype >= sizeof(sqlCtype)) {
        data = NULL;            /* invalid type */
        return APR_EGENERAL;
    }
    sqltype = sqlCtype[dbdtype];

    /* must not memcpy a brigade, sentinals are relative to orig loc */
    if (IS_LOB(sqltype)) 
        return odbc_create_bucket(row, col, sqltype, data);

    p = odbc_get(row, col, sqltype);
    if (p == (void *) -1)
        return APR_EGENERAL;

    if (p == NULL)
        return APR_ENOENT;          /* SQL NULL value */
    
    if (len < 0)
        strcpy(data, p);
    else
        memcpy(data, p, len);
    
    return APR_SUCCESS;

}

/** get_entry: get an entry from a row (string data) **/
static const char *odbc_get_entry(const apr_dbd_row_t * row, int col)
{
    void *p;

    if (col >= row->res->ncols)
        return NULL;

    p = odbc_get(row, col, SQL_C_CHAR);

    /* NULL or invalid (-1) */
    if (p == NULL || p == (void *) -1)
        return p;     
    else
        return apr_pstrdup(row->pool, p);   
}

/** error: get current error message (if any) **/
static const char* odbc_error(apr_dbd_t *handle, int errnum)
{   
    return (handle) ? handle->lastError : "[dbd_odbc]No error message available";
}

/** escape: escape a string so it is safe for use in query/select **/
static const char* odbc_escape(apr_pool_t *pool, const char *s,
                        apr_dbd_t *handle)
{   
    char *newstr, *src, *dst, *sq;
    int qcount;

    /* return the original if there are no single-quotes */
    if (!(sq = strchr(s, '\''))) 
        return (char *) s;
    /* count the single-quotes and allocate a new buffer */
    for (qcount = 1; (sq = strchr(sq + 1, '\'')); )
        qcount++;
    newstr = apr_palloc(pool, strlen(s) + qcount + 1);

    /* move chars, doubling all single-quotes */
    src = (char *) s;
    for (dst = newstr ; *src ; src++) {
        if ((*dst++ = *src) == '\'')  
            *dst++ = '\'';
    }
    *dst = 0;
    return newstr;
}
/** prepare: prepare a statement **/
static int odbc_prepare(apr_pool_t * pool, apr_dbd_t * handle,
                        const char *query, const char *label, int nargs,
                        int nvals, apr_dbd_type_e * types,
                        apr_dbd_prepared_t ** statement)
{
    SQLRETURN rc;
    size_t len = strlen(query);

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    *statement = apr_pcalloc(pool, sizeof(apr_dbd_prepared_t));
    (*statement)->dbc = handle->dbc;
    (*statement)->apr_dbd = handle;
    (*statement)->nargs = nargs;
    (*statement)->nvals = nvals;
    (*statement)->types =
        apr_pmemdup(pool, types, nargs * sizeof(apr_dbd_type_e));
    rc = SQLAllocHandle(SQL_HANDLE_STMT, handle->dbc, &((*statement)->stmt));
    apr_pool_cleanup_register(pool, *statement, 
                              odbc_close_pstmt, apr_pool_cleanup_null);
    CHECK_ERROR(handle, "SQLAllocHandle (STMT)", rc,
                SQL_HANDLE_DBC, handle->dbc);
    rc = SQLPrepare((*statement)->stmt, (SQLCHAR *) query, (SQLINTEGER) len);
    CHECK_ERROR(handle, "SQLPrepare", rc, SQL_HANDLE_STMT,
                (*statement)->stmt);
    return APR_FROM_SQL_RESULT(rc);
}

/** pquery: query using a prepared statement + args **/
static int odbc_pquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
                       apr_dbd_prepared_t * statement, const char **args)
{
    SQLRETURN rc = SQL_SUCCESS;
    int i, argp;

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++) {
        rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
                             &argp, (const void **) args, TEXTMODE);
    }
    if (SQL_SUCCEEDED(rc)) {
        rc = SQLExecute(statement->stmt);
        CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = SQLRowCount(statement->stmt, (SQLINTEGER *) nrows);
        CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    return APR_FROM_SQL_RESULT(rc);
}

/** pvquery: query using a prepared statement + args **/
static int odbc_pvquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
                        apr_dbd_prepared_t * statement, va_list args)
{
    const char **values;
    int i;
    values = apr_palloc(pool, sizeof(*values) * statement->nvals);
    for (i = 0; i < statement->nvals; i++)
        values[i] = va_arg(args, const char *);
    return odbc_pquery(pool, handle, nrows, statement, values);
}

/** pselect: select using a prepared statement + args **/
int odbc_pselect(apr_pool_t * pool, apr_dbd_t * handle,
                 apr_dbd_results_t ** res, apr_dbd_prepared_t * statement,
                 int random, const char **args)
{
    SQLRETURN rc = SQL_SUCCESS;
    int i, argp;

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    if (random) {
        rc = SQLSetStmtAttr(statement->stmt, SQL_ATTR_CURSOR_SCROLLABLE,
                            (SQLPOINTER) SQL_SCROLLABLE, 0);
        CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)",
                    rc, SQL_HANDLE_STMT, statement->stmt);
    }
    if (SQL_SUCCEEDED(rc)) {
        for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++)
            rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
                                 &argp, (const void **) args, TEXTMODE);
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = SQLExecute(statement->stmt);
        CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = odbc_create_results(handle, statement->stmt, pool, random, res);
        apr_pool_cleanup_register(pool, *res,
                                  odbc_close_results, apr_pool_cleanup_null);
        }
    return APR_FROM_SQL_RESULT(rc);
}

/** pvselect: select using a prepared statement + args **/
static int odbc_pvselect(apr_pool_t * pool, apr_dbd_t * handle,
                         apr_dbd_results_t ** res,
                         apr_dbd_prepared_t * statement, int random,
                         va_list args)
{
    const char **values;
    int i;

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);
    for (i = 0; i < statement->nvals; i++)
        values[i] = va_arg(args, const char *);
    return odbc_pselect(pool, handle, res, statement, random, values);
}

/** get_name: get a column title from a result set **/
static const char *odbc_get_name(const apr_dbd_results_t * res, int col)
{
    SQLRETURN rc;
    char buffer[MAX_COLUMN_NAME];
    SQLSMALLINT colnamelength, coltype, coldecimal, colnullable;
    SQLUINTEGER colsize;

    if (col >= res->ncols)
        return NULL;            /* bogus column number */
    if (res->colnames[col] != NULL)
        return res->colnames[col];      /* we already retrieved it */
    rc = SQLDescribeCol(res->stmt, col + 1,
                        (SQLCHAR *)buffer, sizeof(buffer), &colnamelength,
                        &coltype, &colsize, &coldecimal, &colnullable);
    CHECK_ERROR(res->apr_dbd, "SQLDescribeCol", rc,
                SQL_HANDLE_STMT, res->stmt);
    res->colnames[col] = apr_pstrdup(res->pool, buffer);
    return res->colnames[col];
}

/** transaction_mode_get: get the mode of transaction **/
static int odbc_transaction_mode_get(apr_dbd_transaction_t * trans)
{
    return (int) trans->apr_dbd->can_commit;
}

/** transaction_mode_set: set the mode of transaction **/
static int odbc_transaction_mode_set(apr_dbd_transaction_t * trans, int mode)
{
    int legal = (  APR_DBD_TRANSACTION_IGNORE_ERRORS
                 | APR_DBD_TRANSACTION_COMMIT
                 | APR_DBD_TRANSACTION_ROLLBACK);

    if ((mode & legal) != mode)
        return APR_EGENERAL;

    trans->apr_dbd->can_commit = mode;
    return APR_SUCCESS;
}

/** pbquery: query using a prepared statement + binary args **/
static int odbc_pbquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
                        apr_dbd_prepared_t * statement, const void **args)
{
    SQLRETURN rc = SQL_SUCCESS;
    int i, argp;

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++)
        rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
                             &argp, args, BINARYMODE);

    if (SQL_SUCCEEDED(rc)) {
        rc = SQLExecute(statement->stmt);
        CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = SQLRowCount(statement->stmt, (SQLINTEGER *) nrows);
        CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    return APR_FROM_SQL_RESULT(rc);
}

/** pbselect: select using a prepared statement + binary args **/
static int odbc_pbselect(apr_pool_t * pool, apr_dbd_t * handle,
                         apr_dbd_results_t ** res,
                         apr_dbd_prepared_t * statement,
                         int random, const void **args)
{
    SQLRETURN rc = SQL_SUCCESS;
    int i, argp;

    if (odbc_check_rollback(handle))
        return APR_EGENERAL;

    if (random) {
        rc = SQLSetStmtAttr(statement->stmt, SQL_ATTR_CURSOR_SCROLLABLE,
                            (SQLPOINTER) SQL_SCROLLABLE, 0);
        CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)",
                    rc, SQL_HANDLE_STMT, statement->stmt);
    }
    if (SQL_SUCCEEDED(rc)) {
        for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++) {
            rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
                                 &argp, args, BINARYMODE);
        }
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = SQLExecute(statement->stmt);
        CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                    statement->stmt);
        }
    if (SQL_SUCCEEDED(rc)) {
        rc = odbc_create_results(handle, statement->stmt, pool, random, res);
        apr_pool_cleanup_register(pool, *res,
                                  odbc_close_results, apr_pool_cleanup_null);
        }

    return APR_FROM_SQL_RESULT(rc);
}

/** pvbquery: query using a prepared statement + binary args **/
static int odbc_pvbquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
                         apr_dbd_prepared_t * statement, va_list args)
{
    const char **values;
    int i;

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);
    for (i = 0; i < statement->nvals; i++)
        values[i] = va_arg(args, const char *);
    return odbc_pbquery(pool, handle, nrows, statement, (const void **) values);
}

/** pvbselect: select using a prepared statement + binary args **/
static int odbc_pvbselect(apr_pool_t * pool, apr_dbd_t * handle,
                          apr_dbd_results_t ** res,
                          apr_dbd_prepared_t * statement,
                          int random, va_list args)
{
    const char **values;
    int i;

    values = apr_palloc(pool, sizeof(*values) * statement->nvals);
    for (i = 0; i < statement->nvals; i++)
        values[i] = va_arg(args, const char *);
    return odbc_pbselect(pool, handle, res, statement, random, (const void **) values);
}

APU_MODULE_DECLARE_DATA const apr_dbd_driver_t    ODBC_DRIVER_ENTRY = {
    ODBC_DRIVER_STRING,
    odbc_init,
    odbc_native_handle,
    odbc_open,
    odbc_check_conn,
    odbc_close,
    odbc_set_dbname,
    odbc_start_transaction,
    odbc_end_transaction,
    odbc_query,
    odbc_select,
    odbc_num_cols,
    odbc_num_tuples,
    odbc_get_row,
    odbc_get_entry,
    odbc_error,
    odbc_escape,
    odbc_prepare,
    odbc_pvquery,
    odbc_pvselect,
    odbc_pquery,
    odbc_pselect,
    odbc_get_name,
    odbc_transaction_mode_get,
    odbc_transaction_mode_set,
    "?",
    odbc_pvbquery,
    odbc_pvbselect,
    odbc_pbquery,
    odbc_pbselect,
    odbc_datum_get
};

#endif
