#include <glib.h>
#include "ermetadb.h"
#include "metadata_table.h"
Go to the source code of this file.
Functions | |
G_BEGIN_DECLS int | sql3_execute_query (sqlite3 *db, const char *sql, const metadata_table *parameters, metadata_table **result_table) |
Execute sql query. A convenience wrapper around sql3_prepare_statements(), sql3_execute_statements(), sql3_finalize_statements() for queries that have no parameters. | |
int | sql3_begin_transaction (erMetadb thiz) |
Start a database transaction. Transactions may be nested, as long as the calls to sql3_begin_transaction() and sql3_begin_transaction_readonly() are balanced with calls to sql3_commit_or_rollback. | |
int | sql3_begin_transaction_readonly (erMetadb thiz) |
Start a read-only database transaction. Transactions may be nested, as long as the calls to sql3_begin_transaction() and sql3_begin_transaction_readonly() are balanced with calls to sql3_commit_or_rollback. | |
int | sql3_commit_or_rollback (erMetadb thiz, int err) |
Commit or rollback a database transaction Transactions may be nested, as long as the calls to sql3_begin_transaction() are balanced with calls to sql3_commit_or_rollback. Superfluous calls to sql3_commit_or_rollback are allowed. | |
int | sql3_strcase_compare (void *user_data, int left_len, const void *left_void, int right_len, const void *right_void) |
Compare function to be used in custom collation sequence See documentation on sqlite3_create_collation() for details. |
int sql3_begin_transaction | ( | erMetadb | thiz | ) |
Start a database transaction. Transactions may be nested, as long as the calls to sql3_begin_transaction() and sql3_begin_transaction_readonly() are balanced with calls to sql3_commit_or_rollback.
---------------------------------------------------------------------------
Name : sql3_begin_transaction
[in] | thiz | - erMetadb object on which to start a transaction |
--------------------------------------------------------------------------
Definition at line 614 of file sqlite3_wrapper.c.
References begin_transaction().
Referenced by add_filename(), ermetadb_begin_transaction(), ermetadb_global_remove_folder(), ermetadb_local_create_annotation(), ermetadb_local_remove_application_data(), ermetadb_local_set_annotation(), ermetadb_local_set_application_data(), local_delete_all_data_for_id(), open_sql_database(), and set_file_metadata_impl().
00615 { 00616 return begin_transaction(thiz, FALSE); 00617 }
int sql3_begin_transaction_readonly | ( | erMetadb | thiz | ) |
Start a read-only database transaction. Transactions may be nested, as long as the calls to sql3_begin_transaction() and sql3_begin_transaction_readonly() are balanced with calls to sql3_commit_or_rollback.
---------------------------------------------------------------------------
Name : sql3_begin_transaction_readonly
[in] | thiz | - erMetadb object on which to start a transaction |
--------------------------------------------------------------------------
Definition at line 620 of file sqlite3_wrapper.c.
References begin_transaction().
Referenced by ermetadb_begin_transaction_readonly(), ermetadb_global_get_file(), ermetadb_local_get_annotations(), ermetadb_local_get_application_data(), ermetadb_local_select_annotations(), and open_sql_database().
00621 { 00622 return begin_transaction(thiz, TRUE); 00623 }
int sql3_commit_or_rollback | ( | erMetadb | thiz, | |
int | err | |||
) |
Commit or rollback a database transaction Transactions may be nested, as long as the calls to sql3_begin_transaction() are balanced with calls to sql3_commit_or_rollback. Superfluous calls to sql3_commit_or_rollback are allowed.
---------------------------------------------------------------------------
Name : sql3_commit_or_rollback
[in] | thiz | - erMetadb object on which to end a transaction |
[in] | err | - ER_OK or error code |
--------------------------------------------------------------------------
Definition at line 626 of file sqlite3_wrapper.c.
References BEGIN_RETRY_MS, COMMIT_MAX_RETRIES, ER_OK, ERMETADB_DATABASE_BUSY, ERMETADB_FAIL, ERRORPRINTF, LOGPRINTF, QUERYPRINTF, and WARNPRINTF.
Referenced by add_filename(), ermetadb_close(), ermetadb_end_transaction(), ermetadb_global_get_file(), ermetadb_global_remove_folder(), ermetadb_global_rename_file(), ermetadb_local_create_annotation(), ermetadb_local_get_annotations(), ermetadb_local_get_application_data(), ermetadb_local_remove_application_data(), ermetadb_local_select_annotations(), ermetadb_local_set_annotation(), ermetadb_local_set_application_data(), local_delete_all_data_for_id(), open_sql_database(), and set_file_metadata_impl().
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 // decide whether to commit or rollback 00636 if (err != ER_OK) thiz->do_force_rollback = TRUE; 00637 00638 // never turn an error code into a good one 00639 int ret = err; 00640 if (thiz->transaction_nesting > 0) 00641 { 00642 // decrease transaction nesting level 00643 thiz->transaction_nesting--; 00644 00645 if (thiz->transaction_nesting == 0) 00646 { 00647 const char *sql = NULL; 00648 // decide commit or rollback ... 00649 if ( err == ER_OK && thiz->do_force_rollback == FALSE ) 00650 { 00651 // ok: commit changes to database 00652 sql = "COMMIT;"; 00653 } 00654 else 00655 { 00656 // error: rollback and return original error code 00657 sql = "ROLLBACK;"; 00658 } 00659 QUERYPRINTF("sql [%s]", sql); 00660 00661 // ... and execute it 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 // transaction ended 00671 done = TRUE; 00672 } 00673 else if ( rc == SQLITE_BUSY && --retries_left >= 0 ) 00674 { 00675 // database locked: wait a while then try again 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 // free error message, if any 00694 sqlite3_free(errmsg); 00695 errmsg = NULL; 00696 } 00697 } 00698 } 00699 00700 LOGPRINTF("leave: ret [%d]", ret); 00701 return ret; 00702 }
G_BEGIN_DECLS int sql3_execute_query | ( | sqlite3 * | db, | |
const char * | sql, | |||
const metadata_table * | parameters, | |||
metadata_table ** | result_table | |||
) |
Execute sql query. A convenience wrapper around sql3_prepare_statements(), sql3_execute_statements(), sql3_finalize_statements() for queries that have no parameters.
File Name : sqlite3_wrapper.h
Description: Wrapper layer around the sqlite3 C API Copyright (C) 2008 iRex Technologies B.V. All rights reserved.---------------------------------------------------------------------------
Name : sql3_execute_query
[in] | db | - sqlite database object |
[in] | sql | - SQL statement(s) as text |
[in] | parameters | - metadata_table with parameters (value), or NULL table must have exactly one row |
[in] | result_table | - location to store metadata_table holding query results, or NULL when caller is not interested in query results |
[out] | result_table | - metadata_table holding query results, or NULL when no results First row holds column names and cell values, other rows hold cell values only. |
--------------------------------------------------------------------------
Definition at line 453 of file sqlite3_wrapper.c.
References ER_INVALID_PARAMETER, ER_OK, ERRORPRINTF, metadata_table_dump, metadata_table_free, QUERYPRINTF, sql3_bind_parameters(), sql3_execute_statements(), sql3_finalize_statements(), and sql3_prepare_statements().
Referenced by add_file_ids(), add_filename(), check_database_version(), check_global_database_columns(), check_global_database_tables(), convert_database_01_06(), convert_database_05_06(), delete_entry(), ermetadb_global_get_file(), ermetadb_global_remove_folder(), ermetadb_global_rename_file(), ermetadb_global_select_all(), ermetadb_global_update_size(), ermetadb_global_update_title(), ermetadb_local_create_annotation(), ermetadb_local_get_annotations(), ermetadb_local_get_application_data(), ermetadb_local_remove_annotation(), ermetadb_local_remove_application_data(), ermetadb_local_select_annotations(), ermetadb_local_set_application_data(), find_or_create_filename(), get_global_id(), get_local_id(), global_select_common(), local_delete_all_annotations(), local_delete_all_application_data(), local_delete_entry(), open_sql_database(), set_annotation_impl(), set_file_metadata_impl(), and update_version_number().
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 // clean up 00494 if (statements) 00495 { 00496 sql3_finalize_statements(statements); 00497 statements = NULL; 00498 } 00499 00500 // return result 00501 if (result_table) 00502 { 00503 *result_table = result; 00504 result = NULL; 00505 } 00506 metadata_table_free(result); 00507 return ret; 00508 }
int sql3_strcase_compare | ( | void * | user_data, | |
int | left_len, | |||
const void * | left_void, | |||
int | right_len, | |||
const void * | right_void | |||
) |
Compare function to be used in custom collation sequence See documentation on sqlite3_create_collation() for details.
---------------------------------------------------------------------------
Name : sql3_strcase_cmp
--------------------------------------------------------------------------
Definition at line 706 of file sqlite3_wrapper.c.
References LOGPRINTF, and UNUSED.
Referenced by open_sqlite_database().
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 // empty string sorts at end of list 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 // non-empty string sorts case-insensitive 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 }