Take into account PlExportable interface.
[platal.git] / classes / xdb.php
index 28010c9..c991934 100644 (file)
@@ -194,8 +194,13 @@ class XDB
         return self::run($query);
     }
 
+    private static $inTransaction = false;
     public static function startTransaction()
     {
+        if (self::$inTransaction) {
+            throw new XDBException('START TRANSACTION', 'Already in a transaction');
+        }
+        self::$inTransaction = true;
         self::rawExecute('SET AUTOCOMMIT = 0');
         self::rawExecute('START TRANSACTION');
     }
@@ -204,12 +209,43 @@ class XDB
     {
         self::rawExecute('COMMIT');
         self::rawExecute('SET AUTOCOMMIT = 1');
+        self::$inTransaction = false;
     }
 
     public static function rollback()
     {
         self::rawExecute('ROLLBACK');
         self::rawExecute('SET AUTOCOMMIT = 1');
+        self::$inTransaction = false;
+    }
+
+    public static function runTransactionV($callback, array $args)
+    {
+        self::startTransaction();
+        try {
+            if (call_user_func_array($callback, $args)) {
+                self::commit();
+                return true;
+            } else {
+                self::rollback();
+                return false;
+            }
+        } catch (Exception $e) {
+            self::rollback();
+            throw $e;
+        }
+    }
+
+    /** This function takes a callback followed by the arguments to be passed to the callback
+     * as arguments. It starts a transaction and execute the callback. If the callback fails
+     * (return false or raise an exception), the transaction is rollbacked, if the callback
+     * succeeds (return true), the transaction is committed.
+     */
+    public static function runTransaction()
+    {
+        $args = func_get_args();
+        $cb = array_shift($args);
+        return self::runTransactionV($cb, $args);
     }
 
     public static function iterator()