/* 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"
#include "apr_private.h"

#if APU_HAVE_SQLITE3

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

#include <sqlite3.h>

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

#include "apr_dbd_internal.h"

#define MAX_RETRY_COUNT 15
#define MAX_RETRY_SLEEP 100000

struct apr_dbd_transaction_t {
    int mode;
    int errnum;
    apr_dbd_t *handle;
};

struct apr_dbd_t {
    sqlite3 *conn;
    apr_dbd_transaction_t *trans;
    apr_pool_t *pool;
    apr_dbd_prepared_t *prep;
};

typedef struct {
    char *name;
    char *value;
    int size;
    int type;
} apr_dbd_column_t;

struct apr_dbd_row_t {
    apr_dbd_results_t *res;
    apr_dbd_column_t **columns;
    apr_dbd_row_t *next_row;
    int columnCount;
    int rownum;
};

struct apr_dbd_results_t {
    int random;
    sqlite3 *handle;
    sqlite3_stmt *stmt;
    apr_dbd_row_t *next_row;
    size_t sz;
    int tuples;
    char **col_names;
    apr_pool_t *pool;
};

struct apr_dbd_prepared_t {
    sqlite3_stmt *stmt;
    apr_dbd_prepared_t *next;
    int nargs;
    int nvals;
    apr_dbd_type_e *types;
};

#define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE) || ((x) == SQLITE_OK))

static int dbd_sqlite3_select_internal(apr_pool_t *pool,
                                       apr_dbd_t *sql,
                                       apr_dbd_results_t **results,
                                       sqlite3_stmt *stmt, int seek)
{
    int ret, retry_count = 0, column_count;
    size_t i, num_tuples = 0;
    int increment = 0;
    apr_dbd_row_t *row = NULL;
    apr_dbd_row_t *lastrow = NULL;
    apr_dbd_column_t *column;
    char *hold = NULL;

    column_count = sqlite3_column_count(stmt);
    if (!*results) {
        *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
    }
    (*results)->stmt = stmt;
    (*results)->sz = column_count;
    (*results)->random = seek;
    (*results)->next_row = 0;
    (*results)->tuples = 0;
    (*results)->col_names = apr_pcalloc(pool, column_count * sizeof(char *));
    (*results)->pool = pool;
    do {
        ret = sqlite3_step(stmt);
        if (ret == SQLITE_BUSY) {
            if (retry_count++ > MAX_RETRY_COUNT) {
                ret = SQLITE_ERROR;
            } else {
                apr_dbd_mutex_unlock();
                apr_sleep(MAX_RETRY_SLEEP);
                apr_dbd_mutex_lock();
            }
        } else if (ret == SQLITE_ROW) {
            int length;
            row = apr_palloc(pool, sizeof(apr_dbd_row_t));
            row->res = *results;
            increment = sizeof(apr_dbd_column_t *);
            length = increment * (*results)->sz;
            row->columns = apr_palloc(pool, length);
            row->columnCount = column_count;
            for (i = 0; i < (*results)->sz; i++) {
                column = apr_palloc(pool, sizeof(apr_dbd_column_t));
                row->columns[i] = column;
                /* copy column name once only */
                if ((*results)->col_names[i] == NULL) {
                    (*results)->col_names[i] =
                        apr_pstrdup(pool, sqlite3_column_name(stmt, i));
                }
                column->name = (*results)->col_names[i];
                column->size = sqlite3_column_bytes(stmt, i);
                column->type = sqlite3_column_type(stmt, i);
                column->value = NULL;
                switch (column->type) {
                case SQLITE_FLOAT:
                case SQLITE_INTEGER:
                case SQLITE_TEXT:
                    hold = (char *) sqlite3_column_text(stmt, i);
                    if (hold) {
                        column->value = apr_pstrmemdup(pool, hold,
                                                       column->size);
                    }
                    break;
                case SQLITE_BLOB:
                    hold = (char *) sqlite3_column_blob(stmt, i);
                    if (hold) {
                        column->value = apr_pstrmemdup(pool, hold,
                                                       column->size);
                    }
                    break;
                case SQLITE_NULL:
                    break;
                }
            }
            row->rownum = num_tuples++;
            row->next_row = 0;
            (*results)->tuples = num_tuples;
            if ((*results)->next_row == 0) {
                (*results)->next_row = row;
            }
            if (lastrow != 0) {
                lastrow->next_row = row;
            }
            lastrow = row;
        }
    } while (ret == SQLITE_ROW || ret == SQLITE_BUSY);

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
    return ret;
}

static int dbd_sqlite3_select(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **results, const char *query,
                              int seek)
{
    sqlite3_stmt *stmt = NULL;
    const char *tail = NULL;
    int ret;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
    if (dbd_sqlite3_is_success(ret)) {
        ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);
    }
    sqlite3_finalize(stmt);

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

