Skip to content

Commit

Permalink
feat: add SQLite3 config synchronous (#9202)
Browse files Browse the repository at this point in the history
* feat: add SQLite3 config synchronous

* add synchronous value validation

* Update system/Database/SQLite3/Connection.php

Co-authored-by: John Paul E. Balandan, CPA <paulbalandan@gmail.com>

* add type for the synchronous property

* use InvalidArgumentException from the CodeIgniter namespace

* fix rector

---------

Co-authored-by: John Paul E. Balandan, CPA <paulbalandan@gmail.com>
  • Loading branch information
michalsn and paulbalandan authored Dec 2, 2024
1 parent c76a68f commit 35c5784
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/Config/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
17 changes: 17 additions & 0 deletions system/Database/SQLite3/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Database\TableName;
use CodeIgniter\Exceptions\InvalidArgumentException;
use Exception;
use SQLite3;
use SQLite3Result;
Expand Down Expand Up @@ -56,6 +57,15 @@ class Connection extends BaseConnection
*/
protected $busyTimeout;

/**
* The setting of the "synchronous" flag
*
* @var int<0, 3>|null flag
*
* @see https://www.sqlite.org/pragma.html#pragma_synchronous
*/
protected ?int $synchronous = null;

/**
* @return void
*/
Expand All @@ -70,6 +80,13 @@ public function initialize()
if (is_int($this->busyTimeout)) {
$this->connID->busyTimeout($this->busyTimeout);
}

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);
}
}

/**
Expand Down
52 changes: 52 additions & 0 deletions tests/system/Database/Live/SQLite3/ConnectTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* 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\Exceptions\InvalidArgumentException;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Database;
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();
}
}
2 changes: 2 additions & 0 deletions user_guide_src/source/changelogs/v4.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,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
=====
Expand Down
2 changes: 2 additions & 0 deletions user_guide_src/source/database/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ Description of Values
See `SQLite documentation <https://www.sqlite.org/pragma.html#pragma_foreign_keys>`_.
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`_.
Expand Down

0 comments on commit 35c5784

Please sign in to comment.