database: Add interface to handle transactions
authorTobias Brunner <tobias@strongswan.org>
Fri, 6 Sep 2013 06:16:39 +0000 (08:16 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 11 Oct 2013 13:16:04 +0000 (15:16 +0200)
src/libstrongswan/database/database.h
src/libstrongswan/plugins/mysql/mysql_database.c
src/libstrongswan/plugins/sqlite/sqlite_database.c

index d46fc3d..77d4da1 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2013 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -102,7 +103,7 @@ struct database_t {
        enumerator_t* (*query)(database_t *this, char *sql, ...);
 
        /**
-        * Execute a query which dows not return rows, such as INSERT.
+        * Execute a query which does not return rows, such as INSERT.
         *
         * @param rowid         pointer to write inserted AUTO_INCREMENT row ID, or NULL
         * @param sql           sql string, containing '?' placeholders
@@ -112,6 +113,36 @@ struct database_t {
        int (*execute)(database_t *this, int *rowid, char *sql, ...);
 
        /**
+        * Start a transaction.
+        *
+        * @note Either commit() or rollback() has to be called to end the
+        * transaction.
+        * @note Transactions are thread-specific. So commit()/rollbak() has to be
+        * called from the same thread.
+        * @note While this method can be called multiple times (commit/rollback
+        * have to be called an equal number of times) real nested transactions are
+        * not supported.  So if any if the "inner" transactions are rolled back
+        * the outer most transaction is rolled back.
+        *
+        * @return                      TRUE on success
+        */
+       bool (*transaction)(database_t *this);
+
+       /**
+        * Commit all changes made during the current transaction.
+        *
+        * @return                      TRUE on success
+        */
+       bool (*commit)(database_t *this);
+
+       /**
+        * Rollback/revert all changes made during the current transaction.
+        *
+        * @return                      TRUE on success
+        */
+       bool (*rollback)(database_t *this);
+
+       /**
         * Get the database implementation type.
         *
         * To allow driver specific SQL or performance optimizations each database
index fdb6fd6..0757c2a 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2013 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -602,6 +603,24 @@ METHOD(database_t, execute, int,
        return affected;
 }
 
+METHOD(database_t, transaction, bool,
+       private_mysql_database_t *this)
+{
+       return FALSE;
+}
+
+METHOD(database_t, commit, bool,
+       private_mysql_database_t *this)
+{
+       return FALSE;
+}
+
+METHOD(database_t, rollback, bool,
+       private_mysql_database_t *this)
+{
+       return FALSE;
+}
+
 METHOD(database_t, get_driver,db_driver_t,
        private_mysql_database_t *this)
 {
@@ -686,6 +705,9 @@ mysql_database_t *mysql_database_create(char *uri)
                        .db = {
                                .query = _query,
                                .execute = _execute,
+                               .transaction = _transaction,
+                               .commit = _commit,
+                               .rollback = _rollback,
                                .get_driver = _get_driver,
                                .destroy = _destroy,
                        },
index 41d45de..6c8b483 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2013 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -280,6 +281,24 @@ METHOD(database_t, execute, int,
        return affected;
 }
 
+METHOD(database_t, transaction, bool,
+       private_sqlite_database_t *this)
+{
+       return FALSE;
+}
+
+METHOD(database_t, commit, bool,
+       private_sqlite_database_t *this)
+{
+       return FALSE;
+}
+
+METHOD(database_t, rollback, bool,
+       private_sqlite_database_t *this)
+{
+       return FALSE;
+}
+
 METHOD(database_t, get_driver, db_driver_t,
        private_sqlite_database_t *this)
 {
@@ -330,6 +349,9 @@ sqlite_database_t *sqlite_database_create(char *uri)
                        .db = {
                                .query = _query,
                                .execute = _execute,
+                               .transaction = _transaction,
+                               .commit = _commit,
+                               .rollback = _rollback,
                                .get_driver = _get_driver,
                                .destroy = _destroy,
                        },