1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2012 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@linux.intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #include <glib/gstdio.h>
30 #include "gsignond/gsignond-log.h"
31 #include "gsignond-db-error.h"
32 #include "gsignond-db-sql-database.h"
33 #include "gsignond-db-sql-database-private.h"
36 #define GSIGNOND_DB_SQL_DATABASE_GET_PRIVATE(obj) \
37 (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
38 GSIGNOND_DB_TYPE_SQL_DATABASE, \
39 GSignondDbSqlDatabasePrivate))
41 G_DEFINE_TYPE (GSignondDbSqlDatabase, gsignond_db_sql_database, G_TYPE_OBJECT);
45 _gsignond_db_sql_database_finalize_db (GSignondDbSqlDatabase *self)
47 if (self->priv->begin_statement) {
48 sqlite3_finalize (self->priv->begin_statement);
49 self->priv->begin_statement = NULL;
52 if (self->priv->commit_statement) {
53 sqlite3_finalize (self->priv->commit_statement);
54 self->priv->commit_statement = NULL;
57 if (self->priv->rollback_statement) {
58 sqlite3_finalize (self->priv->rollback_statement);
59 self->priv->rollback_statement = NULL;
64 _gsignond_db_sql_database_is_open (GSignondDbSqlDatabase *self)
66 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
67 return self->priv->db != NULL;
71 void trace_callback (void *s, const char *stmt)
74 DBG ("SQLITE TRACE: %s", stmt);
80 _gsignond_db_sql_database_open (
81 GSignondDbSqlDatabase *self,
82 const gchar *filename,
87 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
88 g_return_val_if_fail (filename != NULL, FALSE);
90 if (_gsignond_db_sql_database_is_open (self)) {
94 ret = sqlite3_open_v2 (filename, &self->priv->db, flags, NULL);
95 if (ret != SQLITE_OK) {
97 DBG ("Cannot open %s DB: %s", filename,
98 sqlite3_errmsg (self->priv->db));
100 gsignond_db_sql_database_update_error_from_db(self);
101 GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->close (self);
104 if (flags & SQLITE_OPEN_CREATE) {
105 if (g_chmod (filename, S_IRUSR | S_IWUSR))
106 WARN ("setting file permissions on %s failed", filename);
109 #ifdef ENABLE_SQL_LOG
110 sqlite3_trace (self->priv->db, trace_callback, NULL);
113 if (!GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->create (self)) {
114 GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->close (self);
121 _gsignond_db_sql_database_close (GSignondDbSqlDatabase *self)
123 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
124 g_return_val_if_fail (self->priv->db != NULL, FALSE);
126 _gsignond_db_sql_database_finalize_db (self);
128 if (sqlite3_close (self->priv->db) != SQLITE_OK) {
129 DBG ("Unable to close db: %s", sqlite3_errmsg (self->priv->db));
130 gsignond_db_sql_database_update_error_from_db(self);
132 self->priv->db = NULL;
133 self->priv->db_version = 0;
139 _prepare_transaction_statement (
140 GSignondDbSqlDatabase *self,
141 sqlite3_stmt **sql_stmt,
142 const gchar *statement)
146 if (G_UNLIKELY (!*sql_stmt)) {
147 ret = sqlite3_prepare_v2 (self->priv->db, statement, -1,
150 sqlite3_reset (*sql_stmt);
157 _gsignond_db_sql_database_finalize (GObject *gobject)
159 GSignondDbSqlDatabase *self = GSIGNOND_DB_SQL_DATABASE (gobject);
161 _gsignond_db_sql_database_finalize_db (self);
163 if (self->priv->db) {
164 sqlite3_close (self->priv->db);
165 self->priv->db = NULL;
168 if (self->priv->last_error) {
169 g_error_free (self->priv->last_error);
170 self->priv->last_error = NULL;
173 /* Chain up to the parent class */
174 G_OBJECT_CLASS (gsignond_db_sql_database_parent_class)->finalize (gobject);
178 gsignond_db_sql_database_class_init (GSignondDbSqlDatabaseClass *klass)
180 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
182 gobject_class->finalize = _gsignond_db_sql_database_finalize;
184 /* pure virtual methods */
185 klass->create = NULL;
188 /* virtual methods */
189 klass->open = _gsignond_db_sql_database_open;
190 klass->close = _gsignond_db_sql_database_close;
191 klass->is_open = _gsignond_db_sql_database_is_open;
193 g_type_class_add_private (klass, sizeof (GSignondDbSqlDatabasePrivate));
197 gsignond_db_sql_database_init (GSignondDbSqlDatabase *self)
199 self->priv = GSIGNOND_DB_SQL_DATABASE_GET_PRIVATE (self);
200 self->priv->last_error = NULL;
201 self->priv->db = NULL;
202 self->priv->db_version = 0;
206 gsignond_db_sql_database_update_error_from_db (GSignondDbSqlDatabase *self)
208 GSignondDbError code;
212 g_return_if_fail (self->priv != NULL);
214 sql_code = sqlite3_errcode (self->priv->db);
220 gsignond_db_sql_database_set_last_error (self, NULL);
223 code = GSIGNOND_DB_ERROR_LOCKED;
226 code = GSIGNOND_DB_ERROR_UNKNOWN;
230 error = g_error_new (GSIGNOND_DB_ERROR,
232 "Database (SQLite) error %d: %s",
233 sqlite3_errcode (self->priv->db),
234 sqlite3_errmsg (self->priv->db));
235 gsignond_db_sql_database_set_last_error (self, error);
239 gsignond_db_sql_database_prepare_transaction_statements (
240 GSignondDbSqlDatabase *self)
244 g_return_val_if_fail (self->priv != NULL, FALSE);
246 ret = _prepare_transaction_statement(self, &(self->priv->begin_statement),
248 if (ret != SQLITE_OK) return ret;
250 ret = _prepare_transaction_statement(self, &(self->priv->commit_statement),
252 if (ret != SQLITE_OK) return ret;
254 ret = _prepare_transaction_statement(self,&(self->priv->rollback_statement),
261 * gsignond_db_sql_database_open:
263 * @self: instance of #GSignondDbSqlDatabase
264 * @filename: db filename
265 * @flags: sqlite3_open_v2 flags for opening db
267 * Opens a connection to DB.
269 * Returns: TRUE if successful, FALSE otherwise.
272 gsignond_db_sql_database_open (
273 GSignondDbSqlDatabase *self,
274 const gchar *filename,
277 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
279 return GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->open (
280 self, filename, flags);
284 * gsignond_db_sql_database_close:
286 * @self: instance of #GSignondDbSqlDatabase
288 * Closes the connection to DB if it is opened already.
290 * Returns: TRUE if successful, FALSE otherwise.
293 gsignond_db_sql_database_close (GSignondDbSqlDatabase *self)
295 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
297 return GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->close (self);
301 * gsignond_db_sql_database_is_open:
303 * @self: instance of #GSignondDbSqlDatabase
305 * Retrieves the connectivity status to database if it is open or not.
307 * Returns: TRUE if there exist a valid connection to database,
311 gsignond_db_sql_database_is_open (GSignondDbSqlDatabase *self)
313 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
315 return GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->is_open (self);
319 * gsignond_db_sql_database_create:
321 * @self: instance of #GSignondDbSqlDatabase
323 * Creates database structure/tables if does not already exist.
325 * Returns: TRUE if successful, FALSE otherwise.
328 gsignond_db_sql_database_create (GSignondDbSqlDatabase *self)
330 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
332 return GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->create (self);
336 * gsignond_db_sql_database_clear:
338 * @self: instance of #GSignondDbSqlDatabase
340 * Clear database data as per needed.
342 * Returns: TRUE if successful, FALSE otherwise.
345 gsignond_db_sql_database_clear (GSignondDbSqlDatabase *self)
347 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
349 return GSIGNOND_DB_SQL_DATABASE_GET_CLASS (self)->clear (self);
353 * gsignond_db_sql_database_prepare_statement:
354 * @self: instance of #GSignondDbSqlDatabase
355 * @query: query to be prepared
357 * Prepares the statement from the query.
359 * Returns: (transfer full) NULL if fails, valid sql statement otherwise.
362 gsignond_db_sql_database_prepare_statement (
363 GSignondDbSqlDatabase *self,
367 sqlite3_stmt *sql_stmt = NULL;
369 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
370 g_return_val_if_fail (self->priv->db != NULL, 0);
372 ret = sqlite3_prepare_v2 (self->priv->db, query, -1, &sql_stmt, NULL);
373 if (ret != SQLITE_OK) {
374 DBG ("statement preparation failed for \"%s\": %s",
375 query, sqlite3_errmsg (self->priv->db));
383 * gsignond_db_sql_database_exec:
384 * @self: instance of #GSignondDbSqlDatabase
385 * @stmts: sql statements to be executed on the database
387 * Executes SQL statements. transaction begin and commit statements should be
388 * explicitly called if needed.
390 * Returns: TRUE if the sql statements executes successfully,
394 gsignond_db_sql_database_exec (
395 GSignondDbSqlDatabase *self,
396 const gchar *statements)
400 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
401 g_return_val_if_fail (self->priv->db != NULL, FALSE);
402 g_return_val_if_fail (statements != NULL, FALSE);
404 /* exec statements */
405 ret = sqlite3_exec (self->priv->db, statements, NULL, NULL, NULL);
406 if (G_UNLIKELY (ret != SQLITE_OK)) {
407 gsignond_db_sql_database_update_error_from_db (self);
415 * gsignond_db_sql_database_query_exec:
416 * @self: instance of #GSignondDbSqlDatabase
417 * @query: query to be executed on the database
418 * @callback: callback to be invoked if not NULL for the result of each row
419 * @userdata: user_data to be relayed back through the callback
421 * Executes an SQL statement, and optionally calls
422 * the callback for every row of the result.
423 * Returns the number of rows fetched.
425 * Returns: 0 if no row is fetched, number of rows fetched otherwise.
428 gsignond_db_sql_database_query_exec (
429 GSignondDbSqlDatabase *self,
431 GSignondDbSqlDatabaseQueryCallback callback,
434 sqlite3_stmt *sql_stmt;
437 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
438 g_return_val_if_fail (self->priv->db != NULL, 0);
440 sql_stmt = gsignond_db_sql_database_prepare_statement(self, query);
442 rows = gsignond_db_sql_database_query_exec_stmt(self, sql_stmt,
450 _gsignond_db_read_string (
454 *string = g_strdup ((const gchar *)sqlite3_column_text (stmt, 0));
459 * gsignond_db_sql_database_query_exec_string:
460 * @self: instance of #GSignondDbSqlDatabase
461 * @query: query to be executed on the database
463 * Executes an SQL statement, and returns the fetched integer from the result.
465 * Returns: (transfer full) string if rows fetched are greater than 0,
469 gsignond_db_sql_database_query_exec_string (
470 GSignondDbSqlDatabase *self,
476 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
477 g_return_val_if_fail (self->priv->db != NULL, 0);
479 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
481 (GSignondDbSqlDatabaseQueryCallback)
482 _gsignond_db_read_string,
485 if (G_UNLIKELY (rows <= 0)) {
493 _gsignond_db_read_strings (
497 *strings = g_list_append (*strings,
498 g_strdup ((const gchar *)sqlite3_column_text (stmt, 0)));
503 * gsignond_db_sql_database_query_exec_string_list:
504 * @self: instance of #GSignondDbSqlDatabase
505 * @query: query to be executed on the database
507 * Executes an SQL statement, and returns the fetched strings from the results
510 * Returns: (transfer full) list if rows fetched are greater than 0,
511 * NULL otherwise. When done with list, it must be freed using
512 * g_list_free_full (list, g_free)
515 gsignond_db_sql_database_query_exec_string_list (
516 GSignondDbSqlDatabase *self,
522 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
523 g_return_val_if_fail (self->priv->db != NULL, 0);
525 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
527 (GSignondDbSqlDatabaseQueryCallback)
528 _gsignond_db_read_strings,
531 if (G_UNLIKELY (rows <= 0)) {
532 g_list_free_full (list, g_free);
539 _gsignond_db_read_string_tuple (
543 g_hash_table_insert(tuples,
544 g_strdup ((const gchar *)sqlite3_column_text (stmt, 0)),
545 g_strdup ((const gchar *)sqlite3_column_text (stmt, 1)));
550 * gsignond_db_sql_database_query_exec_string_tuple:
551 * @self: instance of #GSignondDbSqlDatabase
552 * @query: query to be executed on the database
554 * Executes an SQL statement, and returns the fetched string tuples from
555 * the results into the hash table.
557 * Returns: (transfer full) string tuples if rows fetched are greater than 0,
558 * NULL otherwise. When done with tuples, it must be freed using
559 * g_hash_table_unref (tuples)
562 gsignond_db_sql_database_query_exec_string_tuple (
563 GSignondDbSqlDatabase *self,
566 GHashTable *tuples = NULL;
569 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
570 g_return_val_if_fail (self->priv->db != NULL, 0);
572 tuples = g_hash_table_new_full ((GHashFunc)g_str_hash,
573 (GEqualFunc)g_str_equal,
574 (GDestroyNotify)g_free,
575 (GDestroyNotify)g_free);
577 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
579 (GSignondDbSqlDatabaseQueryCallback)
580 _gsignond_db_read_string_tuple,
583 if (G_UNLIKELY (rows <= 0)) {
584 g_hash_table_destroy (tuples);
591 _gsignond_db_read_int_string_tuple (
596 const gchar *method = NULL;
598 id = sqlite3_column_int (stmt, 0);
599 method = (const gchar *)sqlite3_column_text (stmt, 1);
600 g_hash_table_insert(tuples, GINT_TO_POINTER(id), g_strdup (method));
605 * gsignond_db_sql_database_query_exec_int_string_tuple:
606 * @self: instance of #GSignondDbSqlDatabase
607 * @query: query to be executed on the database
609 * Executes an SQL statement, and returns the fetched int-string tuples from
610 * the results into the hash table.
612 * Returns: (transfer full) string tuples if rows fetched are greater than 0,
616 gsignond_db_sql_database_query_exec_int_string_tuple (
617 GSignondDbSqlDatabase *self,
620 GHashTable *tuples = NULL;
623 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
624 g_return_val_if_fail (self->priv->db != NULL, 0);
626 tuples = g_hash_table_new_full ((GHashFunc)g_direct_hash,
627 (GEqualFunc)g_direct_equal,
628 (GDestroyNotify)NULL,
629 (GDestroyNotify)g_free);
631 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
633 (GSignondDbSqlDatabaseQueryCallback)
634 _gsignond_db_read_int_string_tuple,
637 if (G_UNLIKELY (rows <= 0)) {
638 g_hash_table_destroy (tuples);
645 _gsignond_db_read_int (
649 *data = sqlite3_column_int (stmt, 0);
654 * gsignond_db_sql_database_query_exec_int:
655 * @self: instance of #GSignondDbSqlDatabase
656 * @query: query to be executed on the database
658 * Executes an SQL statement, and returns the fetched integer from the result.
660 * Returns: TRUE if successful, FALSE otherwise.
663 gsignond_db_sql_database_query_exec_int (
664 GSignondDbSqlDatabase *self,
671 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
672 g_return_val_if_fail (self->priv->db != NULL, 0);
674 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
676 (GSignondDbSqlDatabaseQueryCallback)
677 _gsignond_db_read_int,
679 if (G_UNLIKELY (rows <= 0)) {
687 _gsignond_db_read_array (
692 item = sqlite3_column_int (stmt, 0);
693 g_array_append_val (array, item);
698 * gsignond_db_sql_database_query_exec_int_array:
699 * @self: instance of #GSignondDbSqlDatabase
700 * @query: query to be executed on the database
702 * Executes an SQL statement, and returns the fetched integers from the results
705 * Returns: (transfer full) list if rows fetched are greater than 0, NULL otherwise.
708 gsignond_db_sql_database_query_exec_int_array (
709 GSignondDbSqlDatabase *self,
712 GArray *array = NULL;
715 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
716 g_return_val_if_fail (self->priv->db != NULL, 0);
718 array = g_array_new (FALSE, FALSE, sizeof(gint));
719 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
721 (GSignondDbSqlDatabaseQueryCallback)
722 _gsignond_db_read_array,
725 if (G_UNLIKELY (rows <= 0)) {
726 g_array_free (array, TRUE);
733 * gsignond_db_sql_database_query_exec_stmt:
734 * @self: instance of #GSignondDbSqlDatabase
735 * @sql_stmt: (transfer full) sql statement executed on the database
736 * @callback: callback to be invoked if not NULL for the result of each row
737 * @userdata: user_data to be relayed back through the callback
739 * Executes an SQL statement, and optionally calls
740 * the callback for every row of the result.
741 * Returns the number of rows fetched.
743 * Returns: 0 if no row is fetched, number of rows fetched otherwise.
746 gsignond_db_sql_database_query_exec_stmt (
747 GSignondDbSqlDatabase *self,
748 sqlite3_stmt *sql_stmt,
749 GSignondDbSqlDatabaseQueryCallback callback,
755 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
756 g_return_val_if_fail (self->priv->db != NULL, 0);
759 ret = sqlite3_step (sql_stmt);
760 if (ret == SQLITE_ROW) {
761 if (callback && !callback (sql_stmt, userdata)) {
762 /* stop if callback return FALSE */
766 } else if (ret != SQLITE_DONE) {
767 gsignond_db_sql_database_update_error_from_db (self);
768 DBG ("error executing query : %s", sqlite3_errmsg (self->priv->db));
772 } while (ret != SQLITE_DONE);
774 sqlite3_finalize (sql_stmt);
780 * gsignond_db_sql_database_start_transaction:
781 * @self: instance of #GSignondDbSqlDatabase
783 * Starts a transaction.
785 * Returns: TRUE if the transaction starts successfully,
789 gsignond_db_sql_database_start_transaction (GSignondDbSqlDatabase *self)
793 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
794 g_return_val_if_fail (self->priv->db != NULL, FALSE);
796 /* prepare transaction begin, commit and rollback statements */
797 ret = gsignond_db_sql_database_prepare_transaction_statements (self);
798 if (G_UNLIKELY (ret != SQLITE_OK)) {
799 DBG ("Prepare statement failed");
800 gsignond_db_sql_database_update_error_from_db (self);
804 /* begin statement */
805 ret = sqlite3_step (self->priv->begin_statement);
806 if (G_UNLIKELY (ret != SQLITE_DONE)) {
807 DBG ("Begin statement failed");
808 gsignond_db_sql_database_update_error_from_db (self);
815 * gsignond_db_sql_database_commit_transaction:
816 * @self: instance of #GSignondDbSqlDatabase
818 * Runs commit statement.
820 * Returns: TRUE if the transaction is committed successfully,
824 gsignond_db_sql_database_commit_transaction (GSignondDbSqlDatabase *self)
828 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
829 g_return_val_if_fail (self->priv->db != NULL, FALSE);
831 ret = sqlite3_step (self->priv->commit_statement);
832 if (G_UNLIKELY (ret != SQLITE_DONE)) {
833 DBG ("Commit statement failed");
834 gsignond_db_sql_database_update_error_from_db (self);
835 sqlite3_reset (self->priv->commit_statement);
838 sqlite3_reset (self->priv->commit_statement);
844 * gsignond_db_sql_database_rollback_transaction:
845 * @self: instance of #GSignondDbSqlDatabase
847 * Runs rollback statement.
849 * Returns: TRUE if the transaction rolls back successfully,
853 gsignond_db_sql_database_rollback_transaction (GSignondDbSqlDatabase *self)
857 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
858 g_return_val_if_fail (self->priv->db != NULL, FALSE);
860 ret = sqlite3_step (self->priv->rollback_statement);
861 if (G_UNLIKELY (ret != SQLITE_DONE)) {
862 DBG ("Rollback statement failed");
863 gsignond_db_sql_database_update_error_from_db (self);
864 sqlite3_reset (self->priv->rollback_statement);
867 sqlite3_reset (self->priv->rollback_statement);
872 * gsignond_db_sql_database_transaction_exec:
873 * @self: instance of #GSignondDbSqlDatabase
874 * @stmts: sql statements to be executed on the database
876 * Executes SQL statements starting with begin statement, and ending with
877 * commit statement. In case of any failures, statements are rolledback.
879 * Returns: TRUE if the sql statements executes successfully,
883 gsignond_db_sql_database_transaction_exec (
884 GSignondDbSqlDatabase *self,
885 const gchar *statements)
889 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), FALSE);
890 g_return_val_if_fail (self->priv->db != NULL, FALSE);
892 if (!gsignond_db_sql_database_start_transaction (self)) {
896 /* exec statements */
897 ret = sqlite3_exec (self->priv->db, statements, NULL, NULL, NULL);
898 if (G_UNLIKELY (ret != SQLITE_OK)) {
899 gsignond_db_sql_database_update_error_from_db (self);
900 gsignond_db_sql_database_rollback_transaction (self);
904 return gsignond_db_sql_database_commit_transaction (self);
908 * gsignond_db_sql_database_get_db_version:
909 * @self: instance of #GSignondDbDefaultStorage
910 * @query: query to be executed on db to get version
911 * e.g. PRAGMA db_version;
913 * reads the database version from db
917 gsignond_db_sql_database_get_db_version (
918 GSignondDbSqlDatabase *self,
922 sqlite3_stmt *sql_stmt;
925 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), 0);
926 g_return_val_if_fail (self->priv->db != NULL, 0);
928 if (self->priv->db_version > 0) {
929 return self->priv->db_version;
932 ret = sqlite3_prepare_v2 (self->priv->db, query, -1, &sql_stmt, NULL);
934 if (ret == SQLITE_OK) {
935 ret = sqlite3_step(sql_stmt);
936 if (ret == SQLITE_ROW || ret == SQLITE_DONE) {
937 db_version = sqlite3_column_int(sql_stmt, 0);
938 DBG ("database version %d", db_version);
939 self->priv->db_version = db_version;
941 sqlite3_finalize(sql_stmt);
948 * gsignond_db_sql_database_set_last_error:
949 * @self: instance of #GSignondDbDefaultStorage
950 * @error: (transfer full) last occurred #GError
952 * sets the last occurred error
956 gsignond_db_sql_database_set_last_error (
957 GSignondDbSqlDatabase *self,
960 g_return_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self));
961 gsignond_db_sql_database_clear_last_error(self);
962 self->priv->last_error = error;
966 * gsignond_db_sql_database_get_last_error:
967 * @self: instance of #GSignondDbDefaultStorage
969 * retrieves the last occurred error
971 * Returns: last occurred #GError
975 gsignond_db_sql_database_get_last_error (GSignondDbSqlDatabase *self)
977 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), NULL);
978 return self->priv->last_error;
982 * gsignond_db_sql_database_clear_last_error:
983 * @self: instance of #GSignondDbDefaultStorage
985 * clears the last occurred error
989 gsignond_db_sql_database_clear_last_error (GSignondDbSqlDatabase *self)
991 g_return_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self));
992 if (self->priv->last_error != NULL) {
993 g_error_free(self->priv->last_error);
994 self->priv->last_error = NULL;
999 * gsignond_db_sql_database_get_last_insert_rowid:
1000 * @self: instance of #GSignondDbDefaultStorage
1002 * the last inserted row id
1004 * Returns: last inserted rowid
1007 gsignond_db_sql_database_get_last_insert_rowid (GSignondDbSqlDatabase *self)
1009 g_return_val_if_fail (GSIGNOND_DB_IS_SQL_DATABASE (self), -1);
1010 g_return_val_if_fail (self->priv->db != NULL, 0);
1012 return sqlite3_last_insert_rowid (self->priv->db);