From c9de94a0146a758214b994206165814c557cc9b7 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Fri, 26 Jan 2024 16:03:45 +0100 Subject: [PATCH] [10.x] Introducing `beforeStartingTransaction` callback and use it in `LazilyRefreshDatabase` (#49853) * Introduced `beforeStartingTransaction` on `Connection` * Use new `beforeStartingTransaction ` in `LazilyRefreshDatabase` * Fix formatting * formatting --------- Co-authored-by: Taylor Otwell --- .../Database/Concerns/ManagesTransactions.php | 4 ++++ src/Illuminate/Database/Connection.php | 20 +++++++++++++++++++ .../Testing/LazilyRefreshDatabase.php | 7 +++++-- tests/Database/DatabaseConnectionTest.php | 12 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Concerns/ManagesTransactions.php b/src/Illuminate/Database/Concerns/ManagesTransactions.php index 99670cf0949c..df60c61b6d87 100644 --- a/src/Illuminate/Database/Concerns/ManagesTransactions.php +++ b/src/Illuminate/Database/Concerns/ManagesTransactions.php @@ -119,6 +119,10 @@ protected function handleTransactionException(Throwable $e, $currentAttempt, $ma */ public function beginTransaction() { + foreach ($this->beforeStartingTransaction as $callback) { + $callback($this); + } + $this->createTransaction(); $this->transactions++; diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index a46448bb8974..f55adabc57cc 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -182,6 +182,13 @@ class Connection implements ConnectionInterface */ protected $pretending = false; + /** + * All of the callbacks that should be invoked before a transaction is started. + * + * @var \Closure[] + */ + protected $beforeStartingTransaction = []; + /** * All of the callbacks that should be invoked before a query is executed. * @@ -1021,6 +1028,19 @@ public function disconnect() $this->doctrineConnection = null; } + /** + * Register a hook to be run just before a database transaction is started. + * + * @param \Closure $callback + * @return $this + */ + public function beforeStartingTransaction(Closure $callback) + { + $this->beforeStartingTransaction[] = $callback; + + return $this; + } + /** * Register a hook to be run just before a database query is executed. * diff --git a/src/Illuminate/Foundation/Testing/LazilyRefreshDatabase.php b/src/Illuminate/Foundation/Testing/LazilyRefreshDatabase.php index 98204cceab48..83e4546c38d3 100644 --- a/src/Illuminate/Foundation/Testing/LazilyRefreshDatabase.php +++ b/src/Illuminate/Foundation/Testing/LazilyRefreshDatabase.php @@ -17,7 +17,7 @@ public function refreshDatabase() { $database = $this->app->make('db'); - $database->beforeExecuting(function () { + $callback = function () { if (RefreshDatabaseState::$lazilyRefreshed) { return; } @@ -25,7 +25,10 @@ public function refreshDatabase() RefreshDatabaseState::$lazilyRefreshed = true; $this->baseRefreshDatabase(); - }); + }; + + $database->beforeStartingTransaction($callback); + $database->beforeExecuting($callback); $this->beforeApplicationDestroyed(function () { RefreshDatabaseState::$lazilyRefreshed = false; diff --git a/tests/Database/DatabaseConnectionTest.php b/tests/Database/DatabaseConnectionTest.php index 8709e339c226..1b6211386a04 100755 --- a/tests/Database/DatabaseConnectionTest.php +++ b/tests/Database/DatabaseConnectionTest.php @@ -484,6 +484,18 @@ public function testBeforeExecutingHooksCanBeRegistered() $connection->select('foo bar', ['baz']); } + public function testBeforeStartingTransactionHooksCanBeRegistered() + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('The callback was fired'); + + $connection = $this->getMockConnection(); + $connection->beforeStartingTransaction(function () { + throw new Exception('The callback was fired'); + }); + $connection->beginTransaction(); + } + public function testPretendOnlyLogsQueries() { $connection = $this->getMockConnection();