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

APLOG_USE_MODULE(lua);
static APR_OPTIONAL_FN_TYPE(ap_dbd_close) *lua_ap_dbd_close = NULL;
static APR_OPTIONAL_FN_TYPE(ap_dbd_open) *lua_ap_dbd_open = NULL;




static request_rec *ap_lua_check_request_rec(lua_State *L, int index)
{
    request_rec *r;
    luaL_checkudata(L, index, "Apache2.Request");
    r = lua_unboxpointer(L, index);
    return r;
}

static lua_db_handle *lua_get_db_handle(lua_State *L)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_rawgeti(L, 1, 0);
    luaL_checktype(L, -1, LUA_TUSERDATA);
    return (lua_db_handle *) lua_topointer(L, -1);
}

static lua_db_result_set *lua_get_result_set(lua_State *L)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_rawgeti(L, 1, 0);
    luaL_checktype(L, -1, LUA_TUSERDATA);
    return (lua_db_result_set *) lua_topointer(L, -1);
}


/*
   =============================================================================
    db:close(): Closes an open database connection.
   =============================================================================
 */
int lua_db_close(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db;
    apr_status_t     rc = 0;
    /*~~~~~~~~~~~~~~~~~~~~*/
    
    db = lua_get_db_handle(L);
    if (db && db->alive) {
        if (db->type == LUA_DBTYPE_APR_DBD) {
            rc = apr_dbd_close(db->driver, db->handle);
            if (db->pool) apr_pool_destroy(db->pool);
        }
        else {
            lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
            if (lua_ap_dbd_close != NULL)
                if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
        }

        db->driver = NULL;
        db->handle = NULL;
        db->alive = 0;
        db->pool = NULL;
    }

    lua_settop(L, 0);
    lua_pushnumber(L, rc);
    return 1;
} 

/*
   =============================================================================
     db:__gc(): Garbage collecting function.
   =============================================================================
 */
int lua_db_gc(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~*/
    lua_db_handle    *db;
    /*~~~~~~~~~~~~~~~~~~~~*/

    db = lua_touserdata(L, 1);
    if (db && db->alive) {
        if (db->type == LUA_DBTYPE_APR_DBD) {
            apr_dbd_close(db->driver, db->handle);
            if (db->pool) apr_pool_destroy(db->pool);
        }
        else {
            lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
            if (lua_ap_dbd_close != NULL)
                if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
        }
        db->driver = NULL;
        db->handle = NULL;
        db->alive = 0;
        db->pool = NULL;
    }
    lua_settop(L, 0);
    return 0;
}

/*
   =============================================================================
    db:active(): Returns true if the connection to the db is still active.
   =============================================================================
 */
int lua_db_active(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db = 0;
    apr_status_t     rc = 0;
    /*~~~~~~~~~~~~~~~~~~~~*/

    db = lua_get_db_handle(L);
    if (db && db->alive) {
        rc = apr_dbd_check_conn(db->driver, db->pool, db->handle);
        if (rc == APR_SUCCESS) {
            lua_pushboolean(L, 1);
            return 1;
        }
    }

    lua_pushboolean(L, 0);
    return 1;
}

/*
   =============================================================================
    db:query(statement): Executes the given database query and returns the 
    number of rows affected. If an error is encountered, returns nil as the 
    first parameter and the error message as the second.
   =============================================================================
 */
int lua_db_query(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db = 0;
    apr_status_t     rc = 0;
    int              x = 0;
    const char      *statement;
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    luaL_checktype(L, 3, LUA_TSTRING);
    statement = lua_tostring(L, 3);
    db = lua_get_db_handle(L);
    if (db && db->alive)
        rc = apr_dbd_query(db->driver, db->handle, &x, statement);
    else {
        rc = 0;
        x = -1;
    }

    if (rc == APR_SUCCESS)
        lua_pushnumber(L, x);
    else {

        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        const char  *err = apr_dbd_error(db->driver, db->handle, rc);
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

        lua_pushnil(L);
        if (err) {
            lua_pushstring(L, err);
            return 2;
        }
    }

    return 1;
}

/*
   =============================================================================
    db:escape(string): Escapes a string for safe use in the given database type.
   =============================================================================
 */
