Revert change to testdate.c (commited by accident)
[apr-util.git] / test / dbd.c
blobb5ae9630318b41791bdfd4fd762b722aaa22a11d
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.
17 #include "apu.h"
18 #include "apr_pools.h"
19 #include "apr_dbd.h"
21 #include <stdio.h>
23 #define TEST(msg,func) \
24 printf("======== %s ========\n", msg); \
25 rv = func(pool, sql, driver); \
26 if (rv != 0) { \
27 printf("Error in %s: rc=%d\n\n", msg, rv); \
28 } \
29 else { \
30 printf("%s test successful\n\n", msg); \
31 } \
32 fflush(stdout);
34 static int create_table(apr_pool_t* pool, apr_dbd_t* handle,
35 const apr_dbd_driver_t* driver)
37 int rv = 0;
38 int nrows;
39 const char *statement = "CREATE TABLE apr_dbd_test ("
40 "col1 varchar(40) not null,"
41 "col2 varchar(40),"
42 "col3 integer)" ;
43 rv = apr_dbd_query(driver, handle, &nrows, statement);
44 return rv;
46 static int drop_table(apr_pool_t* pool, apr_dbd_t* handle,
47 const apr_dbd_driver_t* driver)
49 int rv = 0;
50 int nrows;
51 const char *statement = "DROP TABLE apr_dbd_test" ;
52 rv = apr_dbd_query(driver, handle, &nrows, statement);
53 return rv;
55 static int insert_rows(apr_pool_t* pool, apr_dbd_t* handle,
56 const apr_dbd_driver_t* driver)
58 int i;
59 int rv = 0;
60 int nrows;
61 int nerrors = 0;
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);
70 if (rv) {
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);",
77 NULL
79 printf("Compound insert failed; trying statements one-by-one\n") ;
80 for (i=0; stmt[i] != NULL; ++i) {
81 statement = stmt[i];
82 rv = apr_dbd_query(driver, handle, &nrows, statement);
83 if (rv) {
84 nerrors++;
87 if (nerrors) {
88 printf("%d single inserts failed too.\n", nerrors) ;
91 return rv;
93 static int invalid_op(apr_pool_t* pool, apr_dbd_t* handle,
94 const apr_dbd_driver_t* driver)
96 int rv = 0;
97 int nrows;
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);
105 return rv;
107 static int select_sequential(apr_pool_t* pool, apr_dbd_t* handle,
108 const apr_dbd_driver_t* driver)
110 int rv = 0;
111 int i = 0;
112 int n;
113 const char* entry;
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);
118 if (rv) {
119 printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
120 return rv;
122 for (rv = apr_dbd_get_row(driver, pool, res, &row, -1);
123 rv == 0;
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);
128 if (entry == NULL) {
129 printf("(null) ") ;
131 else {
132 printf("%s ", entry);
135 fputs("\n", stdout);
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)
142 int rv = 0;
143 int n;
144 const char* entry;
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);
149 if (rv) {
150 printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
151 return rv;
153 rv = apr_dbd_get_row(driver, pool, res, &row, 5) ;
154 if (rv) {
155 printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
156 return rv;
158 printf("ROW 5: ");
159 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
160 entry = apr_dbd_get_entry(driver, row, n);
161 if (entry == NULL) {
162 printf("(null) ") ;
164 else {
165 printf("%s ", entry);
168 fputs("\n", stdout);
169 rv = apr_dbd_get_row(driver, pool, res, &row, 1) ;
170 if (rv) {
171 printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
172 return rv;
174 printf("ROW 1: ");
175 for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) {
176 entry = apr_dbd_get_entry(driver, row, n);
177 if (entry == NULL) {
178 printf("(null) ") ;
180 else {
181 printf("%s ", entry);
184 fputs("\n", stdout);
185 rv = apr_dbd_get_row(driver, pool, res, &row, 11) ;
186 if (rv != -1) {
187 printf("Oops! get_row out of range but thinks it succeeded!\n%s\n",
188 apr_dbd_error(driver, handle, rv));
189 return -1;
191 rv = 0;
193 return rv;
195 static int test_transactions(apr_pool_t* pool, apr_dbd_t* handle,
196 const apr_dbd_driver_t* driver)
198 int rv = 0;
199 int nrows;
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);
206 if (rv) {
207 printf("Start transaction failed!\n%s\n",
208 apr_dbd_error(driver, handle, rv));
209 return rv;
211 statement = "UPDATE apr_dbd_test SET col2 = 'failed'";
212 rv = apr_dbd_query(driver, handle, &nrows, statement);
213 if (rv) {
214 printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv));
215 apr_dbd_transaction_end(driver, pool, trans);
216 return rv;
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);
222 if (!rv) {
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);
230 if (rv) {
231 printf("End transaction failed!\n%s\n",
232 apr_dbd_error(driver, handle, rv));
233 return 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);
242 if (rv) {
243 printf("Start transaction failed!\n%s\n",
244 apr_dbd_error(driver, handle, rv));
245 return rv;
247 statement = "UPDATE apr_dbd_test SET col2 = 'success'";
248 rv = apr_dbd_query(driver, handle, &nrows, statement);
249 if (rv) {
250 printf("Update failed: '%s'\n", apr_dbd_error(driver, handle, rv));
251 apr_dbd_transaction_end(driver, pool, trans);
252 return rv;
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);
259 if (rv) {
260 printf("End transaction failed!\n%s\n",
261 apr_dbd_error(driver, handle, rv));
262 return rv;
264 printf("Transaction ended (should be commit) - viewing table\n");
265 select_sequential(pool, handle, driver);
266 return rv;
268 static int test_pselect(apr_pool_t* pool, apr_dbd_t* handle,
269 const apr_dbd_driver_t* driver)
271 int rv = 0;
272 int i, n;
273 const char *query =
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);
282 if (rv) {
283 printf("Prepare statement failed!\n%s\n",
284 apr_dbd_error(driver, handle, rv));
285 return rv;
287 rv = apr_dbd_pvselect(driver, pool, handle, &res, statement, 0, "3", NULL);
288 if (rv) {
289 printf("Exec of prepared statement failed!\n%s\n",
290 apr_dbd_error(driver, handle, rv));
291 return rv;
293 i = 0;
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);
296 rv == 0;
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);
301 if (entry == NULL) {
302 printf("(null) ") ;
304 else {
305 printf("%s ", entry);
308 fputs("\n", stdout);
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)
315 int rv = 0;
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";
319 int nrows;
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); */
324 if (rv) {
325 printf("Prepare statement failed!\n%s\n",
326 apr_dbd_error(driver, handle, rv));
327 return 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);
333 if (rv) {
334 printf("Exec of prepared statement failed!\n%s\n",
335 apr_dbd_error(driver, handle, rv));
336 return rv;
338 printf("Showing table (should now contain row \"prepared insert 2\")\n");
339 select_sequential(pool, handle, driver);
340 return rv;
342 int main(int argc, char** argv)
344 const char *name;
345 const char *params;
346 apr_pool_t *pool = NULL;
347 apr_dbd_t *sql = NULL;
348 const apr_dbd_driver_t *driver = NULL;
349 int rv;
351 apr_initialize();
352 apr_pool_create(&pool, NULL);
354 if (argc >= 2 && argc <= 3) {
355 name = argv[1];
356 params = ( argc == 3 ) ? argv[2] : "";
357 apr_dbd_init(pool);
358 setbuf(stdout,NULL);
359 rv = apr_dbd_get_driver(pool, name, &driver);
360 switch (rv) {
361 case APR_SUCCESS:
362 printf("Loaded %s driver OK.\n", name);
363 break;
364 case APR_EDSOOPEN:
365 printf("Failed to load driver file apr_dbd_%s.so\n", name);
366 goto finish;
367 case APR_ESYMNOTFOUND:
368 printf("Failed to load driver apr_dbd_%s_driver.\n", name);
369 goto finish;
370 case APR_ENOTIMPL:
371 printf("No driver available for %s.\n", name);
372 goto finish;
373 default: /* it's a bug if none of the above happen */
374 printf("Internal error loading %s.\n", name);
375 goto finish;
377 rv = apr_dbd_open(driver, pool, params, &sql);
378 switch (rv) {
379 case APR_SUCCESS:
380 printf("Opened %s[%s] OK\n", name, params);
381 break;
382 case APR_EGENERAL:
383 printf("Failed to open %s[%s]\n", name, params);
384 goto finish;
385 default: /* it's a bug if none of the above happen */
386 printf("Internal error opening %s[%s]\n", name, params);
387 goto finish;
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);
400 else {
401 fprintf(stderr, "Usage: %s driver-name [params]\n", argv[0]);
403 finish:
404 apr_pool_destroy(pool);
405 apr_terminate();
406 return 0;