Author: pquerna Date: Mon Mar 21 23:44:41 2005 New Revision: 158572 URL: http://svn.apache.org/viewcvs?view=rev&rev=158572 Log: - Rewrite the DBD tests to use the ABTS framework. - Move old tests to test/dbd.c - sqlite2 support, based on Ryan's patch. Changes to pass the tests and build on my debian machine.
Submitted By: Ryan Phillips <ryan trolocsis.com> PR: 34078 Added: apr/apr-util/trunk/dbd/apr_dbd_sqlite2.c apr/apr-util/trunk/test/data/ (with props) apr/apr-util/trunk/test/dbd.c - copied unchanged from r158540, apr/apr-util/trunk/test/testdbd.c Modified: apr/apr-util/trunk/CHANGES apr/apr-util/trunk/build/dbd.m4 apr/apr-util/trunk/configure.in apr/apr-util/trunk/dbd/apr_dbd.c apr/apr-util/trunk/include/apu.h.in apr/apr-util/trunk/test/Makefile.in apr/apr-util/trunk/test/abts_tests.h apr/apr-util/trunk/test/testdbd.c apr/apr-util/trunk/test/testutil.h Modified: apr/apr-util/trunk/CHANGES URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/CHANGES?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/CHANGES (original) +++ apr/apr-util/trunk/CHANGES Mon Mar 21 23:44:41 2005 @@ -1,5 +1,7 @@ Changes with APR-util 1.2.0 + *) Add sqlite2 support to APR DBD. [Ryan Phillips <ryan trolocsis.com>] + *) Introduction of APR DBD layer. [Nick Kew] Changes with APR-util 1.1.2 Modified: apr/apr-util/trunk/build/dbd.m4 URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/build/dbd.m4?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/build/dbd.m4 (original) +++ apr/apr-util/trunk/build/dbd.m4 Mon Mar 21 23:44:41 2005 @@ -119,4 +119,41 @@ APR_ADDTO(APRUTIL_LIBS,[-lmysqlclient_r]) fi ]) +AC_DEFUN([APU_CHECK_DBD_SQLITE2], [ + apu_have_sqlite2=0 + + AC_ARG_WITH([sqlite2], [ + --with-sqlite2=DIR + ], [ + apu_have_sqlite2=0 + if test "$withval" = "yes"; then + AC_CHECK_HEADER(sqlite.h, AC_CHECK_LIB(sqlite, sqlite_open, [apu_have_sqlite2=1])) + elif test "$withval" = "no"; then + apu_have_sqlite2=0 + else + CPPFLAGS="-I$withval/include" + LIBS="-L$withval/lib " + + AC_MSG_NOTICE(checking for sqlite2 in $withval) + AC_CHECK_HEADER(sqlite.h, AC_CHECK_LIB(sqlite, sqlite_open, [apu_have_sqlite2=1])) + if test "$apu_have_sqlite2" != "0"; then + APR_ADDTO(APRUTIL_LDFLAGS, [-L$withval/lib]) + APR_ADDTO(APRUTIL_INCLUDES, [-I$withval/include]) + fi + fi + ], [ + apu_have_sqlite2=0 + AC_CHECK_HEADER(sqlite.h, AC_CHECK_LIB(sqlite, sqlite_open, [apu_have_sqlite2=1])) + ]) + + AC_SUBST(apu_have_sqlite2) + + dnl Since we have already done the AC_CHECK_LIB tests, if we have it, + dnl we know the library is there. + if test "$apu_have_sqlite2" = "1"; then + APR_ADDTO(APRUTIL_EXPORT_LIBS,[-lsqlite]) + APR_ADDTO(APRUTIL_LIBS,[-lsqlite]) + fi +]) +dnl Modified: apr/apr-util/trunk/configure.in URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/configure.in?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/configure.in (original) +++ apr/apr-util/trunk/configure.in Mon Mar 21 23:44:41 2005 @@ -120,6 +120,7 @@ APU_CHECK_DBM APU_CHECK_DBD APU_CHECK_DBD_MYSQL +APU_CHECK_DBD_SQLITE2 APU_FIND_EXPAT APU_FIND_ICONV Modified: apr/apr-util/trunk/dbd/apr_dbd.c URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/dbd/apr_dbd.c?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/dbd/apr_dbd.c (original) +++ apr/apr-util/trunk/dbd/apr_dbd.c Mon Mar 21 23:44:41 2005 @@ -68,6 +68,9 @@ #if APU_HAVE_PGSQL DRIVER_LOAD("pgsql", apr_dbd_pgsql_driver, pool); #endif +#if APU_HAVE_SQLITE2 + DRIVER_LOAD("sqlite2", apr_dbd_sqlite2_driver, pool); +#endif #if APU_HAVE_SOME_OTHER_BACKEND DRIVER_LOAD("firebird", apr_dbd_other_driver, pool); #endif Added: apr/apr-util/trunk/dbd/apr_dbd_sqlite2.c URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/dbd/apr_dbd_sqlite2.c?view=auto&rev=158572 ============================================================================== --- apr/apr-util/trunk/dbd/apr_dbd_sqlite2.c (added) +++ apr/apr-util/trunk/dbd/apr_dbd_sqlite2.c Mon Mar 21 23:44:41 2005 @@ -0,0 +1,393 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed 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_SQLITE2 + +#include <ctype.h> +#include <stdlib.h> + +#include <sqlite.h> + +#include "apr_strings.h" +#include "apr_time.h" + +typedef struct apr_dbd_t apr_dbd_t; + +typedef struct +{ + int errnum; + apr_dbd_t *handle; +} apr_dbd_transaction_t; + +struct apr_dbd_t +{ + sqlite *conn; + char *errmsg; + apr_dbd_transaction_t *trans; +}; + +typedef struct +{ + int random; + sqlite *handle; + char **res; + size_t ntuples; + size_t sz; + size_t index; +} apr_dbd_results_t; + +typedef struct +{ + int n; + char **data; + apr_dbd_results_t *res; +} apr_dbd_row_t; + +typedef struct +{ + const char *name; + int prepared; +} apr_dbd_prepared_t; + +#define APR_DBD_INTERNAL +#include "apr_dbd.h" + +#define FREE_ERROR_MSG(dbd) \ + do { \ + if(dbd && dbd->errmsg) { \ + free(dbd->errmsg); \ + dbd->errmsg = NULL; \ + } \ + } while(0); + + +static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql, + apr_dbd_results_t ** results, const char *query, + int seek) +{ + char **result; + int ret = 0; + int tuples = 0; + int fields = 0; + + if (sql->trans && sql->trans->errnum) { + return sql->trans->errnum; + } + + FREE_ERROR_MSG(sql); + + ret = sqlite_get_table(sql->conn, query, &result, &tuples, &fields, + &sql->errmsg); + + if (ret == SQLITE_OK) { + if (!*results) { + *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); + } + + (*results)->res = result; + if (seek) { + (*results)->ntuples = tuples; + } + else { + (*results)->ntuples = -1; + } + (*results)->sz = fields; + (*results)->random = seek; + + if (tuples > 0) + apr_pool_cleanup_register(pool, result, (void *) free, + apr_pool_cleanup_null); + + ret = 0; + } + else { + sql->trans->errnum = ret; + } + + return ret; +} + +static int dbd_sqlite_get_row(apr_pool_t * pool, apr_dbd_results_t * res, + apr_dbd_row_t ** rowp, int rownum) +{ + apr_dbd_row_t *row = *rowp; + int sequential = ((rownum >= 0) && res->random) ? 0 : 1; + + if (row == NULL) { + row = apr_palloc(pool, sizeof(apr_dbd_row_t)); + *rowp = row; + row->res = res; + row->n = sequential ? 0 : rownum - 1; + } + else { + if (sequential) { + ++row->n; + } + else { + row->n = rownum - 1; + } + } + + if (row->n >= res->ntuples) { + *rowp = NULL; + apr_pool_cleanup_kill(pool, res->res, (void *) free); + res->res = NULL; + return -1; + } + + /* Pointer magic explanation: + * The sqlite result is an array such that the first res->sz elements are + * the column names and each tuple follows afterwards + * ex: (from the sqlite2 documentation) + SELECT employee_name, login, host FROM users WHERE login LIKE * 'd%'; + + nrow = 2 + ncolumn = 3 + result[0] = "employee_name" + result[1] = "login" + result[2] = "host" + result[3] = "dummy" + result[4] = "No such user" + result[5] = 0 + result[6] = "D. Richard Hipp" + result[7] = "drh" + result[8] = "zadok" + */ + + row->data = res->res + res->sz + (res->sz * row->n); + + return 0; +} + +static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n) +{ + return row->data[n]; +} + +static const char *dbd_sqlite_error(apr_dbd_t * sql, int n) +{ + return sql->errmsg; +} + +static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query) +{ + char **result; + int ret; + int tuples = 0; + int fields = 0; + + if (sql->trans && sql->trans->errnum) { + return sql->trans->errnum; + } + + FREE_ERROR_MSG(sql); + + ret = + sqlite_get_table(sql->conn, query, &result, &tuples, &fields, + &sql->errmsg); + if (ret == SQLITE_OK) { + *nrows = sqlite_changes(sql->conn); + + if (tuples > 0) + free(result); + + ret = 0; + } + + if (sql->trans) { + sql->trans->errnum = ret; + } + + return ret; +} + +static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg, + apr_dbd_t * sql) +{ + char *ret = sqlite_mprintf(arg); + apr_pool_cleanup_register(pool, ret, (void *) sqlite_freemem, + apr_pool_cleanup_null); + return ret; +} + +static int dbd_sqlite_prepare(apr_pool_t * pool, apr_dbd_t * sql, + const char *query, const char *label, + apr_dbd_prepared_t ** statement) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pquery(apr_pool_t * pool, apr_dbd_t * sql, + int *nrows, apr_dbd_prepared_t * statement, + int nargs, const char **values) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pvquery(apr_pool_t * pool, apr_dbd_t * sql, + int *nrows, apr_dbd_prepared_t * statement, ...) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pselect(apr_pool_t * pool, apr_dbd_t * sql, + apr_dbd_results_t ** results, + apr_dbd_prepared_t * statement, + int seek, int nargs, const char **values) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_pvselect(apr_pool_t * pool, apr_dbd_t * sql, + apr_dbd_results_t ** results, + apr_dbd_prepared_t * statement, int seek, ...) +{ + return APR_ENOTIMPL; +} + +static int dbd_sqlite_start_transaction(apr_pool_t * pool, apr_dbd_t * handle, + apr_dbd_transaction_t ** trans) +{ + int ret, rows; + + ret = dbd_sqlite_query(handle, &rows, "BEGIN TRANSACTION"); + if (ret == 0) { + if (!*trans) { + *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); + } + (*trans)->handle = handle; + handle->trans = *trans; + } + else { + ret = -1; + } + return ret; +} + +static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans) +{ + int rows; + int ret = -1; /* no transaction is an error cond */ + + if (trans) { + if (trans->errnum) { + trans->errnum = 0; + ret = + dbd_sqlite_query(trans->handle, &rows, + "ROLLBACK TRANSACTION"); + } + else { + ret = + dbd_sqlite_query(trans->handle, &rows, "COMMIT TRANSACTION"); + } + trans->handle->trans = NULL; + } + + return ret; +} + +static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_) +{ + apr_dbd_t *sql; + sqlite *conn = NULL; + char *filename, *perm; + int iperms = 600; + char* params = apr_pstrdup(pool, params_); + /* params = "[filename]:[permissions]" + * example: "shopping.db:600" + */ + + perm = strstr(params, ":"); + if (perm) { + *(perm++) = '\x00'; // split the filename and permissions + + if (strlen(perm) > 0) + iperms = atoi(perm); + } + + conn = sqlite_open(params, iperms, NULL); + + sql = apr_pcalloc(pool, sizeof(*sql)); + sql->conn = conn; + + return sql; +} + +static apr_status_t dbd_sqlite_close(apr_dbd_t * handle) +{ + if (handle->conn) { + sqlite_close(handle->conn); + handle->conn = NULL; + } + return APR_SUCCESS; +} + +static apr_status_t dbd_sqlite_check_conn(apr_pool_t * pool, + apr_dbd_t * handle) +{ + if (handle->conn == NULL) + return -1; + return APR_SUCCESS; +} + +static int dbd_sqlite_select_db(apr_pool_t * pool, apr_dbd_t * handle, + const char *name) +{ + return APR_ENOTIMPL; +} + +static void *dbd_sqlite_native(apr_dbd_t * handle) +{ + return handle->conn; +} + +static int dbd_sqlite_num_cols(apr_dbd_results_t * res) +{ + return res->sz; +} + +static int dbd_sqlite_num_tuples(apr_dbd_results_t * res) +{ + return res->ntuples; +} + +APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = { + "sqlite2", + NULL, + dbd_sqlite_native, + dbd_sqlite_open, + dbd_sqlite_check_conn, + dbd_sqlite_close, + dbd_sqlite_select_db, + dbd_sqlite_start_transaction, + dbd_sqlite_end_transaction, + dbd_sqlite_query, + dbd_sqlite_select, + dbd_sqlite_num_cols, + dbd_sqlite_num_tuples, + dbd_sqlite_get_row, + dbd_sqlite_get_entry, + dbd_sqlite_error, + dbd_sqlite_escape, + dbd_sqlite_prepare, + dbd_sqlite_pvquery, + dbd_sqlite_pvselect, + dbd_sqlite_pquery, + dbd_sqlite_pselect, +}; +#endif Modified: apr/apr-util/trunk/include/apu.h.in URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/include/apu.h.in?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/include/apu.h.in (original) +++ apr/apr-util/trunk/include/apu.h.in Mon Mar 21 23:44:41 2005 @@ -79,6 +79,7 @@ #define APU_HAVE_PGSQL @apu_have_pgsql@ #define APU_HAVE_MYSQL @apu_have_mysql@ +#define APU_HAVE_SQLITE2 @apu_have_sqlite2@ #define APU_HAVE_APR_ICONV @have_apr_iconv@ #define APU_HAVE_ICONV @have_iconv@ Modified: apr/apr-util/trunk/test/Makefile.in URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/test/Makefile.in?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/test/Makefile.in (original) +++ apr/apr-util/trunk/test/Makefile.in Mon Mar 21 23:44:41 2005 @@ -3,8 +3,8 @@ INCLUDES = @APRUTIL_PRIV_INCLUDES@ @APR_INCLUDES@ @APRUTIL_INCLUDES@ PROGRAMS = testall testdbm testdate testxml testrmm \ - testreslist testqueue testxlate -TARGETS = $(PROGRAMS) testdbd + testreslist testqueue testxlate dbd +TARGETS = $(PROGRAMS) [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ @@ -33,6 +33,11 @@ testdbm: $(testdbm_OBJECTS) $(testdbm_LDADD) $(LINK) $(APRUTIL_LDFLAGS) $(testdbm_OBJECTS) $(testdbm_LDADD) $(PROGRAM_DEPENDENCIES) +dbd_OBJECTS = dbd.lo +dbd_LDADD = $(TARGET_LIB_PATH) +dbd: $(dbd_OBJECTS) $(dbd_LDADD) + $(LINK) $(APRUTIL_LDFLAGS) $(dbd_OBJECTS) $(dbd_LDADD) $(PROGRAM_DEPENDENCIES) + testdbd_OBJECTS = testdbd.lo testdbd_LDADD = $(TARGET_LIB_PATH) testdbd: $(testdbd_OBJECTS) $(testdbd_LDADD) @@ -69,7 +74,7 @@ $(LINK) $(APRUTIL_LDFLAGS) $(testxlate_OBJECTS) $(testxlate_LDADD) $(PROGRAM_DEPENDENCIES) testall_OBJECTS = teststrmatch.lo testuri.lo testuuid.lo abts.lo testutil.lo \ - testbuckets.lo testpass.lo testmd4.lo testmd5.lo testldap.lo + testbuckets.lo testpass.lo testmd4.lo testmd5.lo testldap.lo testdbd.lo testall_LDADD = $(TARGET_LIB_PATH) testall: $(testall_OBJECTS) $(testall_LDADD) $(LINK) $(APRUTIL_LDFLAGS) $(testall_OBJECTS) $(testall_LDADD) $(PROGRAM_DEPENDENCIES) Modified: apr/apr-util/trunk/test/abts_tests.h URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/test/abts_tests.h?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/test/abts_tests.h (original) +++ apr/apr-util/trunk/test/abts_tests.h Mon Mar 21 23:44:41 2005 @@ -30,7 +30,8 @@ {testpass}, {testmd4}, {testmd5}, - {testldap} + {testldap}, + {testdbd} }; #endif /* APR_TEST_INCLUDES */ Propchange: apr/apr-util/trunk/test/data/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Mar 21 23:44:41 2005 @@ -0,0 +1 @@ +sqlite2.db Modified: apr/apr-util/trunk/test/testdbd.c URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/test/testdbd.c?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/test/testdbd.c (original) +++ apr/apr-util/trunk/test/testdbd.c Mon Mar 21 23:44:41 2005 @@ -14,394 +14,183 @@ * limitations under the License. */ +#include "testutil.h" +#include "apr.h" #include "apu.h" #include "apr_pools.h" #include "apr_dbd.h" -#include <stdio.h> +static void test_dbd_init(abts_case *tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; -#define TEST(msg,func) \ - printf("======== %s ========\n", msg); \ - rv = func(pool, sql, driver); \ - if (rv != 0) { \ - printf("Error in %s: rc=%d\n\n", msg, rv); \ - } \ - else { \ - printf("%s test successful\n\n", msg); \ - } \ - fflush(stdout); + rv = apr_dbd_init(pool); + ABTS_ASSERT(tc, "failed to init apr_dbd", rv == APR_SUCCESS); +} -static int create_table(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) +static void test_statement(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver, const char* sql) { - int rv = 0; int nrows; - const char *statement = "CREATE TABLE apr_dbd_test (" - "col1 varchar(40) not null," - "col2 varchar(40)," - "col3 integer)" ; - rv = apr_dbd_query(driver, handle, &nrows, statement); - return rv; + apr_status_t rv; + + rv = apr_dbd_query(driver, handle, &nrows, sql); + + ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); } -static int drop_table(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + +static void create_table(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver) { - int rv = 0; - int nrows; - const char *statement = "DROP TABLE apr_dbd_test" ; - rv = apr_dbd_query(driver, handle, &nrows, statement); - return rv; + const char *sql = "CREATE TABLE apr_dbd_test (" + "col1 varchar(40) not null," + "col2 varchar(40)," + "col3 integer)"; + + test_statement(tc, handle, driver, sql); } -static int insert_rows(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + +static void drop_table(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver) { - int i; - int rv = 0; - int nrows; - int nerrors = 0; - const char *statement = - "INSERT into apr_dbd_test (col1) values ('foo');" - "INSERT into apr_dbd_test values ('wibble', 'other', 5);" - "INSERT into apr_dbd_test values ('wibble', 'nothing', 5);" - "INSERT into apr_dbd_test values ('qwerty', 'foo', 0);" - "INSERT into apr_dbd_test values ('asdfgh', 'bar', 1);" - ; - rv = apr_dbd_query(driver, handle, &nrows, statement); - if (rv) { - const char* stmt[] = { - "INSERT into apr_dbd_test (col1) values ('foo');", - "INSERT into apr_dbd_test values ('wibble', 'other', 5);", - "INSERT into apr_dbd_test values ('wibble', 'nothing', 5);", - "INSERT into apr_dbd_test values ('qwerty', 'foo', 0);", - "INSERT into apr_dbd_test values ('asdfgh', 'bar', 1);", - NULL - }; - printf("Compound insert failed; trying statements one-by-one\n") ; - for (i=0; stmt[i] != NULL; ++i) { - statement = stmt[i]; - rv = apr_dbd_query(driver, handle, &nrows, statement); - if (rv) { - nerrors++; - } - } - if (nerrors) { - printf("%d single inserts failed too.\n", nerrors) ; - } - } - return rv; + const char *sql = "DROP TABLE apr_dbd_test"; + test_statement(tc, handle, driver, sql); } -static int invalid_op(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + +static void delete_rows(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver) { - int rv = 0; - int nrows; - const char *statement = "INSERT into apr_dbd_test1 (col2) values ('foo')" ; - rv = apr_dbd_query(driver, handle, &nrows, statement); - printf("invalid op returned %d (should be nonzero). Error msg follows\n", rv); - printf("'%s'\n", apr_dbd_error(driver, handle, rv)); - statement = "INSERT into apr_dbd_test (col1, col2) values ('bar', 'foo')" ; - rv = apr_dbd_query(driver, handle, &nrows, statement); - printf("valid op returned %d (should be zero; error shouldn't affect subsequent ops)\n", rv); - return rv; + const char *sql = "DELETE FROM apr_dbd_test"; + test_statement(tc, handle, driver, sql); } -static int select_sequential(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + + +static void insert_data(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver, int count) { - 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); + apr_pool_t* pool = p; + const char* sql = "INSERT INTO apr_dbd_test VALUES('%d', '%d', %d)"; + char* sqf = NULL; + int i; + int nrows; + apr_status_t rv; + + for (i=0; i<count; i++) { + sqf = apr_psprintf(pool, sql, i, i, i); + rv = apr_dbd_query(driver, handle, &nrows, sqf); + ABTS_ASSERT(tc, sqf, rv == APR_SUCCESS); + ABTS_ASSERT(tc, sqf, 1 == nrows); } - return (rv == -1) ? 0 : 1; } -static int select_random(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + +static void select_rows(abts_case *tc, apr_dbd_t* handle, + apr_dbd_driver_t* driver, int count) { - int rv = 0; - int n; - const char* entry; - const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2"; + apr_status_t rv; + apr_pool_t* pool = p; + apr_pool_t* tpool; + const char* sql = "SELECT * FROM apr_dbd_test ORDER BY col1"; 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; + int i; - return rv; + rv = apr_dbd_select(driver, pool, handle, &res, sql, 0); + ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, res); + + rv = apr_dbd_num_tuples(driver, res); + ABTS_ASSERT(tc, "no row counts for async selects", rv == -1); + + apr_pool_create(&tpool, pool); + i = count; + while (i > 0) { + row = NULL; + rv = apr_dbd_get_row(driver, pool, res, &row, -1); + ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, row); + apr_pool_clear(tpool); + i--; + } + ABTS_ASSERT(tc, "Missing Rows!", i == 0); + + res = NULL; + i = count; + + rv = apr_dbd_select(driver, pool, handle, &res, sql, 1); + ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, res); + + rv = apr_dbd_num_tuples(driver, res); + ABTS_ASSERT(tc, "invalid row count", rv == count); + + while (i > 0) { + row = NULL; + rv = apr_dbd_get_row(driver, pool, res, &row, i); + ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, row); + apr_pool_clear(tpool); + i--; + } + ABTS_ASSERT(tc, "Missing Rows!", i == 0); + rv = apr_dbd_get_row(driver, pool, res, &row, count+100); + ABTS_ASSERT(tc, "If we overseek, get_row should return -1", rv == -1); } -static int test_transactions(apr_pool_t* pool, apr_dbd_t* handle, + +static void test_dbd_generic(abts_case *tc, apr_dbd_t* handle, apr_dbd_driver_t* driver) { - int rv = 0; - int nrows; - apr_dbd_transaction_t *trans = NULL; - const char* statement; + void* native; + apr_pool_t *pool = p; + apr_status_t rv; - /* trans 1 - error out early */ - printf("Transaction 1\n"); - rv = apr_dbd_transaction_start(driver, pool, handle, &trans); - if (rv) { - printf("Start transaction failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - statement = "UPDATE apr_dbd_test SET col2 = 'failed'"; - rv = apr_dbd_query(driver, handle, &nrows, statement); - if (rv) { - printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv)); - apr_dbd_transaction_end(driver, pool, trans); - return rv; - } - printf("%d rows updated\n", nrows); + native = apr_dbd_native_handle(driver, handle); + ABTS_PTR_NOTNULL(tc, native); - statement = "INSERT INTO apr_dbd_test1 (col3) values (3)"; - rv = apr_dbd_query(driver, handle, &nrows, statement); - if (!rv) { - printf("Oops, invalid op succeeded but shouldn't!\n"); - } - statement = "INSERT INTO apr_dbd_test values ('zzz', 'aaa', 3)"; - rv = apr_dbd_query(driver, handle, &nrows, statement); - printf("Valid insert returned %d. Should be nonzero (fail) because transaction is bad\n", rv) ; - - rv = apr_dbd_transaction_end(driver, pool, trans); - if (rv) { - printf("End transaction failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - printf("Transaction ended (should be rollback) - viewing table\n" - "A column of \"failed\" indicates transaction failed (no rollback)\n"); - select_sequential(pool, handle, driver); - - /* trans 2 - complete successfully */ - printf("Transaction 2\n"); - rv = apr_dbd_transaction_start(driver, pool, handle, &trans); - if (rv) { - printf("Start transaction failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - statement = "UPDATE apr_dbd_test SET col2 = 'success'"; - rv = apr_dbd_query(driver, handle, &nrows, statement); - if (rv) { - printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv)); - apr_dbd_transaction_end(driver, pool, trans); - return rv; - } - printf("%d rows updated\n", nrows); - statement = "INSERT INTO apr_dbd_test values ('aaa', 'zzz', 3)"; - rv = apr_dbd_query(driver, handle, &nrows, statement); - printf("Valid insert returned %d. Should be zero (OK)\n", rv) ; - rv = apr_dbd_transaction_end(driver, pool, trans); - if (rv) { - printf("End transaction failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - printf("Transaction ended (should be commit) - viewing table\n"); - select_sequential(pool, handle, driver); - return rv; -} -static int test_pselect(apr_pool_t* pool, apr_dbd_t* handle, - 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_check_conn(driver, pool, handle); - 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 = driver->pvselect(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; + create_table(tc, handle, driver); + select_rows(tc, handle, driver, 0); + insert_data(tc, handle, driver, 5); + select_rows(tc, handle, driver, 5); + delete_rows(tc, handle, driver); + select_rows(tc, handle, driver, 0); + drop_table(tc, handle, driver); + + rv = apr_dbd_close(driver, handle); + ABTS_ASSERT(tc, "failed to close database", rv == APR_SUCCESS); } -static int test_pquery(apr_pool_t* pool, apr_dbd_t* handle, - apr_dbd_driver_t* driver) + +#if APU_HAVE_SQLITE2 +static void test_dbd_sqlite2(abts_case *tc, void *data) { - int rv = 0; - const char *query = "INSERT INTO apr_dbd_test VALUES (%s, %s, %d)"; - apr_dbd_prepared_t *statement = NULL; - const char *label = "testpquery"; - int nrows; - apr_dbd_transaction_t *trans =0; + apr_pool_t *pool = p; + apr_status_t rv; + apr_dbd_driver_t* driver = NULL; + apr_dbd_t* handle = NULL; - rv = apr_dbd_prepare(driver, pool, handle, query, label, &statement); - /* rv = apr_dbd_prepare(driver, pool, handle, query, NULL, &statement); */ - if (rv) { - printf("Prepare statement failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - apr_dbd_transaction_start(driver, pool, handle, &trans); - rv = driver->pvquery(pool, handle, &nrows, statement, - "prepared", "insert", "2", NULL); - apr_dbd_transaction_end(driver, pool, trans); - if (rv) { - printf("Exec of prepared statement failed!\n%s\n", - apr_dbd_error(driver, handle, rv)); - return rv; - } - printf("Showing table (should now contain row \"prepared insert 2\")\n"); - select_sequential(pool, handle, driver); - return rv; + rv = apr_dbd_get_driver(pool, "sqlite2", &driver); + ABTS_ASSERT(tc, "failed to fetch driver", rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, driver); + + ABTS_STR_EQUAL(tc, apr_dbd_name(driver), "sqlite2"); + + rv = apr_dbd_open(driver, pool, "data/sqlite2.db:600", &handle); + ABTS_ASSERT(tc, "failed to open database", rv == APR_SUCCESS); + ABTS_PTR_NOTNULL(tc, handle); + + test_dbd_generic(tc, handle, driver); } -int main(int argc, char** argv) +#endif + +abts_suite *testdbd(abts_suite *suite) { - const char *name; - const char *params; - apr_pool_t *pool = NULL; - apr_dbd_t *sql = NULL; - 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; + suite = ADD_SUITE(suite); + + + abts_run_test(suite, test_dbd_init, NULL); +#if APU_HAVE_SQLITE2 + abts_run_test(suite, test_dbd_sqlite2, NULL); +#endif + return suite; } Modified: apr/apr-util/trunk/test/testutil.h URL: http://svn.apache.org/viewcvs/apr/apr-util/trunk/test/testutil.h?view=diff&r1=158571&r2=158572 ============================================================================== --- apr/apr-util/trunk/test/testutil.h (original) +++ apr/apr-util/trunk/test/testutil.h Mon Mar 21 23:44:41 2005 @@ -51,5 +51,6 @@ abts_suite *testmd4(abts_suite *suite); abts_suite *testmd5(abts_suite *suite); abts_suite *testldap(abts_suite *suite); +abts_suite *testdbd(abts_suite *suite); #endif /* APR_TEST_INCLUDES */