int lua_db_escape(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle    *db = 0;
    const char       *statement;
    const char       *escaped = 0;
    request_rec      *r;
    /*~~~~~~~~~~~~~~~~~~~~~*/

    r = ap_lua_check_request_rec(L, 2);
    if (r) {
        luaL_checktype(L, 3, LUA_TSTRING);
        statement = lua_tostring(L, 3);
        db = lua_get_db_handle(L);
        if (db && db->alive) {
            apr_dbd_init(r->pool);
            escaped = apr_dbd_escape(db->driver, r->pool, statement,
                                     db->handle);
            if (escaped) {
                lua_pushstring(L, escaped);
                return 1;
            }
        }
        else {
            lua_pushnil(L);
        }
        return (1);
    }

    return 0;
}

/*
   =============================================================================
     resultset(N): Fetches one or more rows from a result set.
   =============================================================================
 */
int lua_db_get_row(lua_State *L) 
{
    int row_no,x,alpha = 0;
    const char      *entry, *rowname;
    apr_dbd_row_t   *row = 0;
    lua_db_result_set *res = lua_get_result_set(L);
    
    row_no = luaL_optinteger(L, 2, 0);
    if (lua_isboolean(L, 3)) {
        alpha = lua_toboolean(L, 3);
    }
    lua_settop(L,0);
    
    /* Fetch all rows at once? */
    
    if (row_no == 0) {
        row_no = 1;
        lua_newtable(L);
        while (apr_dbd_get_row(res->driver, res->pool, res->results,
                            &row, -1) != -1)
         {
            lua_pushinteger(L, row_no);
            lua_newtable(L);
            for (x = 0; x < res->cols; x++) {
                entry = apr_dbd_get_entry(res->driver, row, x);
                if (entry) {
                    if (alpha == 1) {
                        rowname = apr_dbd_get_name(res->driver, 
                                res->results, x);
                        lua_pushstring(L, rowname ? rowname : "(oob)");
                    }
                    else {
                        lua_pushinteger(L, x + 1);
                    }
                    lua_pushstring(L, entry);
                    lua_rawset(L, -3);
                }
            }
            lua_rawset(L, -3);
            row_no++;
        }
        return 1;
    }
    
    /* Just fetch a single row */
    if (apr_dbd_get_row(res->driver, res->pool, res->results,
                            &row, row_no) != -1)
         {
        
        lua_newtable(L);
        for (x = 0; x < res->cols; x++) {
            entry = apr_dbd_get_entry(res->driver, row, x);
            if (entry) {
                if (alpha == 1) {
                    rowname = apr_dbd_get_name(res->driver, 
                            res->results, x);
                    lua_pushstring(L, rowname ? rowname : "(oob)");
                }
                else {
                    lua_pushinteger(L, x + 1);
                }
                lua_pushstring(L, entry);
                lua_rawset(L, -3);
            }
        }
        return 1;
    }
    return 0;
}


/*
   =============================================================================
    db:select(statement): Queries the database for the given statement and 
    returns the rows/columns found as a table. If an error is encountered, 
    returns nil as the first parameter and the error message as the second.
   =============================================================================
 */
int lua_db_select(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db = 0;
    apr_status_t     rc = 0;
    const char      *statement;
    request_rec     *r;
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    r = ap_lua_check_request_rec(L, 2);
    if (r) {
        luaL_checktype(L, 3, LUA_TSTRING);
        statement = lua_tostring(L, 3);
        db = lua_get_db_handle(L);
        if (db && db->alive) {

            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            int cols;
            apr_dbd_results_t   *results = 0;
            lua_db_result_set* resultset = NULL;
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

            rc = apr_dbd_select(db->driver, db->pool, db->handle,
                                &results, statement, 0);
            if (rc == APR_SUCCESS) {
                
                cols = apr_dbd_num_cols(db->driver, results);
                
                if (cols > 0) {
                    lua_newtable(L);
                    resultset = lua_newuserdata(L, sizeof(lua_db_result_set));
                    resultset->cols = cols;
                    resultset->driver = db->driver;
                    resultset->pool = db->pool;
                    resultset->rows = apr_dbd_num_tuples(db->driver, results);
                    resultset->results = results;
                    luaL_newmetatable(L, "lua_apr.dbselect");
                    lua_pushliteral(L, "__call");
                    lua_pushcfunction(L, lua_db_get_row);
                    lua_rawset(L, -3);
                    lua_setmetatable(L, -3);
                    lua_rawseti(L, -2, 0);
                    return 1;
                }
                return 0;
            }
            else {

                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                const char  *err = apr_dbd_error(db->driver, db->handle, rc);
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

                lua_pushnil(L);
                if (err) {
                    lua_pushstring(L, err);
                    return 2;
                }
            }
        }

        lua_pushboolean(L, 0);
        return 1;
    }

    return 0;
}



