From 1de72e116301a24fc0970d35f3e3f8d3ef13a71a Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 25 Nov 2020 20:51:57 +0100 Subject: [PATCH] added Connection::transaction() (cherry picked from commit 07f994a0b506959182a12754b013dd7b036bdd8b) --- src/Dibi/Connection.php | 17 +++++++++++++++++ src/Dibi/dibi.php | 1 + tests/dibi/Connection.transactions.phpt | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/Dibi/Connection.php b/src/Dibi/Connection.php index acc55b656..1227ad14d 100644 --- a/src/Dibi/Connection.php +++ b/src/Dibi/Connection.php @@ -402,6 +402,23 @@ public function rollback(string $savepoint = null): void } + /** + * @return mixed + */ + public function transaction(callable $callback) + { + $this->begin(); + try { + $res = $callback(); + } catch (\Throwable $e) { + $this->rollback(); + throw $e; + } + $this->commit(); + return $res; + } + + /** * Result set factory. */ diff --git a/src/Dibi/dibi.php b/src/Dibi/dibi.php index 275af6249..d68e4d014 100644 --- a/src/Dibi/dibi.php +++ b/src/Dibi/dibi.php @@ -25,6 +25,7 @@ * @method static void begin(string $savepoint = null) * @method static void commit(string $savepoint = null) * @method static void rollback(string $savepoint = null) + * @method static mixed transaction(callable $callback) * @method static Dibi\Reflection\Database getDatabaseInfo() * @method static Dibi\Fluent command() * @method static Dibi\Fluent select(...$args) diff --git a/tests/dibi/Connection.transactions.phpt b/tests/dibi/Connection.transactions.phpt index 04cfaa354..0a7d5bf83 100644 --- a/tests/dibi/Connection.transactions.phpt +++ b/tests/dibi/Connection.transactions.phpt @@ -48,3 +48,24 @@ $conn->query('INSERT INTO [products]', [ ]); $conn->commit(); Assert::same(4, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle()); + + + +Assert::exception(function () use ($conn) { + $conn->transaction(function () use ($conn) { + $conn->query('INSERT INTO [products]', [ + 'title' => 'Test product', + ]); + throw new Exception('my exception'); + }); +}, \Throwable::class, 'my exception'); + +Assert::same(4, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle()); + +$conn->transaction(function () use ($conn) { + $conn->query('INSERT INTO [products]', [ + 'title' => 'Test product', + ]); +}); + +Assert::same(5, (int) $conn->query('SELECT COUNT(*) FROM [products]')->fetchSingle());