1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "testutil.h" 18#include "apr.h" 19#include "apu.h" 20#include "apr_pools.h" 21#include "apr_dbd.h" 22#include "apr_strings.h" 23 24static void test_dbd_init(abts_case *tc, void *data) 25{ 26 apr_pool_t *pool = p; 27 apr_status_t rv; 28 29 rv = apr_dbd_init(pool); 30 ABTS_ASSERT(tc, "failed to init apr_dbd", rv == APR_SUCCESS); 31} 32 33#if APU_HAVE_SQLITE2 || APU_HAVE_SQLITE3 34static void test_statement(abts_case *tc, apr_dbd_t* handle, 35 const apr_dbd_driver_t* driver, const char* sql) 36{ 37 int nrows; 38 apr_status_t rv; 39 40 rv = apr_dbd_query(driver, handle, &nrows, sql); 41 42 ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); 43} 44 45static void create_table(abts_case *tc, apr_dbd_t* handle, 46 const apr_dbd_driver_t* driver) 47{ 48 const char *sql = "CREATE TABLE apr_dbd_test (" 49 "col1 varchar(40) not null," 50 "col2 varchar(40)," 51 "col3 integer)"; 52 53 test_statement(tc, handle, driver, sql); 54} 55 56static void drop_table(abts_case *tc, apr_dbd_t* handle, 57 const apr_dbd_driver_t* driver) 58{ 59 const char *sql = "DROP TABLE apr_dbd_test"; 60 test_statement(tc, handle, driver, sql); 61} 62 63static void delete_rows(abts_case *tc, apr_dbd_t* handle, 64 const apr_dbd_driver_t* driver) 65{ 66 const char *sql = "DELETE FROM apr_dbd_test"; 67 test_statement(tc, handle, driver, sql); 68} 69 70 71static void insert_data(abts_case *tc, apr_dbd_t* handle, 72 const apr_dbd_driver_t* driver, int count) 73{ 74 apr_pool_t* pool = p; 75 const char* sql = "INSERT INTO apr_dbd_test VALUES('%d', '%d', %d)"; 76 char* sqf = NULL; 77 int i; 78 int nrows; 79 apr_status_t rv; 80 81 for (i=0; i<count; i++) { 82 sqf = apr_psprintf(pool, sql, i, i, i); 83 rv = apr_dbd_query(driver, handle, &nrows, sqf); 84 ABTS_ASSERT(tc, sqf, rv == APR_SUCCESS); 85 ABTS_ASSERT(tc, sqf, 1 == nrows); 86 } 87} 88 89static void select_rows(abts_case *tc, apr_dbd_t* handle, 90 const apr_dbd_driver_t* driver, int count) 91{ 92 apr_status_t rv; 93 apr_pool_t* pool = p; 94 apr_pool_t* tpool; 95 const char* sql = "SELECT * FROM apr_dbd_test ORDER BY col1"; 96 apr_dbd_results_t *res = NULL; 97 apr_dbd_row_t *row = NULL; 98 int i; 99 100 rv = apr_dbd_select(driver, pool, handle, &res, sql, 0); 101 ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); 102 ABTS_PTR_NOTNULL(tc, res); 103 104 apr_pool_create(&tpool, pool); 105 i = count; 106 while (i > 0) { 107 row = NULL; 108 rv = apr_dbd_get_row(driver, pool, res, &row, -1); 109 ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); 110 ABTS_PTR_NOTNULL(tc, row); 111 apr_pool_clear(tpool); 112 i--; 113 } 114 ABTS_ASSERT(tc, "Missing Rows!", i == 0); 115 116 res = NULL; 117 i = count; 118 119 rv = apr_dbd_select(driver, pool, handle, &res, sql, 1); 120 ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); 121 ABTS_PTR_NOTNULL(tc, res); 122 123 rv = apr_dbd_num_tuples(driver, res); 124 ABTS_ASSERT(tc, "invalid row count", rv == count); 125 126 while (i > 0) { 127 row = NULL; 128 rv = apr_dbd_get_row(driver, pool, res, &row, i); 129 ABTS_ASSERT(tc, sql, rv == APR_SUCCESS); 130 ABTS_PTR_NOTNULL(tc, row); 131 apr_pool_clear(tpool); 132 i--; 133 } 134 ABTS_ASSERT(tc, "Missing Rows!", i == 0); 135 rv = apr_dbd_get_row(driver, pool, res, &row, count+100); 136 ABTS_ASSERT(tc, "If we overseek, get_row should return -1", rv == -1); 137} 138 139static void test_escape(abts_case *tc, apr_dbd_t *handle, 140 const apr_dbd_driver_t *driver) 141{ 142 const char *escaped = apr_dbd_escape(driver, p, "foo'bar", handle); 143 144 ABTS_STR_EQUAL(tc, "foo''bar", escaped); 145} 146 147static void test_dbd_generic(abts_case *tc, apr_dbd_t* handle, 148 const apr_dbd_driver_t* driver) 149{ 150 void* native; 151 apr_pool_t *pool = p; 152 apr_status_t rv; 153 154 native = apr_dbd_native_handle(driver, handle); 155 ABTS_PTR_NOTNULL(tc, native); 156 157 rv = apr_dbd_check_conn(driver, pool, handle); 158 159 create_table(tc, handle, driver); 160 select_rows(tc, handle, driver, 0); 161 insert_data(tc, handle, driver, 5); 162 select_rows(tc, handle, driver, 5); 163 delete_rows(tc, handle, driver); 164 select_rows(tc, handle, driver, 0); 165 drop_table(tc, handle, driver); 166 167 test_escape(tc, handle, driver); 168 169 rv = apr_dbd_close(driver, handle); 170 ABTS_ASSERT(tc, "failed to close database", rv == APR_SUCCESS); 171} 172#endif 173 174#if APU_HAVE_SQLITE2 175static void test_dbd_sqlite2(abts_case *tc, void *data) 176{ 177 apr_pool_t *pool = p; 178 apr_status_t rv; 179 const apr_dbd_driver_t* driver = NULL; 180 apr_dbd_t* handle = NULL; 181 182 rv = apr_dbd_get_driver(pool, "sqlite2", &driver); 183 ABTS_ASSERT(tc, "failed to fetch sqlite2 driver", rv == APR_SUCCESS); 184 ABTS_PTR_NOTNULL(tc, driver); 185 if (!driver) { 186 return; 187 } 188 189 ABTS_STR_EQUAL(tc, "sqlite2", apr_dbd_name(driver)); 190 191 rv = apr_dbd_open(driver, pool, "data/sqlite2.db:600", &handle); 192 ABTS_ASSERT(tc, "failed to open sqlite2 atabase", rv == APR_SUCCESS); 193 ABTS_PTR_NOTNULL(tc, handle); 194 if (!handle) { 195 return; 196 } 197 198 test_dbd_generic(tc, handle, driver); 199} 200#endif 201 202#if APU_HAVE_SQLITE3 203static void test_dbd_sqlite3(abts_case *tc, void *data) 204{ 205 apr_pool_t *pool = p; 206 apr_status_t rv; 207 const apr_dbd_driver_t* driver = NULL; 208 apr_dbd_t* handle = NULL; 209 210 rv = apr_dbd_get_driver(pool, "sqlite3", &driver); 211 ABTS_ASSERT(tc, "failed to fetch sqlite3 driver", rv == APR_SUCCESS); 212 ABTS_PTR_NOTNULL(tc, driver); 213 if (!driver) { 214 return; 215 } 216 217 ABTS_STR_EQUAL(tc, "sqlite3", apr_dbd_name(driver)); 218 219 rv = apr_dbd_open(driver, pool, "data/sqlite3.db", &handle); 220 ABTS_ASSERT(tc, "failed to open sqlite3 database", rv == APR_SUCCESS); 221 ABTS_PTR_NOTNULL(tc, handle); 222 if (!handle) { 223 return; 224 } 225 226 test_dbd_generic(tc, handle, driver); 227} 228#endif 229 230abts_suite *testdbd(abts_suite *suite) 231{ 232 suite = ADD_SUITE(suite); 233 234 235 abts_run_test(suite, test_dbd_init, NULL); 236 237#if APU_HAVE_SQLITE2 238 abts_run_test(suite, test_dbd_sqlite2, NULL); 239#endif 240 241#if APU_HAVE_SQLITE3 242 abts_run_test(suite, test_dbd_sqlite3, NULL); 243#endif 244 return suite; 245} 246