static int select_random(apr_pool_t* pool, apr_dbd_t* handle, const apr_dbd_driver_t* driver) { int rv = 0; int n; const char* entry; const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2"; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; rv = apr_dbd_select(driver,pool,handle,&res,statement,1); if (rv) { printf("Select failed: %s", apr_dbd_error(driver, handle, rv)); return rv; } rv = apr_dbd_get_row(driver, pool, res, &row, 5) ; if (rv) { printf("get_row failed: %s", apr_dbd_error(driver, handle, rv)); return rv; } printf("ROW 5: "); for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) { entry = apr_dbd_get_entry(driver, row, n); if (entry == NULL) { printf("(null) ") ; } else { printf("%s ", entry); } } fputs("\n", stdout); rv = apr_dbd_get_row(driver, pool, res, &row, 1) ; if (rv) { printf("get_row failed: %s", apr_dbd_error(driver, handle, rv)); return rv; } printf("ROW 1: "); for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) { entry = apr_dbd_get_entry(driver, row, n); if (entry == NULL) { printf("(null) ") ; } else { printf("%s ", entry); } } fputs("\n", stdout); rv = apr_dbd_get_row(driver, pool, res, &row, 11) ; if (rv != -1) { printf("Oops! get_row out of range but thinks it succeeded!\n%s\n", apr_dbd_error(driver, handle, rv)); return -1; } rv = 0; return rv; }
static int select_sequential(apr_pool_t* pool, apr_dbd_t* handle, const apr_dbd_driver_t* driver) { int rv = 0; int i = 0; int n; const char* entry; const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2"; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; rv = apr_dbd_select(driver,pool,handle,&res,statement,0); if (rv) { printf("Select failed: %s", apr_dbd_error(driver, handle, rv)); return rv; } for (rv = apr_dbd_get_row(driver, pool, res, &row, -1); rv == 0; rv = apr_dbd_get_row(driver, pool, res, &row, -1)) { printf("ROW %d: ", ++i) ; for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) { entry = apr_dbd_get_entry(driver, row, n); if (entry == NULL) { printf("(null) ") ; } else { printf("%s ", entry); } } fputs("\n", stdout); } return (rv == -1) ? 0 : 1; }
std::vector<MetadataStorage::UntypedTuple> MetadataStorage::select_query(const char* query) const { std::vector<UntypedTuple> tuples; apr_dbd_results_t *results = nullptr; int status = apr_dbd_select(driver_, pool_.get(), handle_.get(), &results, query, 0); if (status != 0) { (*logger_)(AKU_LOG_ERROR, "Error executing query"); throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status)); } // get rows int ntuples = apr_dbd_num_tuples(driver_, results); int ncolumns = apr_dbd_num_cols(driver_, results); for (int i = ntuples; i --> 0;) { apr_dbd_row_t *row = nullptr; status = apr_dbd_get_row(driver_, pool_.get(), results, &row, -1); if (status != 0) { (*logger_)(AKU_LOG_ERROR, "Error getting row from resultset"); throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status)); } UntypedTuple tup; for (int col = 0; col < ncolumns; col++) { const char* entry = apr_dbd_get_entry(driver_, row, col); if (entry) { tup.emplace_back(entry); } else { tup.emplace_back(); } } tuples.push_back(std::move(tup)); } return tuples; }
static int test_pselect(apr_pool_t* pool, apr_dbd_t* handle, const apr_dbd_driver_t* driver) { int rv = 0; int i, n; const char *query = "SELECT * FROM apr_dbd_test WHERE col3 <= %s or col1 = 'bar'" ; const char *label = "lowvalues"; apr_dbd_prepared_t *statement = NULL; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; const char *entry = NULL; rv = apr_dbd_prepare(driver, pool, handle, query, label, &statement); if (rv) { printf("Prepare statement failed!\n%s\n", apr_dbd_error(driver, handle, rv)); return rv; } rv = apr_dbd_pvselect(driver, pool, handle, &res, statement, 0, "3", NULL); if (rv) { printf("Exec of prepared statement failed!\n%s\n", apr_dbd_error(driver, handle, rv)); return rv; } i = 0; printf("Selecting rows where col3 <= 3 and bar row where it's unset.\nShould show four rows.\n"); for (rv = apr_dbd_get_row(driver, pool, res, &row, -1); rv == 0; rv = apr_dbd_get_row(driver, pool, res, &row, -1)) { printf("ROW %d: ", ++i) ; for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) { entry = apr_dbd_get_entry(driver, row, n); if (entry == NULL) { printf("(null) ") ; } else { printf("%s ", entry); } } fputs("\n", stdout); } return (rv == -1) ? 0 : 1; }
/* ============================================================================= 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 prepped 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); }
/* ============================================================================= 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; }