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
);