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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "apr_pools.h"
23 #define TEST(msg,func) \
24 printf("======== %s ========\n", msg); \
25 rv = func(pool, sql, driver); \
27 printf("Error in %s: rc=%d\n\n", msg, rv); \
30 printf("%s test successful\n\n", msg); \
34 static int create_table(apr_pool_t* pool, apr_dbd_t* handle,
35 const apr_dbd_driver_t* driver)
39 const char *statement = "CREATE TABLE apr_dbd_test ("
40 "col1 varchar(40) not null,"
43 rv = apr_dbd_query(driver, handle, &nrows, statement);
46 static int drop_table(apr_pool_t* pool, apr_dbd_t* handle,
47 const apr_dbd_driver_t* driver)
51 const char *statement = "DROP TABLE apr_dbd_test" ;
52 rv = apr_dbd_query(driver, handle, &nrows, statement);
55 static int insert_rows(apr_pool_t* pool, apr_dbd_t* handle,
56 const apr_dbd_driver_t* driver)
62 const char *statement =
63 "INSERT into apr_dbd_test (col1) values ('foo');"
64 "INSERT into apr_dbd_test values ('wibble', 'other', 5);"
65 "INSERT into apr_dbd_test values ('wibble', 'nothing', 5);"
66 "INSERT into apr_dbd_test values ('qwerty', 'foo', 0);"
67 "INSERT into apr_dbd_test values ('asdfgh', 'bar', 1);"
69 rv = apr_dbd_query(driver, handle, &nrows, statement);
71 const char* stmt[] = {
72 "INSERT into apr_dbd_test (col1) values ('foo');",
73 "INSERT into apr_dbd_test values ('wibble', 'other', 5);",
74 "INSERT into apr_dbd_test values ('wibble', 'nothing', 5);",
75 "INSERT into apr_dbd_test values ('qwerty', 'foo', 0);",
76 "INSERT into apr_dbd_test values ('asdfgh', 'bar', 1);",
79 printf("Compound insert failed; trying statements one-by-one\n") ;
80 for (i=0; stmt[i] != NULL; ++i) {
82 rv = apr_dbd_query(driver, handle, &nrows, statement);
88 printf("%d single inserts failed too.\n", nerrors) ;
93 static int invalid_op(apr_pool_t* pool, apr_dbd_t* handle,
94 const apr_dbd_driver_t* driver)
98 const char *statement = "INSERT into apr_dbd_test1 (col2) values ('foo')" ;
99 rv = apr_dbd_query(driver, handle, &nrows, statement);
100 printf("invalid op returned %d (should be nonzero). Error msg follows\n", rv);
101 printf("'%s'\n", apr_dbd_error(driver, handle, rv));
102 statement = "INSERT into apr_dbd_test (col1, col2) values ('bar', 'foo')" ;
103 rv = apr_dbd_query(driver, handle, &nrows, statement);
104 printf("valid op returned %d (should be zero; error shouldn't affect subsequent ops)\n", rv);
107 static int select_sequential(apr_pool_t* pool, apr_dbd_t* handle,
108 const apr_dbd_driver_t* driver)
114 const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2";
115 apr_dbd_results_t *res = NULL;
116 apr_dbd_row_t *row = NULL;
117 rv = apr_dbd_select(driver,pool,handle,&res,statement,0);
119 printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
122 for (rv = apr_dbd_get_row(driver, pool, res, &row, -1);
124 rv = apr_dbd_get_row(driver, pool, res, &row, -1)) {
125 printf("ROW %d: ", ++i) ;
126 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
127 entry = apr_dbd_get_entry(driver, row, n);
132 printf("%s ", entry);
137 return (rv == -1) ? 0 : 1;
139 static int select_random(apr_pool_t* pool, apr_dbd_t* handle,
140 const apr_dbd_driver_t* driver)
145 const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2";
146 apr_dbd_results_t *res = NULL;
147 apr_dbd_row_t *row = NULL;
148 rv = apr_dbd_select(driver,pool,handle,&res,statement,1);
150 printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
153 rv = apr_dbd_get_row(driver, pool, res, &row, 5) ;
155 printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
159 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
160 entry = apr_dbd_get_entry(driver, row, n);
165 printf("%s ", entry);
169 rv = apr_dbd_get_row(driver, pool, res, &row, 1) ;
171 printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
175 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
176 entry = apr_dbd_get_entry(driver, row, n);
181 printf("%s ", entry);
185 rv = apr_dbd_get_row(driver, pool, res, &row, 11) ;
187 printf("Oops! get_row out of range but thinks it succeeded!\n%s\n",
188 apr_dbd_error(driver, handle, rv));
195 static int test_transactions(apr_pool_t* pool, apr_dbd_t* handle,
196 const apr_dbd_driver_t* driver)
200 apr_dbd_transaction_t *trans = NULL;
201 const char* statement;
203 /* trans 1 - error out early */
204 printf("Transaction 1\n");
205 rv = apr_dbd_transaction_start(driver, pool, handle, &trans);
207 printf("Start transaction failed!\n%s\n",
208 apr_dbd_error(driver, handle, rv));
211 statement = "UPDATE apr_dbd_test SET col2 = 'failed'";
212 rv = apr_dbd_query(driver, handle, &nrows, statement);
214 printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv));
215 apr_dbd_transaction_end(driver, pool, trans);
218 printf("%d rows updated\n", nrows);
220 statement = "INSERT INTO apr_dbd_test1 (col3) values (3)";
221 rv = apr_dbd_query(driver, handle, &nrows, statement);
223 printf("Oops, invalid op succeeded but shouldn't!\n");
225 statement = "INSERT INTO apr_dbd_test values ('zzz', 'aaa', 3)";
226 rv = apr_dbd_query(driver, handle, &nrows, statement);
227 printf("Valid insert returned %d. Should be nonzero (fail) because transaction is bad\n", rv) ;
229 rv = apr_dbd_transaction_end(driver, pool, trans);
231 printf("End transaction failed!\n%s\n",
232 apr_dbd_error(driver, handle, rv));
235 printf("Transaction ended (should be rollback) - viewing table\n"
236 "A column of \"failed\" indicates transaction failed (no rollback)\n");
237 select_sequential(pool, handle, driver);
239 /* trans 2 - complete successfully */
240 printf("Transaction 2\n");
241 rv = apr_dbd_transaction_start(driver, pool, handle, &trans);
243 printf("Start transaction failed!\n%s\n",
244 apr_dbd_error(driver, handle, rv));
247 statement = "UPDATE apr_dbd_test SET col2 = 'success'";
248 rv = apr_dbd_query(driver, handle, &nrows, statement);
250 printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv));
251 apr_dbd_transaction_end(driver, pool, trans);
254 printf("%d rows updated\n", nrows);
255 statement = "INSERT INTO apr_dbd_test values ('aaa', 'zzz', 3)";
256 rv = apr_dbd_query(driver, handle, &nrows, statement);
257 printf("Valid insert returned %d. Should be zero (OK)\n", rv) ;
258 rv = apr_dbd_transaction_end(driver, pool, trans);
260 printf("End transaction failed!\n%s\n",
261 apr_dbd_error(driver, handle, rv));
264 printf("Transaction ended (should be commit) - viewing table\n");
265 select_sequential(pool, handle, driver);
268 static int test_pselect(apr_pool_t* pool, apr_dbd_t* handle,
269 const apr_dbd_driver_t* driver)
274 "SELECT * FROM apr_dbd_test WHERE col3 <= %s or col1 = 'bar'" ;
275 const char *label = "lowvalues";
276 apr_dbd_prepared_t *statement = NULL;
277 apr_dbd_results_t *res = NULL;
278 apr_dbd_row_t *row = NULL;
279 const char *entry = NULL;
281 rv = apr_dbd_prepare(driver, pool, handle, query, label, &statement);
283 printf("Prepare statement failed!\n%s\n",
284 apr_dbd_error(driver, handle, rv));
287 rv = apr_dbd_pvselect(driver, pool, handle, &res, statement, 0, "3", NULL);
289 printf("Exec of prepared statement failed!\n%s\n",
290 apr_dbd_error(driver, handle, rv));
294 printf("Selecting rows where col3 <= 3 and bar row where it's unset.\nShould show four rows.\n");
295 for (rv = apr_dbd_get_row(driver, pool, res, &row, -1);
297 rv = apr_dbd_get_row(driver, pool, res, &row, -1)) {
298 printf("ROW %d: ", ++i) ;
299 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
300 entry = apr_dbd_get_entry(driver, row, n);
305 printf("%s ", entry);
310 return (rv == -1) ? 0 : 1;
312 static int test_pquery(apr_pool_t* pool, apr_dbd_t* handle,
313 const apr_dbd_driver_t* driver)
316 const char *query = "INSERT INTO apr_dbd_test VALUES (%s, %s, %d)";
317 apr_dbd_prepared_t *statement = NULL;
318 const char *label = "testpquery";
320 apr_dbd_transaction_t *trans =0;
322 rv = apr_dbd_prepare(driver, pool, handle, query, label, &statement);
323 /* rv = apr_dbd_prepare(driver, pool, handle, query, NULL, &statement); */
325 printf("Prepare statement failed!\n%s\n",
326 apr_dbd_error(driver, handle, rv));
329 apr_dbd_transaction_start(driver, pool, handle, &trans);
330 rv = apr_dbd_pvquery(driver, pool, handle, &nrows, statement,
331 "prepared", "insert", "2", NULL);
332 apr_dbd_transaction_end(driver, pool, trans);
334 printf("Exec of prepared statement failed!\n%s\n",
335 apr_dbd_error(driver, handle, rv));
338 printf("Showing table (should now contain row \"prepared insert 2\")\n");
339 select_sequential(pool, handle, driver);
342 int main(int argc, char** argv)
346 apr_pool_t *pool = NULL;
347 apr_dbd_t *sql = NULL;
348 const apr_dbd_driver_t *driver = NULL;
352 apr_pool_create(&pool, NULL);
354 if (argc >= 2 && argc <= 3) {
356 params = ( argc == 3 ) ? argv[2] : "";
359 rv = apr_dbd_get_driver(pool, name, &driver);
362 printf("Loaded %s driver OK.\n", name);
365 printf("Failed to load driver file apr_dbd_%s.so\n", name);
367 case APR_ESYMNOTFOUND:
368 printf("Failed to load driver apr_dbd_%s_driver.\n", name);
371 printf("No driver available for %s.\n", name);
373 default: /* it's a bug if none of the above happen */
374 printf("Internal error loading %s.\n", name);
377 rv = apr_dbd_open(driver, pool, params, &sql);
380 printf("Opened %s[%s] OK\n", name, params);
383 printf("Failed to open %s[%s]\n", name, params);
385 default: /* it's a bug if none of the above happen */
386 printf("Internal error opening %s[%s]\n", name, params);
389 TEST("create table", create_table);
390 TEST("insert rows", insert_rows);
391 TEST("invalid op", invalid_op);
392 TEST("select random", select_random);
393 TEST("select sequential", select_sequential);
394 TEST("transactions", test_transactions);
395 TEST("prepared select", test_pselect);
396 TEST("prepared query", test_pquery);
397 TEST("drop table", drop_table);
398 apr_dbd_close(driver, sql);
401 fprintf(stderr, "Usage: %s driver-name [params]\n", argv[0]);
404 apr_pool_destroy(pool);