static const char *dbd_sqlite3_get_name(const apr_dbd_results_t *res, int n)
{
    if ((n < 0) || ((size_t)n >= res->sz)) {
        return NULL;
    }

    return res->col_names[n];
}

static int dbd_sqlite3_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
                               apr_dbd_row_t **rowp, int rownum)
{
    int i = 0;

    if (rownum == -1) {
        *rowp = res->next_row;
        if (*rowp == 0)
            return -1;
        res->next_row = (*rowp)->next_row;
        return 0;
    }
    if (rownum > res->tuples) {
        return -1;
    }
    rownum--;
    *rowp = res->next_row;
    for (; *rowp != 0; i++, *rowp = (*rowp)->next_row) {
        if (i == rownum) {
            return 0;
        }
    }

    return -1;

}

static const char *dbd_sqlite3_get_entry(const apr_dbd_row_t *row, int n)
{
    apr_dbd_column_t *column;
    const char *value;
    if ((n < 0) || (n >= row->columnCount)) {
        return NULL;
    }
    column = row->columns[n];
    value = column->value;
    return value;
}

static apr_status_t dbd_sqlite3_datum_get(const apr_dbd_row_t *row, int n,
                                          apr_dbd_type_e type, void *data)
{
    if ((n < 0) || ((size_t)n >= row->res->sz)) {
      return APR_EGENERAL;
    }

    if (row->columns[n]->type == SQLITE_NULL) {
        return APR_ENOENT;
    }

    switch (type) {
    case APR_DBD_TYPE_TINY:
        *(char*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_UTINY:
        *(unsigned char*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_SHORT:
        *(short*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_USHORT:
        *(unsigned short*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_INT:
        *(int*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_UINT:
        *(unsigned int*)data = atoi(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_LONG:
        *(long*)data = atol(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_ULONG:
        *(unsigned long*)data = atol(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_LONGLONG:
        *(apr_int64_t*)data = apr_atoi64(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_ULONGLONG:
        *(apr_uint64_t*)data = apr_atoi64(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_FLOAT:
        *(float*)data = (float)atof(row->columns[n]->value);
        break;
    case APR_DBD_TYPE_DOUBLE:
        *(double*)data = atof(row->columns[n]->value);
        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:
        *(char**)data = row->columns[n]->value;
        break;
    case APR_DBD_TYPE_BLOB:
    case APR_DBD_TYPE_CLOB:
        {
        apr_bucket *e;
        apr_bucket_brigade *b = (apr_bucket_brigade*)data;

        e = apr_bucket_pool_create(row->columns[n]->value,
                                   row->columns[n]->size,
                                   row->res->pool, b->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(b, e);
        }
        break;
    case APR_DBD_TYPE_NULL:
        *(void**)data = NULL;
        break;
    default:
        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n)
{
    return sqlite3_errmsg(sql->conn);
}

static int dbd_sqlite3_query_internal(apr_dbd_t *sql, sqlite3_stmt *stmt,
                                      int *nrows)
{
    int ret = -1, retry_count = 0;

    while(retry_count++ <= MAX_RETRY_COUNT) {
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_BUSY)
            break;

        apr_dbd_mutex_unlock();
        apr_sleep(MAX_RETRY_SLEEP);
        apr_dbd_mutex_lock();
    }

    *nrows = sqlite3_changes(sql->conn);

    if (dbd_sqlite3_is_success(ret)) {
        ret = 0;
    }
    return ret;
}

static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query)
{
    sqlite3_stmt *stmt = NULL;
    const char *tail = NULL;
    int ret = -1, length = 0;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    length = strlen(query);
    apr_dbd_mutex_lock();

    do {
        ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail);
        if (ret != SQLITE_OK) {
            sqlite3_finalize(stmt);
            break;
        }

        ret = dbd_sqlite3_query_internal(sql, stmt, nrows);

        sqlite3_finalize(stmt);
        length -= (tail - query);
        query = tail;
    } while (length > 0);

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

static apr_status_t free_mem(void *data)
{
    sqlite3_free(data);
    return APR_SUCCESS;
}

static const char *dbd_sqlite3_escape(apr_pool_t *pool, const char *arg,
                                      apr_dbd_t *sql)
{
    char *ret = sqlite3_mprintf("%q", arg);
    apr_pool_cleanup_register(pool, ret, free_mem,
                              apr_pool_cleanup_null);
    return ret;
}

static int dbd_sqlite3_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)
{
    sqlite3_stmt *stmt;
    const char *tail = NULL;
    int ret;

    apr_dbd_mutex_lock();

    ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail);
    if (ret == SQLITE_OK) {
        apr_dbd_prepared_t *prep; 

        prep = apr_pcalloc(sql->pool, sizeof(*prep));
        prep->stmt = stmt;
        prep->next = sql->prep;
        prep->nargs = nargs;
        prep->nvals = nvals;
        prep->types = types;

        /* link new statement to the handle */
        sql->prep = prep;

        *statement = prep;
    } else {
        sqlite3_finalize(stmt);
    }
   
    apr_dbd_mutex_unlock();

    return ret;
}

static void dbd_sqlite3_bind(apr_dbd_prepared_t *statement, const char **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int i, j;

    for (i = 0, j = 0; i < statement->nargs; i++, j++) {
        if (values[j] == NULL) {
            sqlite3_bind_null(stmt, i + 1);
        }
        else {
            switch (statement->types[i]) {
            case APR_DBD_TYPE_BLOB:
            case APR_DBD_TYPE_CLOB:
                {
                char *data = (char *)values[j];
                int size = atoi((char*)values[++j]);

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

                sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC);
                }
                break;
            default:
                sqlite3_bind_text(stmt, i + 1, values[j],
                                  strlen(values[j]), SQLITE_STATIC);
                break;
            }
        }
    }

    return;
}

static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql,
                              int *nrows, apr_dbd_prepared_t *statement,
                              const char **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int ret = -1;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_reset(stmt);
    if (ret == SQLITE_OK) {
        dbd_sqlite3_bind(statement, values);

        ret = dbd_sqlite3_query_internal(sql, stmt, nrows);

        sqlite3_reset(stmt);
    }

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

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

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

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

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

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

static int dbd_sqlite3_pselect(apr_pool_t *pool, apr_dbd_t *sql,
                               apr_dbd_results_t **results,
                               apr_dbd_prepared_t *statement, int seek,
                               const char **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int ret;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_reset(stmt);
    if (ret == SQLITE_OK) {
        dbd_sqlite3_bind(statement, values);

        ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);

        sqlite3_reset(stmt);
    }

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

static int dbd_sqlite3_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->errnum) {
        return sql->trans->errnum;
    }

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

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

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

static void dbd_sqlite3_bbind(apr_dbd_prepared_t * statement,
                              const void **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int i, j;
    apr_dbd_type_e type;

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

        switch (type) {
        case APR_DBD_TYPE_TINY:
            sqlite3_bind_int(stmt, i + 1, *(char*)values[j]);
            break;
        case APR_DBD_TYPE_UTINY:
            sqlite3_bind_int(stmt, i + 1, *(unsigned char*)values[j]);
            break;
        case APR_DBD_TYPE_SHORT:
            sqlite3_bind_int(stmt, i + 1, *(short*)values[j]);
            break;
        case APR_DBD_TYPE_USHORT:
            sqlite3_bind_int(stmt, i + 1, *(unsigned short*)values[j]);
            break;
        case APR_DBD_TYPE_INT:
            sqlite3_bind_int(stmt, i + 1, *(int*)values[j]);
            break;
        case APR_DBD_TYPE_UINT:
            sqlite3_bind_int(stmt, i + 1, *(unsigned int*)values[j]);
            break;
        case APR_DBD_TYPE_LONG:
            sqlite3_bind_int64(stmt, i + 1, *(long*)values[j]);
            break;
        case APR_DBD_TYPE_ULONG:
            sqlite3_bind_int64(stmt, i + 1, *(unsigned long*)values[j]);
            break;
        case APR_DBD_TYPE_LONGLONG:
            sqlite3_bind_int64(stmt, i + 1, *(apr_int64_t*)values[j]);
            break;
        case APR_DBD_TYPE_ULONGLONG:
            sqlite3_bind_int64(stmt, i + 1, *(apr_uint64_t*)values[j]);
            break;
        case APR_DBD_TYPE_FLOAT:
            sqlite3_bind_double(stmt, i + 1, *(float*)values[j]);
            break;
        case APR_DBD_TYPE_DOUBLE:
            sqlite3_bind_double(stmt, i + 1, *(double*)values[j]);
            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:
            sqlite3_bind_text(stmt, i + 1, values[j], strlen(values[j]),
                              SQLITE_STATIC);
            break;
        case APR_DBD_TYPE_BLOB:
        case APR_DBD_TYPE_CLOB:
            {
            char *data = (char*)values[j];
            apr_size_t size = *(apr_size_t*)values[++j];

            sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC);

            /* skip table and column */
            j += 2;
            }
            break;
        case APR_DBD_TYPE_NULL:
        default:
            sqlite3_bind_null(stmt, i + 1);
            break;
        }
    }

    return;
}

static int dbd_sqlite3_pbquery(apr_pool_t * pool, apr_dbd_t * sql,
                               int *nrows, apr_dbd_prepared_t * statement,
                               const void **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int ret = -1;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_reset(stmt);
    if (ret == SQLITE_OK) {
        dbd_sqlite3_bbind(statement, values);

        ret = dbd_sqlite3_query_internal(sql, stmt, nrows);

        sqlite3_reset(stmt);
    }

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

static int dbd_sqlite3_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->errnum) {
        return sql->trans->errnum;
    }

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

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

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

static int dbd_sqlite3_pbselect(apr_pool_t * pool, apr_dbd_t * sql,
                                apr_dbd_results_t ** results,
                                apr_dbd_prepared_t * statement,
                                int seek, const void **values)
{
    sqlite3_stmt *stmt = statement->stmt;
    int ret;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    apr_dbd_mutex_lock();

    ret = sqlite3_reset(stmt);
    if (ret == SQLITE_OK) {
        dbd_sqlite3_bbind(statement, values);

        ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek);

        sqlite3_reset(stmt);
    }

    apr_dbd_mutex_unlock();

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }
    return ret;
}

static int dbd_sqlite3_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->errnum) {
        return sql->trans->errnum;
    }

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

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

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

static int dbd_sqlite3_start_transaction(apr_pool_t *pool,
                                         apr_dbd_t *handle,
                                         apr_dbd_transaction_t **trans)
{
    int ret = 0;
    int nrows = 0;

    ret = dbd_sqlite3_query(handle, &nrows, "BEGIN IMMEDIATE");
    if (!*trans) {
        *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
        (*trans)->handle = handle;
        handle->trans = *trans;
    }

    return ret;
}

static int dbd_sqlite3_end_transaction(apr_dbd_transaction_t *trans)
{
    int ret = -1; /* ending transaction that was never started is an error */
    int nrows = 0;

    if (trans) {
        /* rollback on error or explicit rollback request */
        if (trans->errnum || TXN_DO_ROLLBACK(trans)) {
            trans->errnum = 0;
            ret = dbd_sqlite3_query(trans->handle, &nrows, "ROLLBACK");
        } else {
            ret = dbd_sqlite3_query(trans->handle, &nrows, "COMMIT");
        }
        trans->handle->trans = NULL;
    }

    return ret;
}

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

    return trans->mode;
}

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

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

