static void test_dbd_sqlite3(abts_case *tc, void *data) { apr_pool_t *pool = p; apr_status_t rv; const apr_dbd_driver_t* driver = NULL; apr_dbd_t* handle = NULL; rv = apr_dbd_get_driver(pool, "sqlite3", &driver); ABTS_ASSERT(tc, "failed to fetch sqlite3 driver", rv == APR_SUCCESS); ABTS_PTR_NOTNULL(tc, driver); if (!driver) { return; } ABTS_STR_EQUAL(tc, "sqlite3", apr_dbd_name(driver)); rv = apr_dbd_open(driver, pool, "data/sqlite3.db", &handle); ABTS_ASSERT(tc, "failed to open sqlite3 database", rv == APR_SUCCESS); ABTS_PTR_NOTNULL(tc, handle); if (!handle) { return; } test_dbd_generic(tc, handle, driver); }
MetadataStorage::MetadataStorage(const char* db, aku_logger_cb_t logger) : pool_(nullptr, &delete_apr_pool) , driver_(nullptr) , handle_(nullptr, AprHandleDeleter(nullptr)) , logger_(logger) { apr_pool_t *pool = nullptr; auto status = apr_pool_create(&pool, NULL); if (status != APR_SUCCESS) { // report error (can't return error from c-tor) throw std::runtime_error("Can't create memory pool"); } pool_.reset(pool); status = apr_dbd_get_driver(pool, "sqlite3", &driver_); if (status != APR_SUCCESS) { (*logger_)(AKU_LOG_ERROR, "Can't load driver, maybe libaprutil1-dbd-sqlite3 isn't installed"); throw std::runtime_error("Can't load sqlite3 dirver"); } apr_dbd_t *handle = nullptr; status = apr_dbd_open(driver_, pool, db, &handle); if (status != APR_SUCCESS) { (*logger_)(AKU_LOG_ERROR, "Can't open database, check file path"); throw std::runtime_error("Can't open database"); } handle_ = HandleT(handle, AprHandleDeleter(driver_)); auto sqlite_handle = apr_dbd_native_handle(driver_, handle); sqlite3_trace((sqlite3*)sqlite_handle, callback_adapter, (void*)logger_); create_tables(); // Create prepared statement const char* query = "INSERT INTO akumuli_series (series_id, keyslist, storage_id) VALUES (%s, %s, %d)"; status = apr_dbd_prepare(driver_, pool_.get(), handle_.get(), query, "INSERT_SERIES_NAME", &insert_); if (status != 0) { (*logger_)(AKU_LOG_ERROR, "Error creating prepared statement"); throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status)); } }
/* ============================================================================= 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. ============================================================================= */ AP_LUA_DECLARE(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; }
int main(int argc, char** argv) { const char *name; const char *params; apr_pool_t *pool = NULL; apr_dbd_t *sql = NULL; const apr_dbd_driver_t *driver = NULL; int rv; apr_initialize(); apr_pool_create(&pool, NULL); if (argc >= 2 && argc <= 3) { name = argv[1]; params = ( argc == 3 ) ? argv[2] : ""; apr_dbd_init(pool); setbuf(stdout,NULL); rv = apr_dbd_get_driver(pool, name, &driver); switch (rv) { case APR_SUCCESS: printf("Loaded %s driver OK.\n", name); break; case APR_EDSOOPEN: printf("Failed to load driver file apr_dbd_%s.so\n", name); goto finish; case APR_ESYMNOTFOUND: printf("Failed to load driver apr_dbd_%s_driver.\n", name); goto finish; case APR_ENOTIMPL: printf("No driver available for %s.\n", name); goto finish; default: /* it's a bug if none of the above happen */ printf("Internal error loading %s.\n", name); goto finish; } rv = apr_dbd_open(driver, pool, params, &sql); switch (rv) { case APR_SUCCESS: printf("Opened %s[%s] OK\n", name, params); break; case APR_EGENERAL: printf("Failed to open %s[%s]\n", name, params); goto finish; default: /* it's a bug if none of the above happen */ printf("Internal error opening %s[%s]\n", name, params); goto finish; } TEST("create table", create_table); TEST("insert rows", insert_rows); TEST("invalid op", invalid_op); TEST("select random", select_random); TEST("select sequential", select_sequential); TEST("transactions", test_transactions); TEST("prepared select", test_pselect); TEST("prepared query", test_pquery); TEST("drop table", drop_table); apr_dbd_close(driver, sql); } else { fprintf(stderr, "Usage: %s driver-name [params]\n", argv[0]); } finish: apr_pool_destroy(pool); apr_terminate(); return 0; }