From c2d91650bd5e8e7f9e2ba005e47934292faaafb0 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 11 Jun 2024 16:08:39 +0700 Subject: [PATCH 1/3] [ticket/17337] Fix mysqli driver is missing transaction begin statement PHPBB-17337 --- phpBB/phpbb/db/driver/mysqli.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index e474b2584e1..6182801da60 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -155,7 +155,9 @@ function _sql_transaction($status = 'begin') switch ($status) { case 'begin': - return @mysqli_autocommit($this->db_connect_id, false); + @mysqli_autocommit($this->db_connect_id, false); + $result = @mysqli_begin_transaction($this->db_connect_id); + return $result; break; case 'commit': From f3460fe9eb308e3cf5e9f8535e997ddfd93d5118 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 23 Jun 2024 23:26:13 +0200 Subject: [PATCH 2/3] [ticket/17337] Extend write tests with simple transaction test PHPBB-17337 --- tests/dbal/write_test.php | 41 +++++++++++++++++++ .../phpbb_database_test_case.php | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/dbal/write_test.php b/tests/dbal/write_test.php index f0093ff869e..6e76e08802e 100644 --- a/tests/dbal/write_test.php +++ b/tests/dbal/write_test.php @@ -73,6 +73,47 @@ public function test_delete() $db->sql_freeresult($result); } + public function test_delete_rollback() + { + $db = $this->new_dbal(); + + $db->sql_transaction('begin'); + + $sql = "DELETE FROM phpbb_config + WHERE config_name = 'config1'"; + $db->sql_query($sql); + + // Rollback and check that nothing was changed + $db->sql_transaction('rollback'); + + $sql = 'SELECT * + FROM phpbb_config'; + $result = $db->sql_query($sql); + $rows = $db->sql_fetchrowset($result); + $db->sql_freeresult($result); + + $this->assertEquals(2, count($rows)); + $this->assertEquals('config1', $rows[0]['config_name']); + + $db->sql_transaction('begin'); + + $sql = "DELETE FROM phpbb_config + WHERE config_name = 'config1'"; + $db->sql_query($sql); + + // Commit and check that data was actually changed + $db->sql_transaction('commit'); + + $sql = 'SELECT * + FROM phpbb_config'; + $result = $db->sql_query($sql); + $rows = $db->sql_fetchrowset($result); + $db->sql_freeresult($result); + + $this->assertEquals(1, count($rows)); + $this->assertEquals('config2', $rows[0]['config_name']); + } + public function test_multiple_insert() { $db = $this->new_dbal(); diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index c46bbe11c38..a7054d56356 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -285,7 +285,7 @@ public function getConnection() return $this->createDefaultDBConnection($manager->get_pdo(), 'testdb'); } - public function new_dbal() + public function new_dbal() : \phpbb\db\driver\driver_interface { $config = $this->get_database_config(); From dd3ebe2b71adca803dce4e89ee9c10e04c9f2e31 Mon Sep 17 00:00:00 2001 From: rxu Date: Mon, 24 Jun 2024 21:07:43 +0700 Subject: [PATCH 3/3] [ticket/17337] Correctly handle transaction test on MyISAM (non-transactional) PHPBB-17337 --- tests/dbal/write_test.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/dbal/write_test.php b/tests/dbal/write_test.php index 6e76e08802e..f94aebd85b3 100644 --- a/tests/dbal/write_test.php +++ b/tests/dbal/write_test.php @@ -77,6 +77,13 @@ public function test_delete_rollback() { $db = $this->new_dbal(); + $is_myisam = false; + if ($db->get_sql_layer() === 'mysqli') + { + $table_status = $db->get_table_status('phpbb_config'); + $is_myisam = isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM'; + } + $db->sql_transaction('begin'); $sql = "DELETE FROM phpbb_config @@ -92,8 +99,21 @@ public function test_delete_rollback() $rows = $db->sql_fetchrowset($result); $db->sql_freeresult($result); - $this->assertEquals(2, count($rows)); - $this->assertEquals('config1', $rows[0]['config_name']); + if (!$is_myisam) + { + $this->assertEquals(2, count($rows)); + $this->assertEquals('config1', $rows[0]['config_name']); + } + else + { + // Rollback does not work on MyISAM + $this->assertEquals(1, count($rows)); + $this->assertEquals('config2', $rows[0]['config_name']); + + // Restore deleted config value on MyISAM + $sql = "INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('config1', 'foo', 0)"; + $db->sql_query($sql); + } $db->sql_transaction('begin');