static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *pool, const char *params,
                                   const char **error)
{
    apr_dbd_t *sql = NULL;
    sqlite3 *conn = NULL;
    int sqlres;
    if (!params)
        return NULL;
    sqlres = sqlite3_open(params, &conn);
    if (sqlres != SQLITE_OK) {
        if (error) {
            *error = apr_pstrdup(pool, sqlite3_errmsg(conn));
        }
        sqlite3_close(conn);
        return NULL;
    }
    /* should we register rand or power functions to the sqlite VM? */
    sql = apr_pcalloc(pool, sizeof(*sql));
    sql->conn = conn;
    sql->pool = pool;
    sql->trans = NULL;

    return sql;
}

static apr_status_t dbd_sqlite3_close(apr_dbd_t *handle)
{
    apr_dbd_prepared_t *prep = handle->prep;

    /* finalize all prepared statements, or we'll get SQLITE_BUSY on close */
    while (prep) {
        sqlite3_finalize(prep->stmt);
        prep = prep->next;
    }

    sqlite3_close(handle->conn);
    return APR_SUCCESS;
}

static apr_status_t dbd_sqlite3_check_conn(apr_pool_t *pool,
                                           apr_dbd_t *handle)
{
    return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL;
}

static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle,
                                 const char *name)
{
    return APR_ENOTIMPL;
}

