Skip to content

Commit 35c5784

Browse files
feat: add SQLite3 config synchronous (#9202)
* feat: add SQLite3 config synchronous * add synchronous value validation * Update system/Database/SQLite3/Connection.php Co-authored-by: John Paul E. Balandan, CPA <[email protected]> * add type for the synchronous property * use InvalidArgumentException from the CodeIgniter namespace * fix rector --------- Co-authored-by: John Paul E. Balandan, CPA <[email protected]>
1 parent c76a68f commit 35c5784

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

app/Config/Database.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Database extends Config
6565
// 'failover' => [],
6666
// 'foreignKeys' => true,
6767
// 'busyTimeout' => 1000,
68+
// 'synchronous' => null,
6869
// 'dateFormat' => [
6970
// 'date' => 'Y-m-d',
7071
// 'datetime' => 'Y-m-d H:i:s',

system/Database/SQLite3/Connection.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use CodeIgniter\Database\BaseConnection;
1717
use CodeIgniter\Database\Exceptions\DatabaseException;
1818
use CodeIgniter\Database\TableName;
19+
use CodeIgniter\Exceptions\InvalidArgumentException;
1920
use Exception;
2021
use SQLite3;
2122
use SQLite3Result;
@@ -56,6 +57,15 @@ class Connection extends BaseConnection
5657
*/
5758
protected $busyTimeout;
5859

60+
/**
61+
* The setting of the "synchronous" flag
62+
*
63+
* @var int<0, 3>|null flag
64+
*
65+
* @see https://www.sqlite.org/pragma.html#pragma_synchronous
66+
*/
67+
protected ?int $synchronous = null;
68+
5969
/**
6070
* @return void
6171
*/
@@ -70,6 +80,13 @@ public function initialize()
7080
if (is_int($this->busyTimeout)) {
7181
$this->connID->busyTimeout($this->busyTimeout);
7282
}
83+
84+
if (is_int($this->synchronous)) {
85+
if (! in_array($this->synchronous, [0, 1, 2, 3], true)) {
86+
throw new InvalidArgumentException('Invalid synchronous value.');
87+
}
88+
$this->connID->exec('PRAGMA synchronous = ' . $this->synchronous);
89+
}
7390
}
7491

7592
/**
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Database\Live\SQLite3;
15+
16+
use CodeIgniter\Exceptions\InvalidArgumentException;
17+
use CodeIgniter\Test\CIUnitTestCase;
18+
use Config\Database;
19+
use PHPUnit\Framework\Attributes\Group;
20+
21+
/**
22+
* @internal
23+
*/
24+
#[Group('DatabaseLive')]
25+
final class ConnectTest extends CIUnitTestCase
26+
{
27+
protected function setUp(): void
28+
{
29+
parent::setUp();
30+
31+
$this->db = Database::connect($this->DBGroup);
32+
33+
if ($this->db->DBDriver !== 'SQLite3') {
34+
$this->markTestSkipped('This test is only for SQLite3.');
35+
}
36+
}
37+
38+
public function testShowErrorMessageWhenSettingInvalidSynchronous(): void
39+
{
40+
$this->expectException(InvalidArgumentException::class);
41+
$this->expectExceptionMessage('Invalid synchronous value.');
42+
43+
$config = config('Database');
44+
$group = $config->tests;
45+
// Sets invalid synchronous.
46+
$group['synchronous'] = 123;
47+
$db = Database::connect($group);
48+
49+
// Actually connect to DB.
50+
$db->initialize();
51+
}
52+
}

user_guide_src/source/changelogs/v4.6.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ Others
213213
- Added a new configuration ``foundRows`` for MySQLi to use ``MYSQLI_CLIENT_FOUND_ROWS``.
214214
- Added the ``BaseConnection::resetTransStatus()`` method to reset the transaction
215215
status. See :ref:`transactions-resetting-transaction-status` for details.
216+
- SQLite3 has a new Config item ``synchronous`` to adjust how strict SQLite is at flushing
217+
to disk during transactions. Modifying this can be useful if we use journal mode set to ``WAL``.
216218

217219
Model
218220
=====

user_guide_src/source/database/configuration.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ Description of Values
178178
See `SQLite documentation <https://www.sqlite.org/pragma.html#pragma_foreign_keys>`_.
179179
To enforce Foreign Key constraint, set this config item to true.
180180
**busyTimeout** (``SQLite3`` only) milliseconds (int) - Sleeps for a specified amount of time when a table is locked.
181+
**synchronous** (``SQLite3`` only) flag (int) - How strict SQLite will be at flushing to disk during transactions.
182+
Use `null` to stay with the default setting. This can be used since v4.6.0.
181183
**numberNative** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_OPT_INT_AND_FLOAT_NATIVE.
182184
**foundRows** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_CLIENT_FOUND_ROWS.
183185
**dateFormat** The default date/time formats as PHP's `DateTime format`_.

0 commit comments

Comments
 (0)