00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <glib.h>
00033 #include <sqlite3.h>
00034 #include <sys/types.h>
00035 #include <unistd.h>
00036
00037
00038 #include <liberutils/er_error.h>
00039
00040
00041 #define LOGGING_ON 0
00042 #include "ermetadb_log.h"
00043 #include "ermetadb.h"
00044 #include "ermetadb_error.h"
00045 #include "ermetadb_private.h"
00046 #include "metadata_table.h"
00047 #include "metadata_table_private.h"
00048 #include "sqlite3_wrapper.h"
00049
00050 #define UNUSED(x) (void)(x)
00051
00052
00053
00054
00055
00056
00057 static const int BEGIN_MAX_RETRIES = 20;
00058 static const int BEGIN_RETRY_MS = 250;
00059
00060
00061 static const int COMMIT_MAX_RETRIES = 30;
00062 static const int COMMIT_RETRY_MS = 100;
00063
00064
00065 static const int STEP_MAX_RETRIES = 10;
00066 static const int STEP_RETRY_MS = 100;
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 static void sql3_finalize_statements(GPtrArray *statements)
00083 {
00084 LOGPRINTF("entry");
00085
00086 if (statements)
00087 {
00088 unsigned int i;
00089 for (i = 0 ; i < statements->len ; i++)
00090 {
00091 sqlite3_stmt *stmt = g_ptr_array_index(statements, i);
00092 sqlite3_finalize(stmt);
00093 }
00094 g_ptr_array_free(statements, TRUE);
00095 }
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 static int sql3_prepare_statements (sqlite3 *db, const char *sql, GPtrArray **statements)
00113 {
00114 int ret = ER_OK;
00115 const char *head = NULL;
00116 const char *tail = NULL;
00117 sqlite3_stmt *stmt = NULL;
00118 GPtrArray *stmt_list = NULL;
00119
00120 LOGPRINTF("entry: sql [%s]", sql);
00121
00122 g_return_val_if_fail( db , ER_INVALID_PARAMETER);
00123 g_return_val_if_fail( sql , ER_INVALID_PARAMETER);
00124 g_return_val_if_fail((*sql != '\0' ), ER_INVALID_PARAMETER);
00125 g_return_val_if_fail( statements , ER_INVALID_PARAMETER);
00126 g_return_val_if_fail((*statements == NULL), ER_INVALID_PARAMETER);
00127
00128
00129 gboolean done = FALSE;
00130 for ( done = FALSE, head = sql ; !done ; head = tail )
00131 {
00132 int rc = sqlite3_prepare_v2(db, head, -1, &stmt, &tail);
00133 if (rc != ER_OK)
00134 {
00135 ERRORPRINTF("sqlite error [%d] [%s] on prepare_v2 [%s]", rc, sqlite3_errmsg(db), head);
00136 ret = ERMETADB_FAIL;
00137 done = TRUE;
00138 }
00139 else
00140 {
00141 if (stmt)
00142 {
00143
00144 if (stmt_list == NULL)
00145 {
00146 stmt_list = g_ptr_array_new();
00147 if (stmt_list == NULL)
00148 {
00149 ERRORPRINTF("cannot create GPtrArray");
00150 ret = ER_OUT_OF_MEMORY;
00151 done = TRUE;
00152 }
00153 }
00154 if (stmt_list)
00155 {
00156 g_ptr_array_add(stmt_list, stmt);
00157 }
00158 stmt = NULL;
00159 }
00160
00161 if (*tail == '\0')
00162 {
00163
00164 done = TRUE;
00165 }
00166 }
00167 }
00168
00169
00170 if (ret != ER_OK)
00171 {
00172 if (stmt_list)
00173 {
00174 sql3_finalize_statements(stmt_list);
00175 stmt_list = NULL;
00176 }
00177 }
00178
00179
00180 *statements = stmt_list;
00181 return ret;
00182 }
00183
00184
00185 static void bind_single_statement (void *p1, void *p2)
00186 {
00187 sqlite3_stmt *stmt = (sqlite3_stmt*) p1;
00188 const metadata_table *parameters = (const metadata_table*) p2;
00189
00190 LOGPRINTF("entry: stmt [%p]", stmt);
00191
00192
00193 int n_parms = sqlite3_bind_parameter_count(stmt);
00194
00195
00196 GString *parm_name = g_string_new("");
00197 int parm_idx;
00198 const metadata_cell *parm = NULL;
00199 for (parm_idx = 0 ; parm_idx < n_parms ; parm_idx++)
00200 {
00201
00202 g_string_printf(parm_name, "?%d", parm_idx + 1);
00203
00204
00205 metadata_cell_type parm_type = METADATA_NULL;
00206 if (parameters)
00207 {
00208 parm = metadata_table_get_cell(parameters, parm_idx);
00209 if (parm)
00210 {
00211 parm_type = parm->type;
00212 }
00213 }
00214
00215 int rc;
00216
00217 switch (parm_type)
00218 {
00219 case METADATA_INT64:
00220 rc = sqlite3_bind_int64(stmt, parm_idx + 1, parm->value.v_int64);
00221 break;
00222 case METADATA_DOUBLE:
00223 rc = sqlite3_bind_double(stmt, parm_idx + 1, parm->value.v_double);
00224 break;
00225 case METADATA_TEXT:
00226 rc = sqlite3_bind_text(stmt, parm_idx + 1, parm->value.v_text->str, -1, SQLITE_STATIC);
00227 break;
00228 case METADATA_BLOB:
00229 rc = sqlite3_bind_blob(stmt, parm_idx + 1, parm->value.v_blob.data, parm->value.v_blob.len, SQLITE_STATIC);
00230 break;
00231 default:
00232 rc = sqlite3_bind_null(stmt, parm_idx + 1);
00233 }
00234 if (rc != ER_OK)
00235 {
00236 ERRORPRINTF("sqlite3_bind_xx returns [%d] on stmt [%p]", rc, stmt);
00237 sqlite3_bind_null(stmt, parm_idx + 1);
00238 }
00239 }
00240
00241 g_string_free(parm_name, TRUE);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 int sql3_bind_parameters (GPtrArray *statements, const metadata_table *parameters)
00261 {
00262 g_return_val_if_fail( statements , ER_INVALID_PARAMETER);
00263 g_return_val_if_fail((statements->len > 0), ER_INVALID_PARAMETER);
00264
00265 metadata_table *parms = (metadata_table*) parameters;
00266 g_ptr_array_foreach(statements, bind_single_statement, parms);
00267
00268 return ER_OK;
00269 }
00270
00271
00272 static metadata_table* create_result_table (sqlite3_stmt *stmt)
00273 {
00274 metadata_table *result = metadata_table_new();
00275 g_assert(result);
00276
00277
00278 int n_col = sqlite3_column_count(stmt);
00279 int col;
00280 for (col = 0 ; col < n_col ; col++)
00281 {
00282 const char* name = sqlite3_column_name(stmt, col);
00283 if (name == NULL)
00284 {
00285 ERRORPRINTF("sqlite3_column returns NULL");
00286 }
00287 LOGPRINTF("column [%d] name [%s]", col, name);
00288 metadata_table_add_column(result, name);
00289 }
00290 return result;
00291 }
00292
00293
00294
00295 static int execute_single_statement (sqlite3_stmt *stmt, metadata_table **result_table)
00296 {
00297 int ret = ER_OK;
00298
00299
00300 metadata_table *result = NULL;
00301 int retries_left = STEP_MAX_RETRIES;
00302 gboolean done = FALSE;
00303 while (!done)
00304 {
00305 int step_rc = sqlite3_step(stmt);
00306 switch (step_rc)
00307 {
00308 case SQLITE_ROW:
00309 {
00310 if (result == NULL) result = create_result_table(stmt);
00311
00312
00313 int n_row = metadata_table_n_rows(result);
00314 int n_col = metadata_table_n_columns(result);
00315 int idx = n_row * n_col;
00316 int col;
00317 for (col = 0 ; col < n_col && ret == ER_OK ; col++)
00318 {
00319 sqlite3_value *value = sqlite3_column_value(stmt, col);
00320 int rc = metadata_table_set_value(result, idx, value);
00321 if (rc != ER_OK)
00322 {
00323 ret = rc;
00324 done = TRUE;
00325 }
00326 idx++;
00327 }
00328 retries_left = STEP_MAX_RETRIES;
00329 break;
00330 }
00331 case SQLITE_DONE:
00332 done = TRUE;
00333 break;
00334
00335 case SQLITE_BUSY:
00336 if (--retries_left >= 0)
00337 {
00338
00339 usleep(STEP_RETRY_MS * 1000);
00340 break;
00341 }
00342 else
00343 {
00344
00345 ;
00346 }
00347
00348 default:
00349 ERRORPRINTF("sqlite3_step reports error [%d]", step_rc);
00350 ret = ERMETADB_FAIL;
00351 done = TRUE;
00352 }
00353 }
00354
00355 if (result)
00356 {
00357
00358 if (*result_table)
00359 {
00360 ERRORPRINTF( "Not allowed to have SQL statements produce multiple result sets.\n"
00361 "Second result set discarded:" );
00362 metadata_table_dump(result);
00363 metadata_table_free(result);
00364 ret = ERMETADB_FAIL;
00365 }
00366 else
00367 {
00368 *result_table = result;
00369 }
00370 }
00371
00372 return ret;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 static int sql3_execute_statements(sqlite3 *db, const GPtrArray *statements, metadata_table **result_table)
00394 {
00395 LOGPRINTF("entry");
00396
00397 g_return_val_if_fail( db , ER_INVALID_PARAMETER);
00398 g_return_val_if_fail( statements , ER_INVALID_PARAMETER);
00399 g_return_val_if_fail((statements->len > 0 ), ER_INVALID_PARAMETER);
00400 g_return_val_if_fail( result_table , ER_INVALID_PARAMETER);
00401 g_return_val_if_fail(( result_table == NULL
00402 || *result_table == NULL), ER_INVALID_PARAMETER);
00403
00404
00405 int ret = ER_OK;
00406 unsigned int stmt_idx;
00407 metadata_table *result = NULL;
00408 for ( stmt_idx = 0 ; stmt_idx < statements->len && ret == ER_OK ; stmt_idx++ )
00409 {
00410 sqlite3_stmt *stmt = g_ptr_array_index(statements, stmt_idx);
00411
00412 ret = execute_single_statement(stmt, &result);
00413 if (ret != ER_OK)
00414 {
00415 ERRORPRINTF( "execute_single_statement returns [%d] on stmt_idx [%d], sqlite error [%s]",
00416 ret, stmt_idx, sqlite3_errmsg(db) );
00417 }
00418 }
00419
00420
00421 for (stmt_idx = 0 ; stmt_idx < statements->len ; stmt_idx++)
00422 {
00423 sqlite3_stmt *stmt = g_ptr_array_index(statements, stmt_idx);
00424
00425
00426 int n_parms = sqlite3_bind_parameter_count(stmt);
00427 int parm_idx;
00428 for (parm_idx = 0 ; parm_idx < n_parms ; parm_idx++)
00429 {
00430 sqlite3_bind_null(stmt, parm_idx + 1);
00431 }
00432
00433
00434 sqlite3_reset(stmt);
00435 }
00436
00437
00438 if (ret != ER_OK)
00439 {
00440 metadata_table_free(result);
00441 }
00442
00443 if (result_table)
00444 {
00445 *result_table = result;
00446 result = NULL;
00447 }
00448 metadata_table_free(result);
00449 return ret;
00450 }
00451
00452
00453 int sql3_execute_query(sqlite3 *db, const char *sql, const metadata_table *parameters, metadata_table **result_table)
00454 {
00455 QUERYPRINTF("entry: sql [%s]", sql);
00456 metadata_table_dump(parameters);
00457
00458 g_return_val_if_fail( db , ER_INVALID_PARAMETER);
00459 g_return_val_if_fail( sql , ER_INVALID_PARAMETER);
00460 g_return_val_if_fail(( result_table == NULL
00461 || *result_table == NULL), ER_INVALID_PARAMETER);
00462
00463 int ret = ER_OK;
00464 GPtrArray *statements = NULL;
00465 int rc = sql3_prepare_statements(db, sql, &statements);
00466 if (rc != ER_OK)
00467 {
00468 ERRORPRINTF("sql3_prepare_statements returns [%d] sql [%s]", rc, sql);
00469 ret = rc;
00470 }
00471
00472 if (ret == ER_OK && parameters)
00473 {
00474 rc = sql3_bind_parameters(statements, parameters);
00475 if (rc != ER_OK)
00476 {
00477 ERRORPRINTF("sql3_bind_parameters returns [%d] sql [%s]", rc, sql);
00478 ret = rc;
00479 }
00480 }
00481
00482 metadata_table *result = NULL;
00483 if (ret == ER_OK)
00484 {
00485 rc = sql3_execute_statements(db, statements, &result);
00486 if (rc != ER_OK)
00487 {
00488 ERRORPRINTF("sql3_execute_statements returns [%d] sql [%s]", rc, sql);
00489 ret = rc;
00490 }
00491 }
00492
00493
00494 if (statements)
00495 {
00496 sql3_finalize_statements(statements);
00497 statements = NULL;
00498 }
00499
00500
00501 if (result_table)
00502 {
00503 *result_table = result;
00504 result = NULL;
00505 }
00506 metadata_table_free(result);
00507 return ret;
00508 }
00509
00510
00511 static int begin_transaction(erMetadb thiz, const gboolean is_readonly)
00512 {
00513 int ret = ER_OK;
00514 int rc;
00515 const char *sql = NULL;
00516 char *errmsg = NULL;
00517 int retries_left = BEGIN_MAX_RETRIES;
00518 gboolean done = FALSE;
00519
00520 g_assert(thiz && thiz->database);
00521 g_assert(thiz->transaction_nesting < 100);
00522
00523 sqlite3 *db = thiz->database;
00524
00525 LOGPRINTF( "entry: db [%p] is_readonly [%d] [%d] transaction_nesting [%d]",
00526 db,
00527 is_readonly,
00528 thiz->is_transaction_readonly,
00529 thiz->transaction_nesting );
00530
00531 g_return_val_if_fail(db, ER_INVALID_PARAMETER);
00532
00533
00534
00535 if (thiz->transaction_nesting == 0)
00536 {
00537 thiz->is_transaction_readonly = is_readonly;
00538 thiz->do_force_rollback = FALSE;
00539
00540
00541 if ( is_readonly )
00542 {
00543 sql = "BEGIN DEFERRED;";
00544 }
00545 else
00546 {
00547 sql = "BEGIN IMMEDIATE;";
00548 }
00549 QUERYPRINTF("sql [%s]", sql);
00550 while (!done)
00551 {
00552 rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
00553 if (rc == SQLITE_OK)
00554 {
00555
00556 thiz->transaction_nesting++;
00557 done = TRUE;
00558
00559 }
00560 else if ( rc == SQLITE_BUSY
00561 && --retries_left >= 0 )
00562 {
00563
00564 WARNPRINTF("pid [%ld] waiting for database lock", (long)getpid());
00565 usleep(BEGIN_RETRY_MS * 1000);
00566 }
00567 else
00568 {
00569 ERRORPRINTF("pid [%ld] cannot begin transaction, error [%d] [%s]", (long)getpid(), rc, errmsg);
00570 switch (rc)
00571 {
00572 case SQLITE_BUSY:
00573 ret = ERMETADB_DATABASE_BUSY;
00574 break;
00575 case SQLITE_READONLY:
00576 ret = ER_READONLY;
00577 break;
00578 default:
00579 ret = ERMETADB_FAIL;
00580 }
00581 done = TRUE;
00582 }
00583
00584
00585 sqlite3_free(errmsg);
00586 errmsg = NULL;
00587 }
00588 }
00589 else
00590 {
00591
00592 if ( is_readonly == thiz->is_transaction_readonly )
00593 {
00594
00595 thiz->transaction_nesting++;
00596 }
00597 else if ( is_readonly )
00598 {
00599
00600 thiz->transaction_nesting++;
00601 }
00602 else
00603 {
00604
00605 ret = ER_READONLY;
00606 }
00607 }
00608
00609 if (ret != ER_OK) WARNPRINTF("cannot begin transaction. ret [%d]", ret);
00610 return ret;
00611 }
00612
00613
00614 int sql3_begin_transaction(erMetadb thiz)
00615 {
00616 return begin_transaction(thiz, FALSE);
00617 }
00618
00619
00620 int sql3_begin_transaction_readonly(erMetadb thiz)
00621 {
00622 return begin_transaction(thiz, TRUE);
00623 }
00624
00625
00626 int sql3_commit_or_rollback(erMetadb thiz, int err)
00627 {
00628 g_assert(thiz && thiz->database);
00629
00630 LOGPRINTF( "entry: err [%d] is_readonly [%d] transaction_nesting [%d]",
00631 err,
00632 thiz->is_transaction_readonly,
00633 thiz->transaction_nesting );
00634
00635
00636 if (err != ER_OK) thiz->do_force_rollback = TRUE;
00637
00638
00639 int ret = err;
00640 if (thiz->transaction_nesting > 0)
00641 {
00642
00643 thiz->transaction_nesting--;
00644
00645 if (thiz->transaction_nesting == 0)
00646 {
00647 const char *sql = NULL;
00648
00649 if ( err == ER_OK && thiz->do_force_rollback == FALSE )
00650 {
00651
00652 sql = "COMMIT;";
00653 }
00654 else
00655 {
00656
00657 sql = "ROLLBACK;";
00658 }
00659 QUERYPRINTF("sql [%s]", sql);
00660
00661
00662 gboolean done = FALSE;
00663 int retries_left = COMMIT_MAX_RETRIES;
00664 while (!done)
00665 {
00666 char *errmsg = NULL;
00667 int rc = sqlite3_exec(thiz->database, sql, NULL, NULL, &errmsg);
00668 if (rc == SQLITE_OK)
00669 {
00670
00671 done = TRUE;
00672 }
00673 else if ( rc == SQLITE_BUSY && --retries_left >= 0 )
00674 {
00675
00676 WARNPRINTF("pid [%ld] waiting for database lock, sql [%s]", (long)getpid(), sql);
00677 usleep(BEGIN_RETRY_MS * 1000);
00678 }
00679 else
00680 {
00681 ERRORPRINTF("cannot end transaction, sql [%s] error [%d] [%s]", sql, rc, errmsg);
00682 if (rc == SQLITE_BUSY)
00683 {
00684 ret = ERMETADB_DATABASE_BUSY;
00685 }
00686 else
00687 {
00688 ret = ERMETADB_FAIL;
00689 }
00690 done = TRUE;
00691 }
00692
00693
00694 sqlite3_free(errmsg);
00695 errmsg = NULL;
00696 }
00697 }
00698 }
00699
00700 LOGPRINTF("leave: ret [%d]", ret);
00701 return ret;
00702 }
00703
00704
00705
00706 int sql3_strcase_compare( void *user_data,
00707 int left_len,
00708 const void *left_void,
00709 int right_len,
00710 const void *right_void )
00711 {
00712 UNUSED(user_data);
00713 int ret = 0;
00714 const gchar *left = (gchar*)left_void;
00715 const gchar *right = (gchar*)right_void;
00716
00717 int len = MIN(left_len, right_len);
00718 if (len == 0)
00719 {
00720
00721 if (left_len == right_len)
00722 {
00723 ret = 0;
00724 }
00725 else if (left_len == 0)
00726 {
00727 ret = 1;
00728 }
00729 else
00730 {
00731 ret = -1;
00732 }
00733 }
00734 else
00735 {
00736
00737 ret = g_ascii_strncasecmp(left, right, len);
00738 if (ret == 0)
00739 {
00740 if (left_len < right_len)
00741 {
00742 ret = -1;
00743 }
00744 else
00745 {
00746 ret = 1;
00747 }
00748 }
00749 }
00750
00751 LOGPRINTF("return [%d] left [%.*s] right [%.*s]", ret, left_len, left, right_len, right);
00752 return ret;
00753 }
00754