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()) {
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()));