Add an API to handle caching.
[platal.git] / classes / xdb.php
index 2265e41..c991934 100644 (file)
@@ -86,7 +86,7 @@ class XDB
 
         if ($globals->debug & DEBUG_BT) {
             $explain = array();
-            if (strpos($query, 'FOUND_ROWS()') === false) {
+            if (strpos($query, 'FOUND_ROWS()') === false && strpos($query, 'AUTOCOMMIT') === false) {
                 $res = self::$mysqli->query("EXPLAIN $query");
                 if ($res) {
                     while ($row = $res->fetch_assoc()) {
@@ -194,6 +194,60 @@ 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');
+    }
+
+    public static function commit()
+    {
+        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()
     {
         return new XDBIterator(self::prepare(func_get_args()));