/*
   =============================================================================
    statement:select(var1, var2, var3...): Injects variables into a prepared 
    statement and returns the number of rows matching the query.
   =============================================================================
 */
int lua_db_prepared_select(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_prepared_statement  *st = 0;
    apr_status_t     rc = 0;
    const char       **vars;
    int              x, have;
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    
    /* Fetch the prepared statement and the vars passed */
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_rawgeti(L, 1, 0);
    luaL_checktype(L, -1, LUA_TUSERDATA);
    st = (lua_db_prepared_statement*) lua_topointer(L, -1);
    
    /* Check if we got enough variables passed on to us.
     * This, of course, only works for prepared statements made through lua. */
    have = lua_gettop(L) - 2;
    if (st->variables != -1 && have < st->variables ) {
        lua_pushboolean(L, 0);
        lua_pushfstring(L, 
                "Error in executing prepared statement: Expected %d arguments, got %d.", 
                st->variables, have);
        return 2;
    }
    vars = apr_pcalloc(st->db->pool, have*sizeof(char *));
    for (x = 0; x < have; x++) {
        vars[x] = lua_tostring(L, x + 2);
    }

    /* Fire off the query */
    if (st->db && st->db->alive) {

        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        int cols;
        apr_dbd_results_t   *results = 0;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

        rc = apr_dbd_pselect(st->db->driver, st->db->pool, st->db->handle,
                                &results, st->statement, 0, have, vars);
        if (rc == APR_SUCCESS) {

            /*~~~~~~~~~~~~~~~~~~~~~*/
            lua_db_result_set *resultset;
            /*~~~~~~~~~~~~~~~~~~~~~*/

            cols = apr_dbd_num_cols(st->db->driver, results);
            lua_newtable(L);
            resultset = lua_newuserdata(L, sizeof(lua_db_result_set));
            resultset->cols = cols;
            resultset->driver = st->db->driver;
            resultset->pool = st->db->pool;
            resultset->rows = apr_dbd_num_tuples(st->db->driver, results);
            resultset->results = results;
            luaL_newmetatable(L, "lua_apr.dbselect");
            lua_pushliteral(L, "__call");
            lua_pushcfunction(L, lua_db_get_row);
            lua_rawset(L, -3);
            lua_setmetatable(L, -3);
            lua_rawseti(L, -2, 0);
            return 1;
            
        }
        else {

            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            const char  *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

            lua_pushnil(L);
            if (err) {
                lua_pushstring(L, err);
                return 2;
            }
            return 1;
        }
    }

    lua_pushboolean(L, 0);
    lua_pushliteral(L, 
            "Database connection seems to be closed, please reacquire it.");
    return (2);
}


/*
   =============================================================================
    statement:query(var1, var2, var3...): Injects variables into a prepared 
    statement and returns the number of rows affected.
   =============================================================================
 */
int lua_db_prepared_query(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_prepared_statement  *st = 0;
    apr_status_t     rc = 0;
    const char       **vars;
    int              x, have;
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    
    /* Fetch the prepared statement and the vars passed */
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_rawgeti(L, 1, 0);
    luaL_checktype(L, -1, LUA_TUSERDATA);
    st = (lua_db_prepared_statement*) lua_topointer(L, -1);
    
    /* Check if we got enough variables passed on to us.
     * This, of course, only works for prepared statements made through lua. */
    have = lua_gettop(L) - 2;
    if (st->variables != -1 && have < st->variables ) {
        lua_pushboolean(L, 0);
        lua_pushfstring(L, 
                "Error in executing prepared statement: Expected %d arguments, got %d.", 
                st->variables, have);
        return 2;
    }
    vars = apr_pcalloc(st->db->pool, have*sizeof(char *));
    for (x = 0; x < have; x++) {
        vars[x] = lua_tostring(L, x + 2);
    }

    /* Fire off the query */
    if (st->db && st->db->alive) {

        /*~~~~~~~~~~~~~~*/
        int affected = 0;
        /*~~~~~~~~~~~~~~*/

        rc = apr_dbd_pquery(st->db->driver, st->db->pool, st->db->handle,
                                &affected, st->statement, have, vars);
        if (rc == APR_SUCCESS) {
            lua_pushinteger(L, affected);
            return 1;
        }
        else {

            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            const char  *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

            lua_pushnil(L);
            if (err) {
                lua_pushstring(L, err);
                return 2;
            }
            return 1;
        }
    }

    lua_pushboolean(L, 0);
    lua_pushliteral(L, 
            "Database connection seems to be closed, please reacquire it.");
    return (2);
}

