From 3af4da84cb56832018825aa00c4dbaff5a3d529d Mon Sep 17 00:00:00 2001 From: michalsn Date: Wed, 25 Sep 2024 14:05:47 +0200 Subject: [PATCH 1/6] feat: add SQLite3 config synchronous --- app/Config/Database.php | 1 + system/Database/SQLite3/Connection.php | 13 +++++++++++++ user_guide_src/source/changelogs/v4.6.0.rst | 2 ++ user_guide_src/source/database/configuration.rst | 2 ++ 4 files changed, 18 insertions(+) diff --git a/app/Config/Database.php b/app/Config/Database.php index 1b4c66e52e65..29f6f4a14f42 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -65,6 +65,7 @@ class Database extends Config // 'failover' => [], // 'foreignKeys' => true, // 'busyTimeout' => 1000, + // 'synchronous' => null, // 'dateFormat' => [ // 'date' => 'Y-m-d', // 'datetime' => 'Y-m-d H:i:s', diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 03eb3ab130f7..83e1803ed826 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -56,6 +56,15 @@ class Connection extends BaseConnection */ protected $busyTimeout; + /** + * The setting of the "synchronous" flag + * + * @var int|null flag + * + * @see https://www.sqlite.org/pragma.html#pragma_synchronous + */ + protected $synchronous; + /** * @return void */ @@ -70,6 +79,10 @@ public function initialize() if (is_int($this->busyTimeout)) { $this->connID->busyTimeout($this->busyTimeout); } + + if (is_int($this->synchronous)) { + $this->connID->exec('PRAGMA synchronous = ' . $this->synchronous); + } } /** diff --git a/user_guide_src/source/changelogs/v4.6.0.rst b/user_guide_src/source/changelogs/v4.6.0.rst index d3dc4529d512..02f5750d78fa 100644 --- a/user_guide_src/source/changelogs/v4.6.0.rst +++ b/user_guide_src/source/changelogs/v4.6.0.rst @@ -208,6 +208,8 @@ Others - Added a new configuration ``foundRows`` for MySQLi to use ``MYSQLI_CLIENT_FOUND_ROWS``. - Added the ``BaseConnection::resetTransStatus()`` method to reset the transaction status. See :ref:`transactions-resetting-transaction-status` for details. +- SQLite3 has a new Config item ``synchronous`` to adjust how strict SQLite is at flushing + to disk during transactions. Modifying this can be useful if we use journal mode set to ``WAL``. Model ===== diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst index b42317469038..3d523bcbf3d9 100644 --- a/user_guide_src/source/database/configuration.rst +++ b/user_guide_src/source/database/configuration.rst @@ -178,6 +178,8 @@ Description of Values See `SQLite documentation `_. To enforce Foreign Key constraint, set this config item to true. **busyTimeout** (``SQLite3`` only) milliseconds (int) - Sleeps for a specified amount of time when a table is locked. +**synchronous** (``SQLite3`` only) flag (int) - How strict SQLite will be at flushing to disk during transactions. + Use `null` to stay with the default setting. This can be used since v4.6.0. **numberNative** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_OPT_INT_AND_FLOAT_NATIVE. **foundRows** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_CLIENT_FOUND_ROWS. **dateFormat** The default date/time formats as PHP's `DateTime format`_. From 31c5648db1811873b9db311388ceb9d2e7ba9179 Mon Sep 17 00:00:00 2001 From: michalsn Date: Mon, 7 Oct 2024 07:44:21 +0200 Subject: [PATCH 2/6] add synchronous value validation --- system/Database/SQLite3/Connection.php | 4 ++ .../Database/Live/SQLite3/ConnectTest.php | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/system/Database/Live/SQLite3/ConnectTest.php diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 83e1803ed826..06a8f1911819 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -17,6 +17,7 @@ use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\TableName; use Exception; +use InvalidArgumentException; use SQLite3; use SQLite3Result; use stdClass; @@ -81,6 +82,9 @@ public function initialize() } if (is_int($this->synchronous)) { + if (! in_array($this->synchronous, [0, 1, 2, 3], true)) { + throw new InvalidArgumentException('Invalid synchronous value.'); + } $this->connID->exec('PRAGMA synchronous = ' . $this->synchronous); } } diff --git a/tests/system/Database/Live/SQLite3/ConnectTest.php b/tests/system/Database/Live/SQLite3/ConnectTest.php new file mode 100644 index 000000000000..e14e3acb1add --- /dev/null +++ b/tests/system/Database/Live/SQLite3/ConnectTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Database\Live\SQLite3; + +use CodeIgniter\Test\CIUnitTestCase; +use Config\Database; +use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Group; + +/** + * @internal + */ +#[Group('DatabaseLive')] +final class ConnectTest extends CIUnitTestCase +{ + protected function setUp(): void + { + parent::setUp(); + + $this->db = Database::connect($this->DBGroup); + + if ($this->db->DBDriver !== 'SQLite3') { + $this->markTestSkipped('This test is only for SQLite3.'); + } + } + + public function testShowErrorMessageWhenSettingInvalidSynchronous(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid synchronous value.'); + + $config = config('Database'); + $group = $config->tests; + // Sets invalid synchronous. + $group['synchronous'] = 123; + $db = Database::connect($group); + + // Actually connect to DB. + $db->initialize(); + } +} From 8c4e5fd61fed40e5358f99e40c09b0ec7c2661b9 Mon Sep 17 00:00:00 2001 From: Michal Sniatala Date: Sun, 1 Dec 2024 19:38:17 +0100 Subject: [PATCH 3/6] Update system/Database/SQLite3/Connection.php Co-authored-by: John Paul E. Balandan, CPA --- system/Database/SQLite3/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 06a8f1911819..15042452f4e6 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -60,7 +60,7 @@ class Connection extends BaseConnection /** * The setting of the "synchronous" flag * - * @var int|null flag + * @var int<0, 3>|null flag * * @see https://www.sqlite.org/pragma.html#pragma_synchronous */ From 5cbd51eb8ff49c41bc690100329253bfa1c9f6f7 Mon Sep 17 00:00:00 2001 From: michalsn Date: Sun, 1 Dec 2024 19:44:39 +0100 Subject: [PATCH 4/6] add type for the synchronous property --- system/Database/SQLite3/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 15042452f4e6..79a07a0eb710 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -64,7 +64,7 @@ class Connection extends BaseConnection * * @see https://www.sqlite.org/pragma.html#pragma_synchronous */ - protected $synchronous; + protected ?int $synchronous; /** * @return void From 5580ef88e684ad5964c4d08b3d45f0a5a8d602ce Mon Sep 17 00:00:00 2001 From: michalsn Date: Sun, 1 Dec 2024 19:45:23 +0100 Subject: [PATCH 5/6] use InvalidArgumentException from the CodeIgniter namespace --- system/Database/SQLite3/Connection.php | 2 +- tests/system/Database/Live/SQLite3/ConnectTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 79a07a0eb710..77fac4b61099 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -16,8 +16,8 @@ use CodeIgniter\Database\BaseConnection; use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\TableName; +use CodeIgniter\Exceptions\InvalidArgumentException; use Exception; -use InvalidArgumentException; use SQLite3; use SQLite3Result; use stdClass; diff --git a/tests/system/Database/Live/SQLite3/ConnectTest.php b/tests/system/Database/Live/SQLite3/ConnectTest.php index e14e3acb1add..17871de81bf1 100644 --- a/tests/system/Database/Live/SQLite3/ConnectTest.php +++ b/tests/system/Database/Live/SQLite3/ConnectTest.php @@ -13,9 +13,9 @@ namespace CodeIgniter\Database\Live\SQLite3; +use CodeIgniter\Exceptions\InvalidArgumentException; use CodeIgniter\Test\CIUnitTestCase; use Config\Database; -use InvalidArgumentException; use PHPUnit\Framework\Attributes\Group; /** From 6e2b333531936f3aaebdb15c443c870c23fbae0b Mon Sep 17 00:00:00 2001 From: michalsn Date: Sun, 1 Dec 2024 19:49:07 +0100 Subject: [PATCH 6/6] fix rector --- system/Database/SQLite3/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 77fac4b61099..df6229d632d8 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -64,7 +64,7 @@ class Connection extends BaseConnection * * @see https://www.sqlite.org/pragma.html#pragma_synchronous */ - protected ?int $synchronous; + protected ?int $synchronous = null; /** * @return void