static void *dbd_sqlite3_native(apr_dbd_t *handle)
{
    return handle->conn;
}

static int dbd_sqlite3_num_cols(apr_dbd_results_t *res)
{
    return res->sz;
}

static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res)
{
    return res->tuples;
}

APR_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite3_driver = {
    "sqlite3",
    NULL,
    dbd_sqlite3_native,
    dbd_sqlite3_open,
    dbd_sqlite3_check_conn,
    dbd_sqlite3_close,
    dbd_sqlite3_select_db,
    dbd_sqlite3_start_transaction,
    dbd_sqlite3_end_transaction,
    dbd_sqlite3_query,
    dbd_sqlite3_select,
    dbd_sqlite3_num_cols,
    dbd_sqlite3_num_tuples,
    dbd_sqlite3_get_row,
    dbd_sqlite3_get_entry,
    dbd_sqlite3_error,
    dbd_sqlite3_escape,
    dbd_sqlite3_prepare,
    dbd_sqlite3_pvquery,
    dbd_sqlite3_pvselect,
    dbd_sqlite3_pquery,
    dbd_sqlite3_pselect,
    dbd_sqlite3_get_name,
    dbd_sqlite3_transaction_mode_get,
    dbd_sqlite3_transaction_mode_set,
    "?",
    dbd_sqlite3_pvbquery,
    dbd_sqlite3_pvbselect,
    dbd_sqlite3_pbquery,
    dbd_sqlite3_pbselect,
    dbd_sqlite3_datum_get
};
#endif