/*
   =============================================================================
    db:prepare(statement): Prepares a statement for later query/select.
    Returns a table with a :query and :select function, same as the db funcs.
   =============================================================================
 */
int lua_db_prepare(lua_State* L) 
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db = 0;
    apr_status_t     rc = 0;
    const char      *statement, *at;
    request_rec     *r;
    lua_db_prepared_statement* st;
    int need = 0;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    r = ap_lua_check_request_rec(L, 2);
    if (r) {
        apr_dbd_prepared_t *pstatement = NULL;
        luaL_checktype(L, 3, LUA_TSTRING);
        statement = lua_tostring(L, 3);
        
        /* Count number of variables in statement */
        at = ap_strchr_c(statement,'%');
        while (at != NULL) {
            if (at[1] == '%') {
                at++;
            }
            else {
                need++;
            }
            at = ap_strchr_c(at+1,'%');
        }
        
        
        db = lua_get_db_handle(L);
        rc = apr_dbd_prepare(db->driver, r->pool, db->handle, statement, 
                    NULL, &pstatement);
        if (rc != APR_SUCCESS) {
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
            const char  *err = apr_dbd_error(db->driver, db->handle, rc);
            /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

            lua_pushnil(L);
            if (err) {
                lua_pushstring(L, err);
                return 2;
            }
            return 1;
        }
        
        /* Push the prepared statement table */
        lua_newtable(L);
        st = lua_newuserdata(L, sizeof(lua_db_prepared_statement));
        st->statement = pstatement;
        st->variables = need;
        st->db = db;
        
        lua_pushliteral(L, "select");
        lua_pushcfunction(L, lua_db_prepared_select);
        lua_rawset(L, -4);
        lua_pushliteral(L, "query");
        lua_pushcfunction(L, lua_db_prepared_query);
        lua_rawset(L, -4);
        lua_rawseti(L, -2, 0);
        return 1;
    }
    return 0;
}



/*
   =============================================================================
    db:prepared(statement): Fetches a prepared statement made through 
    DBDPrepareSQL.
   =============================================================================
 */
int lua_db_prepared(lua_State* L) 
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    lua_db_handle   *db = 0;
    const char      *tag;
    request_rec     *r;
    lua_db_prepared_statement* st;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    r = ap_lua_check_request_rec(L, 2);
    if (r) {
        apr_dbd_prepared_t *pstatement = NULL;
        db = lua_get_db_handle(L);
        luaL_checktype(L, 3, LUA_TSTRING);
        tag = lua_tostring(L, 3);
        
        /* Look for the statement */
        pstatement = apr_hash_get(db->dbdhandle->prepared, tag, 
                APR_HASH_KEY_STRING);
        
        if (pstatement == NULL) {
            lua_pushnil(L);
            lua_pushfstring(L, 
                    "Could not find any prepared statement called %s!", tag);
            return 2;
        }
        
        
        /* Push the prepared statement table */
        lua_newtable(L);
        st = lua_newuserdata(L, sizeof(lua_db_prepared_statement));
        st->statement = pstatement;
        st->variables = -1; /* we don't know :( */
        st->db = db;
        lua_pushliteral(L, "select");
        lua_pushcfunction(L, lua_db_prepared_select);
        lua_rawset(L, -4);
        lua_pushliteral(L, "query");
        lua_pushcfunction(L, lua_db_prepared_query);
        lua_rawset(L, -4);
        lua_rawseti(L, -2, 0);
        return 1;
    }
    return 0;
}



/* lua_push_db_handle: Creates a database table object with database functions 
   and a userdata at index 0, which will call lua_dbgc when garbage collected.
 */
static lua_db_handle* lua_push_db_handle(lua_State *L, request_rec* r, int type,
        apr_pool_t* pool) 
{
    lua_db_handle* db;
    lua_newtable(L);
    db = lua_newuserdata(L, sizeof(lua_db_handle));
    db->alive = 1;
    db->pool = pool;
    db->type = type;
    db->dbdhandle = 0;
    db->server = r->server;
    luaL_newmetatable(L, "lua_apr.dbacquire");
    lua_pushliteral(L, "__gc");
    lua_pushcfunction(L, lua_db_gc);
    lua_rawset(L, -3);
    lua_setmetatable(L, -2);
    lua_rawseti(L, -2, 0);
    
    lua_pushliteral(L, "escape");
    lua_pushcfunction(L, lua_db_escape);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "close");
    lua_pushcfunction(L, lua_db_close);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "select");
    lua_pushcfunction(L, lua_db_select);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "query");
    lua_pushcfunction(L, lua_db_query);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "active");
    lua_pushcfunction(L, lua_db_active);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "prepare");
    lua_pushcfunction(L, lua_db_prepare);
    lua_rawset(L, -3);
    
    lua_pushliteral(L, "prepared");
    lua_pushcfunction(L, lua_db_prepared);
    lua_rawset(L, -3);
    return db;
}

