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 "apu.h" 18 19#if APU_HAVE_SQLITE3 20 21#include <ctype.h> 22#include <stdlib.h> 23 24#include <sqlite3.h> 25 26#include "apr_strings.h" 27#include "apr_time.h" 28#include "apr_buckets.h" 29 30#include "apr_dbd_internal.h" 31 32#define MAX_RETRY_COUNT 15 33#define MAX_RETRY_SLEEP 100000 34 35struct apr_dbd_transaction_t { 36 int mode; 37 int errnum; 38 apr_dbd_t *handle; 39}; 40 41struct apr_dbd_t { 42 sqlite3 *conn; 43 apr_dbd_transaction_t *trans; 44 apr_pool_t *pool; 45 apr_dbd_prepared_t *prep; 46}; 47 48typedef struct { 49 char *name; 50 char *value; 51 int size; 52 int type; 53} apr_dbd_column_t; 54 55struct apr_dbd_row_t { 56 apr_dbd_results_t *res; 57 apr_dbd_column_t **columns; 58 apr_dbd_row_t *next_row; 59 int columnCount; 60 int rownum; 61}; 62 63struct apr_dbd_results_t { 64 int random; 65 sqlite3 *handle; 66 sqlite3_stmt *stmt; 67 apr_dbd_row_t *next_row; 68 size_t sz; 69 int tuples; 70 char **col_names; 71 apr_pool_t *pool; 72}; 73 74struct apr_dbd_prepared_t { 75 sqlite3_stmt *stmt; 76 apr_dbd_prepared_t *next; 77 int nargs; 78 int nvals; 79 apr_dbd_type_e *types; 80}; 81 82#define dbd_sqlite3_is_success(x) (((x) == SQLITE_DONE) || ((x) == SQLITE_OK)) 83 84static int dbd_sqlite3_select_internal(apr_pool_t *pool, 85 apr_dbd_t *sql, 86 apr_dbd_results_t **results, 87 sqlite3_stmt *stmt, int seek) 88{ 89 int ret, retry_count = 0, column_count; 90 size_t i, num_tuples = 0; 91 int increment = 0; 92 apr_dbd_row_t *row = NULL; 93 apr_dbd_row_t *lastrow = NULL; 94 apr_dbd_column_t *column; 95 char *hold = NULL; 96 97 column_count = sqlite3_column_count(stmt); 98 if (!*results) { 99 *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); 100 } 101 (*results)->stmt = stmt; 102 (*results)->sz = column_count; 103 (*results)->random = seek; 104 (*results)->next_row = 0; 105 (*results)->tuples = 0; 106 (*results)->col_names = apr_pcalloc(pool, column_count * sizeof(char *)); 107 (*results)->pool = pool; 108 do { 109 ret = sqlite3_step(stmt); 110 if (ret == SQLITE_BUSY) { 111 if (retry_count++ > MAX_RETRY_COUNT) { 112 ret = SQLITE_ERROR; 113 } else { 114 apr_dbd_mutex_unlock(); 115 apr_sleep(MAX_RETRY_SLEEP); 116 apr_dbd_mutex_lock(); 117 } 118 } else if (ret == SQLITE_ROW) { 119 int length; 120 row = apr_palloc(pool, sizeof(apr_dbd_row_t)); 121 row->res = *results; 122 increment = sizeof(apr_dbd_column_t *); 123 length = increment * (*results)->sz; 124 row->columns = apr_palloc(pool, length); 125 row->columnCount = column_count; 126 for (i = 0; i < (*results)->sz; i++) { 127 column = apr_palloc(pool, sizeof(apr_dbd_column_t)); 128 row->columns[i] = column; 129 /* copy column name once only */ 130 if ((*results)->col_names[i] == NULL) { 131 (*results)->col_names[i] = 132 apr_pstrdup(pool, sqlite3_column_name(stmt, i)); 133 } 134 column->name = (*results)->col_names[i]; 135 column->size = sqlite3_column_bytes(stmt, i); 136 column->type = sqlite3_column_type(stmt, i); 137 column->value = NULL; 138 switch (column->type) { 139 case SQLITE_FLOAT: 140 case SQLITE_INTEGER: 141 case SQLITE_TEXT: 142 hold = (char *) sqlite3_column_text(stmt, i); 143 if (hold) { 144 column->value = apr_pstrmemdup(pool, hold, 145 column->size); 146 } 147 break; 148 case SQLITE_BLOB: 149 hold = (char *) sqlite3_column_blob(stmt, i); 150 if (hold) { 151 column->value = apr_pstrmemdup(pool, hold, 152 column->size); 153 } 154 break; 155 case SQLITE_NULL: 156 break; 157 } 158 } 159 row->rownum = num_tuples++; 160 row->next_row = 0; 161 (*results)->tuples = num_tuples; 162 if ((*results)->next_row == 0) { 163 (*results)->next_row = row; 164 } 165 if (lastrow != 0) { 166 lastrow->next_row = row; 167 } 168 lastrow = row; 169 } 170 } while (ret == SQLITE_ROW || ret == SQLITE_BUSY); 171 172 if (dbd_sqlite3_is_success(ret)) { 173 ret = 0; 174 } 175 return ret; 176} 177 178static int dbd_sqlite3_select(apr_pool_t *pool, apr_dbd_t *sql, 179 apr_dbd_results_t **results, const char *query, 180 int seek) 181{ 182 sqlite3_stmt *stmt = NULL; 183 const char *tail = NULL; 184 int ret; 185 186 if (sql->trans && sql->trans->errnum) { 187 return sql->trans->errnum; 188 } 189 190 apr_dbd_mutex_lock(); 191 192 ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail); 193 if (dbd_sqlite3_is_success(ret)) { 194 ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); 195 } 196 sqlite3_finalize(stmt); 197 198 apr_dbd_mutex_unlock(); 199 200 if (TXN_NOTICE_ERRORS(sql->trans)) { 201 sql->trans->errnum = ret; 202 } 203 return ret; 204} 205 206static const char *dbd_sqlite3_get_name(const apr_dbd_results_t *res, int n) 207{ 208 if ((n < 0) || ((size_t)n >= res->sz)) { 209 return NULL; 210 } 211 212 return res->col_names[n]; 213} 214 215static int dbd_sqlite3_get_row(apr_pool_t *pool, apr_dbd_results_t *res, 216 apr_dbd_row_t **rowp, int rownum) 217{ 218 int i = 0; 219 220 if (rownum == -1) { 221 *rowp = res->next_row; 222 if (*rowp == 0) 223 return -1; 224 res->next_row = (*rowp)->next_row; 225 return 0; 226 } 227 if (rownum > res->tuples) { 228 return -1; 229 } 230 rownum--; 231 *rowp = res->next_row; 232 for (; *rowp != 0; i++, *rowp = (*rowp)->next_row) { 233 if (i == rownum) { 234 return 0; 235 } 236 } 237 238 return -1; 239 240} 241 242static const char *dbd_sqlite3_get_entry(const apr_dbd_row_t *row, int n) 243{ 244 apr_dbd_column_t *column; 245 const char *value; 246 if ((n < 0) || (n >= row->columnCount)) { 247 return NULL; 248 } 249 column = row->columns[n]; 250 value = column->value; 251 return value; 252} 253 254static apr_status_t dbd_sqlite3_datum_get(const apr_dbd_row_t *row, int n, 255 apr_dbd_type_e type, void *data) 256{ 257 if ((n < 0) || ((size_t)n >= row->res->sz)) { 258 return APR_EGENERAL; 259 } 260 261 if (row->columns[n]->type == SQLITE_NULL) { 262 return APR_ENOENT; 263 } 264 265 switch (type) { 266 case APR_DBD_TYPE_TINY: 267 *(char*)data = atoi(row->columns[n]->value); 268 break; 269 case APR_DBD_TYPE_UTINY: 270 *(unsigned char*)data = atoi(row->columns[n]->value); 271 break; 272 case APR_DBD_TYPE_SHORT: 273 *(short*)data = atoi(row->columns[n]->value); 274 break; 275 case APR_DBD_TYPE_USHORT: 276 *(unsigned short*)data = atoi(row->columns[n]->value); 277 break; 278 case APR_DBD_TYPE_INT: 279 *(int*)data = atoi(row->columns[n]->value); 280 break; 281 case APR_DBD_TYPE_UINT: 282 *(unsigned int*)data = atoi(row->columns[n]->value); 283 break; 284 case APR_DBD_TYPE_LONG: 285 *(long*)data = atol(row->columns[n]->value); 286 break; 287 case APR_DBD_TYPE_ULONG: 288 *(unsigned long*)data = atol(row->columns[n]->value); 289 break; 290 case APR_DBD_TYPE_LONGLONG: 291 *(apr_int64_t*)data = apr_atoi64(row->columns[n]->value); 292 break; 293 case APR_DBD_TYPE_ULONGLONG: 294 *(apr_uint64_t*)data = apr_atoi64(row->columns[n]->value); 295 break; 296 case APR_DBD_TYPE_FLOAT: 297 *(float*)data = (float)atof(row->columns[n]->value); 298 break; 299 case APR_DBD_TYPE_DOUBLE: 300 *(double*)data = atof(row->columns[n]->value); 301 break; 302 case APR_DBD_TYPE_STRING: 303 case APR_DBD_TYPE_TEXT: 304 case APR_DBD_TYPE_TIME: 305 case APR_DBD_TYPE_DATE: 306 case APR_DBD_TYPE_DATETIME: 307 case APR_DBD_TYPE_TIMESTAMP: 308 case APR_DBD_TYPE_ZTIMESTAMP: 309 *(char**)data = row->columns[n]->value; 310 break; 311 case APR_DBD_TYPE_BLOB: 312 case APR_DBD_TYPE_CLOB: 313 { 314 apr_bucket *e; 315 apr_bucket_brigade *b = (apr_bucket_brigade*)data; 316 317 e = apr_bucket_pool_create(row->columns[n]->value, 318 row->columns[n]->size, 319 row->res->pool, b->bucket_alloc); 320 APR_BRIGADE_INSERT_TAIL(b, e); 321 } 322 break; 323 case APR_DBD_TYPE_NULL: 324 *(void**)data = NULL; 325 break; 326 default: 327 return APR_EGENERAL; 328 } 329 330 return APR_SUCCESS; 331} 332 333static const char *dbd_sqlite3_error(apr_dbd_t *sql, int n) 334{ 335 return sqlite3_errmsg(sql->conn); 336} 337 338static int dbd_sqlite3_query_internal(apr_dbd_t *sql, sqlite3_stmt *stmt, 339 int *nrows) 340{ 341 int ret = -1, retry_count = 0; 342 343 while(retry_count++ <= MAX_RETRY_COUNT) { 344 ret = sqlite3_step(stmt); 345 if (ret != SQLITE_BUSY) 346 break; 347 348 apr_dbd_mutex_unlock(); 349 apr_sleep(MAX_RETRY_SLEEP); 350 apr_dbd_mutex_lock(); 351 } 352 353 *nrows = sqlite3_changes(sql->conn); 354 355 if (dbd_sqlite3_is_success(ret)) { 356 ret = 0; 357 } 358 return ret; 359} 360 361static int dbd_sqlite3_query(apr_dbd_t *sql, int *nrows, const char *query) 362{ 363 sqlite3_stmt *stmt = NULL; 364 const char *tail = NULL; 365 int ret = -1, length = 0; 366 367 if (sql->trans && sql->trans->errnum) { 368 return sql->trans->errnum; 369 } 370 371 length = strlen(query); 372 apr_dbd_mutex_lock(); 373 374 do { 375 ret = sqlite3_prepare(sql->conn, query, length, &stmt, &tail); 376 if (ret != SQLITE_OK) { 377 sqlite3_finalize(stmt); 378 break; 379 } 380 381 ret = dbd_sqlite3_query_internal(sql, stmt, nrows); 382 383 sqlite3_finalize(stmt); 384 length -= (tail - query); 385 query = tail; 386 } while (length > 0); 387 388 apr_dbd_mutex_unlock(); 389 390 if (TXN_NOTICE_ERRORS(sql->trans)) { 391 sql->trans->errnum = ret; 392 } 393 return ret; 394} 395 396static apr_status_t free_mem(void *data) 397{ 398 sqlite3_free(data); 399 return APR_SUCCESS; 400} 401 402static const char *dbd_sqlite3_escape(apr_pool_t *pool, const char *arg, 403 apr_dbd_t *sql) 404{ 405 char *ret = sqlite3_mprintf("%q", arg); 406 apr_pool_cleanup_register(pool, ret, free_mem, 407 apr_pool_cleanup_null); 408 return ret; 409} 410 411static int dbd_sqlite3_prepare(apr_pool_t *pool, apr_dbd_t *sql, 412 const char *query, const char *label, 413 int nargs, int nvals, apr_dbd_type_e *types, 414 apr_dbd_prepared_t **statement) 415{ 416 sqlite3_stmt *stmt; 417 const char *tail = NULL; 418 int ret; 419 420 apr_dbd_mutex_lock(); 421 422 ret = sqlite3_prepare(sql->conn, query, strlen(query), &stmt, &tail); 423 if (ret == SQLITE_OK) { 424 apr_dbd_prepared_t *prep; 425 426 prep = apr_pcalloc(sql->pool, sizeof(*prep)); 427 prep->stmt = stmt; 428 prep->next = sql->prep; 429 prep->nargs = nargs; 430 prep->nvals = nvals; 431 prep->types = types; 432 433 /* link new statement to the handle */ 434 sql->prep = prep; 435 436 *statement = prep; 437 } else { 438 sqlite3_finalize(stmt); 439 } 440 441 apr_dbd_mutex_unlock(); 442 443 return ret; 444} 445 446static void dbd_sqlite3_bind(apr_dbd_prepared_t *statement, const char **values) 447{ 448 sqlite3_stmt *stmt = statement->stmt; 449 int i, j; 450 451 for (i = 0, j = 0; i < statement->nargs; i++, j++) { 452 if (values[j] == NULL) { 453 sqlite3_bind_null(stmt, i + 1); 454 } 455 else { 456 switch (statement->types[i]) { 457 case APR_DBD_TYPE_BLOB: 458 case APR_DBD_TYPE_CLOB: 459 { 460 char *data = (char *)values[j]; 461 int size = atoi((char*)values[++j]); 462 463 /* skip table and column */ 464 j += 2; 465 466 sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC); 467 } 468 break; 469 default: 470 sqlite3_bind_text(stmt, i + 1, values[j], 471 strlen(values[j]), SQLITE_STATIC); 472 break; 473 } 474 } 475 } 476 477 return; 478} 479 480static int dbd_sqlite3_pquery(apr_pool_t *pool, apr_dbd_t *sql, 481 int *nrows, apr_dbd_prepared_t *statement, 482 const char **values) 483{ 484 sqlite3_stmt *stmt = statement->stmt; 485 int ret = -1; 486 487 if (sql->trans && sql->trans->errnum) { 488 return sql->trans->errnum; 489 } 490 491 apr_dbd_mutex_lock(); 492 493 ret = sqlite3_reset(stmt); 494 if (ret == SQLITE_OK) { 495 dbd_sqlite3_bind(statement, values); 496 497 ret = dbd_sqlite3_query_internal(sql, stmt, nrows); 498 499 sqlite3_reset(stmt); 500 } 501 502 apr_dbd_mutex_unlock(); 503 504 if (TXN_NOTICE_ERRORS(sql->trans)) { 505 sql->trans->errnum = ret; 506 } 507 return ret; 508} 509 510static int dbd_sqlite3_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, 511 apr_dbd_prepared_t *statement, va_list args) 512{ 513 const char **values; 514 int i; 515 516 if (sql->trans && sql->trans->errnum) { 517 return sql->trans->errnum; 518 } 519 520 values = apr_palloc(pool, sizeof(*values) * statement->nvals); 521 522 for (i = 0; i < statement->nvals; i++) { 523 values[i] = va_arg(args, const char*); 524 } 525 526 return dbd_sqlite3_pquery(pool, sql, nrows, statement, values); 527} 528 529static int dbd_sqlite3_pselect(apr_pool_t *pool, apr_dbd_t *sql, 530 apr_dbd_results_t **results, 531 apr_dbd_prepared_t *statement, int seek, 532 const char **values) 533{ 534 sqlite3_stmt *stmt = statement->stmt; 535 int ret; 536 537 if (sql->trans && sql->trans->errnum) { 538 return sql->trans->errnum; 539 } 540 541 apr_dbd_mutex_lock(); 542 543 ret = sqlite3_reset(stmt); 544 if (ret == SQLITE_OK) { 545 dbd_sqlite3_bind(statement, values); 546 547 ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); 548 549 sqlite3_reset(stmt); 550 } 551 552 apr_dbd_mutex_unlock(); 553 554 if (TXN_NOTICE_ERRORS(sql->trans)) { 555 sql->trans->errnum = ret; 556 } 557 return ret; 558} 559 560static int dbd_sqlite3_pvselect(apr_pool_t *pool, apr_dbd_t *sql, 561 apr_dbd_results_t **results, 562 apr_dbd_prepared_t *statement, int seek, 563 va_list args) 564{ 565 const char **values; 566 int i; 567 568 if (sql->trans && sql->trans->errnum) { 569 return sql->trans->errnum; 570 } 571 572 values = apr_palloc(pool, sizeof(*values) * statement->nvals); 573 574 for (i = 0; i < statement->nvals; i++) { 575 values[i] = va_arg(args, const char*); 576 } 577 578 return dbd_sqlite3_pselect(pool, sql, results, statement, seek, values); 579} 580 581static void dbd_sqlite3_bbind(apr_dbd_prepared_t * statement, 582 const void **values) 583{ 584 sqlite3_stmt *stmt = statement->stmt; 585 int i, j; 586 apr_dbd_type_e type; 587 588 for (i = 0, j = 0; i < statement->nargs; i++, j++) { 589 type = (values[j] == NULL ? APR_DBD_TYPE_NULL : statement->types[i]); 590 591 switch (type) { 592 case APR_DBD_TYPE_TINY: 593 sqlite3_bind_int(stmt, i + 1, *(char*)values[j]); 594 break; 595 case APR_DBD_TYPE_UTINY: 596 sqlite3_bind_int(stmt, i + 1, *(unsigned char*)values[j]); 597 break; 598 case APR_DBD_TYPE_SHORT: 599 sqlite3_bind_int(stmt, i + 1, *(short*)values[j]); 600 break; 601 case APR_DBD_TYPE_USHORT: 602 sqlite3_bind_int(stmt, i + 1, *(unsigned short*)values[j]); 603 break; 604 case APR_DBD_TYPE_INT: 605 sqlite3_bind_int(stmt, i + 1, *(int*)values[j]); 606 break; 607 case APR_DBD_TYPE_UINT: 608 sqlite3_bind_int(stmt, i + 1, *(unsigned int*)values[j]); 609 break; 610 case APR_DBD_TYPE_LONG: 611 sqlite3_bind_int64(stmt, i + 1, *(long*)values[j]); 612 break; 613 case APR_DBD_TYPE_ULONG: 614 sqlite3_bind_int64(stmt, i + 1, *(unsigned long*)values[j]); 615 break; 616 case APR_DBD_TYPE_LONGLONG: 617 sqlite3_bind_int64(stmt, i + 1, *(apr_int64_t*)values[j]); 618 break; 619 case APR_DBD_TYPE_ULONGLONG: 620 sqlite3_bind_int64(stmt, i + 1, *(apr_uint64_t*)values[j]); 621 break; 622 case APR_DBD_TYPE_FLOAT: 623 sqlite3_bind_double(stmt, i + 1, *(float*)values[j]); 624 break; 625 case APR_DBD_TYPE_DOUBLE: 626 sqlite3_bind_double(stmt, i + 1, *(double*)values[j]); 627 break; 628 case APR_DBD_TYPE_STRING: 629 case APR_DBD_TYPE_TEXT: 630 case APR_DBD_TYPE_TIME: 631 case APR_DBD_TYPE_DATE: 632 case APR_DBD_TYPE_DATETIME: 633 case APR_DBD_TYPE_TIMESTAMP: 634 case APR_DBD_TYPE_ZTIMESTAMP: 635 sqlite3_bind_text(stmt, i + 1, values[j], strlen(values[j]), 636 SQLITE_STATIC); 637 break; 638 case APR_DBD_TYPE_BLOB: 639 case APR_DBD_TYPE_CLOB: 640 { 641 char *data = (char*)values[j]; 642 apr_size_t size = *(apr_size_t*)values[++j]; 643 644 sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC); 645 646 /* skip table and column */ 647 j += 2; 648 } 649 break; 650 case APR_DBD_TYPE_NULL: 651 default: 652 sqlite3_bind_null(stmt, i + 1); 653 break; 654 } 655 } 656 657 return; 658} 659 660static int dbd_sqlite3_pbquery(apr_pool_t * pool, apr_dbd_t * sql, 661 int *nrows, apr_dbd_prepared_t * statement, 662 const void **values) 663{ 664 sqlite3_stmt *stmt = statement->stmt; 665 int ret = -1; 666 667 if (sql->trans && sql->trans->errnum) { 668 return sql->trans->errnum; 669 } 670 671 apr_dbd_mutex_lock(); 672 673 ret = sqlite3_reset(stmt); 674 if (ret == SQLITE_OK) { 675 dbd_sqlite3_bbind(statement, values); 676 677 ret = dbd_sqlite3_query_internal(sql, stmt, nrows); 678 679 sqlite3_reset(stmt); 680 } 681 682 apr_dbd_mutex_unlock(); 683 684 if (TXN_NOTICE_ERRORS(sql->trans)) { 685 sql->trans->errnum = ret; 686 } 687 return ret; 688} 689 690static int dbd_sqlite3_pvbquery(apr_pool_t * pool, apr_dbd_t * sql, 691 int *nrows, apr_dbd_prepared_t * statement, 692 va_list args) 693{ 694 const void **values; 695 int i; 696 697 if (sql->trans && sql->trans->errnum) { 698 return sql->trans->errnum; 699 } 700 701 values = apr_palloc(pool, sizeof(*values) * statement->nvals); 702 703 for (i = 0; i < statement->nvals; i++) { 704 values[i] = va_arg(args, const void*); 705 } 706 707 return dbd_sqlite3_pbquery(pool, sql, nrows, statement, values); 708} 709 710static int dbd_sqlite3_pbselect(apr_pool_t * pool, apr_dbd_t * sql, 711 apr_dbd_results_t ** results, 712 apr_dbd_prepared_t * statement, 713 int seek, const void **values) 714{ 715 sqlite3_stmt *stmt = statement->stmt; 716 int ret; 717 718 if (sql->trans && sql->trans->errnum) { 719 return sql->trans->errnum; 720 } 721 722 apr_dbd_mutex_lock(); 723 724 ret = sqlite3_reset(stmt); 725 if (ret == SQLITE_OK) { 726 dbd_sqlite3_bbind(statement, values); 727 728 ret = dbd_sqlite3_select_internal(pool, sql, results, stmt, seek); 729 730 sqlite3_reset(stmt); 731 } 732 733 apr_dbd_mutex_unlock(); 734 735 if (TXN_NOTICE_ERRORS(sql->trans)) { 736 sql->trans->errnum = ret; 737 } 738 return ret; 739} 740 741static int dbd_sqlite3_pvbselect(apr_pool_t * pool, apr_dbd_t * sql, 742 apr_dbd_results_t ** results, 743 apr_dbd_prepared_t * statement, int seek, 744 va_list args) 745{ 746 const void **values; 747 int i; 748 749 if (sql->trans && sql->trans->errnum) { 750 return sql->trans->errnum; 751 } 752 753 values = apr_palloc(pool, sizeof(*values) * statement->nvals); 754 755 for (i = 0; i < statement->nvals; i++) { 756 values[i] = va_arg(args, const void*); 757 } 758 759 return dbd_sqlite3_pbselect(pool, sql, results, statement, seek, values); 760} 761 762static int dbd_sqlite3_start_transaction(apr_pool_t *pool, 763 apr_dbd_t *handle, 764 apr_dbd_transaction_t **trans) 765{ 766 int ret = 0; 767 int nrows = 0; 768 769 ret = dbd_sqlite3_query(handle, &nrows, "BEGIN IMMEDIATE"); 770 if (!*trans) { 771 *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); 772 (*trans)->handle = handle; 773 handle->trans = *trans; 774 } 775 776 return ret; 777} 778 779static int dbd_sqlite3_end_transaction(apr_dbd_transaction_t *trans) 780{ 781 int ret = -1; /* ending transaction that was never started is an error */ 782 int nrows = 0; 783 784 if (trans) { 785 /* rollback on error or explicit rollback request */ 786 if (trans->errnum || TXN_DO_ROLLBACK(trans)) { 787 trans->errnum = 0; 788 ret = dbd_sqlite3_query(trans->handle, &nrows, "ROLLBACK"); 789 } else { 790 ret = dbd_sqlite3_query(trans->handle, &nrows, "COMMIT"); 791 } 792 trans->handle->trans = NULL; 793 } 794 795 return ret; 796} 797 798static int dbd_sqlite3_transaction_mode_get(apr_dbd_transaction_t *trans) 799{ 800 if (!trans) 801 return APR_DBD_TRANSACTION_COMMIT; 802 803 return trans->mode; 804} 805 806static int dbd_sqlite3_transaction_mode_set(apr_dbd_transaction_t *trans, 807 int mode) 808{ 809 if (!trans) 810 return APR_DBD_TRANSACTION_COMMIT; 811 812 return trans->mode = (mode & TXN_MODE_BITS); 813} 814 815static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *pool, const char *params, 816 const char **error) 817{ 818 apr_dbd_t *sql = NULL; 819 sqlite3 *conn = NULL; 820 int sqlres; 821 if (!params) 822 return NULL; 823 sqlres = sqlite3_open(params, &conn); 824 if (sqlres != SQLITE_OK) { 825 if (error) { 826 *error = apr_pstrdup(pool, sqlite3_errmsg(conn)); 827 } 828 sqlite3_close(conn); 829 return NULL; 830 } 831 /* should we register rand or power functions to the sqlite VM? */ 832 sql = apr_pcalloc(pool, sizeof(*sql)); 833 sql->conn = conn; 834 sql->pool = pool; 835 sql->trans = NULL; 836 837 return sql; 838} 839 840static apr_status_t dbd_sqlite3_close(apr_dbd_t *handle) 841{ 842 apr_dbd_prepared_t *prep = handle->prep; 843 844 /* finalize all prepared statements, or we'll get SQLITE_BUSY on close */ 845 while (prep) { 846 sqlite3_finalize(prep->stmt); 847 prep = prep->next; 848 } 849 850 sqlite3_close(handle->conn); 851 return APR_SUCCESS; 852} 853 854static apr_status_t dbd_sqlite3_check_conn(apr_pool_t *pool, 855 apr_dbd_t *handle) 856{ 857 return (handle->conn != NULL) ? APR_SUCCESS : APR_EGENERAL; 858} 859 860static int dbd_sqlite3_select_db(apr_pool_t *pool, apr_dbd_t *handle, 861 const char *name) 862{ 863 return APR_ENOTIMPL; 864} 865 866static void *dbd_sqlite3_native(apr_dbd_t *handle) 867{ 868 return handle->conn; 869} 870 871static int dbd_sqlite3_num_cols(apr_dbd_results_t *res) 872{ 873 return res->sz; 874} 875 876static int dbd_sqlite3_num_tuples(apr_dbd_results_t *res) 877{ 878 return res->tuples; 879} 880 881APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite3_driver = { 882 "sqlite3", 883 NULL, 884 dbd_sqlite3_native, 885 dbd_sqlite3_open, 886 dbd_sqlite3_check_conn, 887 dbd_sqlite3_close, 888 dbd_sqlite3_select_db, 889 dbd_sqlite3_start_transaction, 890 dbd_sqlite3_end_transaction, 891 dbd_sqlite3_query, 892 dbd_sqlite3_select, 893 dbd_sqlite3_num_cols, 894 dbd_sqlite3_num_tuples, 895 dbd_sqlite3_get_row, 896 dbd_sqlite3_get_entry, 897 dbd_sqlite3_error, 898 dbd_sqlite3_escape, 899 dbd_sqlite3_prepare, 900 dbd_sqlite3_pvquery, 901 dbd_sqlite3_pvselect, 902 dbd_sqlite3_pquery, 903 dbd_sqlite3_pselect, 904 dbd_sqlite3_get_name, 905 dbd_sqlite3_transaction_mode_get, 906 dbd_sqlite3_transaction_mode_set, 907 "?", 908 dbd_sqlite3_pvbquery, 909 dbd_sqlite3_pvbselect, 910 dbd_sqlite3_pbquery, 911 dbd_sqlite3_pbselect, 912 dbd_sqlite3_datum_get 913}; 914#endif 915