mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
This commit implements GH-8967.
SQLite supports multiple transaction modes. These include:
- DEFERRED (default) only acquires a lock when you start a read/write
- IMMEDIATE acquires a reserved lock
- EXCLUSIVE acquires an exclusive lock (stricter than immediate)
In WAL mode IMMEDIATE and EXCLUSIVE are identical.
One reason for wanting to specify a transaction mode is that SQLite
doesn't respect busy_timeout when a DEFERRED transaction tries to
upgrade a read lock to a write lock. Normally if you try to acquire a
lock and have busy_timeout configured, SQLite will wait for that period
until giving up and erroring out (SQLITE_BUSY). With DEFERRED, if you
have a transaction that first reads and there's a concurrent writer
while it's trying to upgrade to a write lock, you will immediately get
SQLITE_BUSY regardless of your busy_timeout.
Prior to this commit, the only available workarounds were:
- Using $pdo->exec("BEGIN IMMEDIATE TRANSACTION") instead of
$pdo->beginTransaction()
- Doing a dummy write at the start of each transaction so you don't get
stuck with a read lock
Both of those aren't very usable, especially in a framework context
where the user doesn't have complete control over how transactions are
started.
To address that, this commit adds four class constants to Pdo\Sqlite:
- ATTR_TRANSACTION_MODE -- a new attribute
- TRANSACTION_MODE_DEFERRED = 0
- TRANSACTION_MODE_IMMEDIATE = 1
- TRANSACTION_MODE_EXCLUSIVE = 2
These can be used as:
$pdo->setAttribute(
$pdo::ATTR_TRANSACTION_MODE,
$pdo::TRANSACTION_MODE_IMMEDIATE
);
98 lines
2.7 KiB
PHP
98 lines
2.7 KiB
PHP
<?php
|
|
|
|
/** @generate-class-entries */
|
|
|
|
namespace Pdo;
|
|
|
|
/**
|
|
* @strict-properties
|
|
* @not-serializable
|
|
*/
|
|
class Sqlite extends \PDO
|
|
{
|
|
#ifdef SQLITE_DETERMINISTIC
|
|
/** @cvalue SQLITE_DETERMINISTIC */
|
|
public const int DETERMINISTIC = UNKNOWN;
|
|
#endif
|
|
|
|
/** @cvalue SQLITE_OPEN_READONLY */
|
|
public const int OPEN_READONLY = UNKNOWN;
|
|
|
|
/** @cvalue SQLITE_OPEN_READWRITE */
|
|
public const int OPEN_READWRITE = UNKNOWN;
|
|
|
|
/** @cvalue SQLITE_OPEN_CREATE */
|
|
public const int OPEN_CREATE = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_OPEN_FLAGS */
|
|
public const int ATTR_OPEN_FLAGS = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_READONLY_STATEMENT */
|
|
public const int ATTR_READONLY_STATEMENT = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES */
|
|
public const int ATTR_EXTENDED_RESULT_CODES = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_BUSY_STATEMENT */
|
|
public const int ATTR_BUSY_STATEMENT = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_EXPLAIN_STATEMENT */
|
|
public const int ATTR_EXPLAIN_STATEMENT = UNKNOWN;
|
|
|
|
/** @cvalue PDO_SQLITE_ATTR_TRANSACTION_MODE */
|
|
public const int ATTR_TRANSACTION_MODE = UNKNOWN;
|
|
|
|
public const int TRANSACTION_MODE_DEFERRED = 0;
|
|
public const int TRANSACTION_MODE_IMMEDIATE = 1;
|
|
public const int TRANSACTION_MODE_EXCLUSIVE = 2;
|
|
|
|
#if SQLITE_VERSION_NUMBER >= 3043000
|
|
public const int EXPLAIN_MODE_PREPARED = 0;
|
|
public const int EXPLAIN_MODE_EXPLAIN = 1;
|
|
public const int EXPLAIN_MODE_EXPLAIN_QUERY_PLAN = 2;
|
|
#endif
|
|
|
|
/** @cvalue SQLITE_OK */
|
|
public const int OK = UNKNOWN;
|
|
|
|
/* Constants for authorizer return */
|
|
|
|
/** @cvalue SQLITE_DENY */
|
|
public const int DENY = UNKNOWN;
|
|
/** @cvalue SQLITE_IGNORE */
|
|
public const int IGNORE = UNKNOWN;
|
|
|
|
// Registers an aggregating User Defined Function for use in SQL statements
|
|
public function createAggregate(
|
|
string $name,
|
|
callable $step,
|
|
callable $finalize,
|
|
int $numArgs = -1
|
|
): bool {}
|
|
|
|
// Registers a User Defined Function for use as a collating function in SQL statements
|
|
public function createCollation(string $name, callable $callback): bool {}
|
|
|
|
public function createFunction(
|
|
string $function_name,
|
|
callable $callback,
|
|
int $num_args = -1,
|
|
int $flags = 0
|
|
): bool {}
|
|
|
|
#ifndef PDO_SQLITE_OMIT_LOAD_EXTENSION
|
|
public function loadExtension(string $name): void {}
|
|
#endif
|
|
|
|
/** @return resource|false */
|
|
public function openBlob(
|
|
string $table,
|
|
string $column,
|
|
int $rowid,
|
|
?string $dbname = "main",
|
|
int $flags = \Pdo\Sqlite::OPEN_READONLY
|
|
) {}
|
|
|
|
public function setAuthorizer(?callable $callback): void {}
|
|
}
|