/*
   =============================================================================
    dbacquire(dbType, dbString): Opens a new connection to a database of type 
    _dbType_ and with the connection parameters _dbString_. If successful, 
    returns a table with functions for using the database handle. If an error 
    occurs, returns nil as the first parameter and the error message as the 
    second. See the APR_DBD for a list of database types and connection strings 
    supported.
   =============================================================================
 */
int lua_db_acquire(lua_State *L)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    const char      *type;
    const char      *arguments;
    const char      *error = 0;
    request_rec     *r;
    lua_db_handle   *db = 0;
    apr_status_t     rc = 0;
    ap_dbd_t        *dbdhandle = NULL;
    apr_pool_t      *pool = NULL;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    r = ap_lua_check_request_rec(L, 1);
    if (r) {
        type = luaL_optstring(L, 2, "mod_dbd"); /* Defaults to mod_dbd */
        
        if (!strcmp(type, "mod_dbd")) {

            lua_settop(L, 0);
            lua_ap_dbd_open = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_open);
            if (lua_ap_dbd_open)
                dbdhandle = (ap_dbd_t *) lua_ap_dbd_open(
                        r->server->process->pool, r->server);

            if (dbdhandle) {
                db = lua_push_db_handle(L, r, LUA_DBTYPE_MOD_DBD, dbdhandle->pool);
                db->driver = dbdhandle->driver;
                db->handle = dbdhandle->handle;
                db->dbdhandle = dbdhandle;
                return 1;
            }
            else {
                lua_pushnil(L);
                if ( lua_ap_dbd_open == NULL )
                    lua_pushliteral(L,
                                    "mod_dbd doesn't seem to have been loaded.");
                else
                    lua_pushliteral(
                        L,
                        "Could not acquire connection from mod_dbd. If your database is running, this may indicate a permission problem.");
                return 2;
            }
        }
        else {
            rc = apr_pool_create(&pool, NULL);
            if (rc != APR_SUCCESS) {
                lua_pushnil(L);
                lua_pushliteral(L, "Could not allocate memory for database!");
                return 2;
            }
            apr_pool_tag(pool, "lua_dbd_pool");
            apr_dbd_init(pool);
            dbdhandle = apr_pcalloc(pool, sizeof(ap_dbd_t));
            rc = apr_dbd_get_driver(pool, type, &dbdhandle->driver);
            if (rc == APR_SUCCESS) {
                luaL_checktype(L, 3, LUA_TSTRING);
                arguments = lua_tostring(L, 3);
                lua_settop(L, 0);
                
                if (strlen(arguments)) {
                    rc = apr_dbd_open_ex(dbdhandle->driver, pool, 
                            arguments, &dbdhandle->handle, &error);
                    if (rc == APR_SUCCESS) {
                        db = lua_push_db_handle(L, r, LUA_DBTYPE_APR_DBD, pool);
                        db->driver = dbdhandle->driver;
                        db->handle = dbdhandle->handle;
                        db->dbdhandle = dbdhandle;
                        return 1;
                    }
                    else {
                        lua_pushnil(L);
                        if (error) {
                            lua_pushstring(L, error);
                            return 2;
                        }

                        return 1;
                    }
                }

                lua_pushnil(L);
                lua_pushliteral(L,
                                "No database connection string was specified.");
                apr_pool_destroy(pool);
                return (2);
            }
            else {
                lua_pushnil(L);
                if (APR_STATUS_IS_ENOTIMPL(rc)) {
                    lua_pushfstring(L, 
                         "driver for %s not available", type);
                }
                else if (APR_STATUS_IS_EDSOOPEN(rc)) {
                    lua_pushfstring(L, 
                                "can't find driver for %s", type);
                }
                else if (APR_STATUS_IS_ESYMNOTFOUND(rc)) {
                    lua_pushfstring(L, 
                                "driver for %s is invalid or corrupted",
                                type);
                }
                else {
                    lua_pushliteral(L, 
                                "mod_lua not compatible with APR in get_driver");
                }
                lua_pushinteger(L, rc);
                apr_pool_destroy(pool);
                return 3;
            }
        }

        lua_pushnil(L);
        return 1;
    }

    return 0;
}

