280 lines
7.6 KiB
PHP
280 lines
7.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
* The SQLite driver uses PDO. Enable PDO function calls:
|
|
* phpcs:disable WordPress.DB.RestrictedClasses.mysql__PDO
|
|
*/
|
|
|
|
/**
|
|
* For back compatibility with dependencies that use their own loader scripts
|
|
* (e.g., WP CLI SQLite Command), ensure the new PDO-based classes are loaded.
|
|
*/
|
|
require_once __DIR__ . '/class-wp-pdo-mysql-on-sqlite.php';
|
|
require_once __DIR__ . '/class-wp-pdo-proxy-statement.php';
|
|
|
|
/**
|
|
* Deprecated: A proxy of the WP_PDO_MySQL_On_SQLite class preserving legacy API.
|
|
*
|
|
* This is a temporary class to preserve the legacy API for easier transition
|
|
* to the new PDO-based API, developed in the "WP_PDO_MySQL_On_SQLite" class.
|
|
*/
|
|
class WP_SQLite_Driver {
|
|
/**
|
|
* The SQLite engine version.
|
|
*
|
|
* This is a mysqli-like property that is needed to avoid a PHP warning in
|
|
* the WordPress health info. The "WP_Debug_Data::get_wp_database()" method
|
|
* calls "$wpdb->dbh->client_info" - a mysqli-specific abstraction leak.
|
|
*
|
|
* @TODO: This should be fixed in WordPress core.
|
|
*
|
|
* See:
|
|
* https://github.com/WordPress/wordpress-develop/blob/bcdca3f9925f1d3eca7b78d231837c0caf0c8c24/src/wp-admin/includes/class-wp-debug-data.php#L1579
|
|
*
|
|
* @var string
|
|
*/
|
|
public $client_info;
|
|
|
|
/**
|
|
* The MySQL-on-SQLite driver instance.
|
|
*
|
|
* @var WP_PDO_MySQL_On_SQLite
|
|
*/
|
|
private $mysql_on_sqlite_driver;
|
|
|
|
/**
|
|
* Results of the last emulated query.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
private $last_result;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* Set up an SQLite connection and the MySQL-on-SQLite driver.
|
|
*
|
|
* @param WP_SQLite_Connection $connection A SQLite database connection.
|
|
* @param string $database The database name.
|
|
*
|
|
* @throws WP_SQLite_Driver_Exception When the driver initialization fails.
|
|
*/
|
|
public function __construct(
|
|
WP_SQLite_Connection $connection,
|
|
string $database,
|
|
int $mysql_version = 80038
|
|
) {
|
|
$this->mysql_on_sqlite_driver = new WP_PDO_MySQL_On_SQLite(
|
|
sprintf( 'mysql-on-sqlite:dbname=%s', $database ),
|
|
null,
|
|
null,
|
|
array(
|
|
'mysql_version' => $mysql_version,
|
|
'pdo' => $connection->get_pdo(),
|
|
)
|
|
);
|
|
$this->main_db_name = $database;
|
|
$this->client_info = $this->mysql_on_sqlite_driver->client_info;
|
|
|
|
$connection->get_pdo()->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true );
|
|
}
|
|
|
|
/**
|
|
* Get the SQLite connection instance.
|
|
*
|
|
* @return WP_SQLite_Connection
|
|
*/
|
|
public function get_connection(): WP_SQLite_Connection {
|
|
return $this->mysql_on_sqlite_driver->get_connection();
|
|
}
|
|
|
|
/**
|
|
* Get the version of the SQLite engine.
|
|
*
|
|
* @return string SQLite engine version as a string.
|
|
*/
|
|
public function get_sqlite_version(): string {
|
|
return $this->mysql_on_sqlite_driver->get_sqlite_version();
|
|
}
|
|
|
|
/**
|
|
* Get the SQLite driver version saved in the database.
|
|
*
|
|
* The saved driver version corresponds to the latest version of the SQLite
|
|
* driver that was used to initialize and configure the SQLite database.
|
|
*
|
|
* @return string SQLite driver version as a string.
|
|
* @throws PDOException When the query execution fails.
|
|
*/
|
|
public function get_saved_driver_version(): string {
|
|
return $this->mysql_on_sqlite_driver->get_saved_driver_version();
|
|
}
|
|
|
|
/**
|
|
* Check if a specific SQL mode is active.
|
|
*
|
|
* @param string $mode The SQL mode to check.
|
|
* @return bool True if the SQL mode is active, false otherwise.
|
|
*/
|
|
public function is_sql_mode_active( string $mode ): bool {
|
|
return $this->mysql_on_sqlite_driver->is_sql_mode_active( $mode );
|
|
}
|
|
|
|
/**
|
|
* Get the last executed MySQL query.
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function get_last_mysql_query(): ?string {
|
|
return $this->mysql_on_sqlite_driver->get_last_mysql_query();
|
|
}
|
|
|
|
/**
|
|
* Get SQLite queries executed for the last MySQL query.
|
|
*
|
|
* @return array{ sql: string, params: array }[]
|
|
*/
|
|
public function get_last_sqlite_queries(): array {
|
|
return $this->mysql_on_sqlite_driver->get_last_sqlite_queries();
|
|
}
|
|
|
|
/**
|
|
* Get the auto-increment value generated for the last query.
|
|
*
|
|
* @return int|string
|
|
*/
|
|
public function get_insert_id() {
|
|
return $this->mysql_on_sqlite_driver->get_insert_id();
|
|
}
|
|
|
|
/**
|
|
* @param string $query Full SQL statement string.
|
|
* @param int $fetch_mode PDO fetch mode. Default is PDO::FETCH_OBJ.
|
|
* @param array ...$fetch_mode_args Additional fetch mode arguments.
|
|
*
|
|
* @return mixed Return value, depending on the query type.
|
|
*
|
|
* @throws WP_SQLite_Driver_Exception When the query execution fails.
|
|
*/
|
|
public function query( string $query, $fetch_mode = PDO::FETCH_OBJ, ...$fetch_mode_args ) {
|
|
$stmt = $this->mysql_on_sqlite_driver->query( $query, $fetch_mode, ...$fetch_mode_args );
|
|
|
|
if ( $stmt->columnCount() > 0 ) {
|
|
$this->last_result = $stmt->fetchAll( $fetch_mode );
|
|
} else {
|
|
$this->last_result = $stmt->rowCount();
|
|
}
|
|
return $this->last_result;
|
|
}
|
|
|
|
/**
|
|
* Tokenize a MySQL query and initialize a parser.
|
|
*
|
|
* @param string $query The MySQL query to parse.
|
|
* @return WP_MySQL_Parser A parser initialized for the MySQL query.
|
|
*/
|
|
public function create_parser( string $query ): WP_MySQL_Parser {
|
|
return $this->mysql_on_sqlite_driver->create_parser( $query );
|
|
}
|
|
|
|
/**
|
|
* Get results of the last query.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function get_query_results() {
|
|
return $this->last_result;
|
|
}
|
|
|
|
/**
|
|
* Get return value of the last query() function call.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function get_last_return_value() {
|
|
return $this->last_result;
|
|
}
|
|
|
|
/**
|
|
* Get the number of columns returned by the last emulated query.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function get_last_column_count(): int {
|
|
return $this->mysql_on_sqlite_driver->get_last_column_count();
|
|
}
|
|
|
|
/**
|
|
* Get column metadata for results of the last emulated query.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_last_column_meta(): array {
|
|
return $this->mysql_on_sqlite_driver->get_last_column_meta();
|
|
}
|
|
|
|
/**
|
|
* Execute a query in SQLite.
|
|
*
|
|
* @param string $sql The query to execute.
|
|
* @param array $params The query parameters.
|
|
* @throws PDOException When the query execution fails.
|
|
* @return PDOStatement The PDO statement object.
|
|
*/
|
|
public function execute_sqlite_query( string $sql, array $params = array() ): PDOStatement {
|
|
return $this->mysql_on_sqlite_driver->execute_sqlite_query( $sql, $params );
|
|
}
|
|
|
|
/**
|
|
* Begin a new transaction or nested transaction.
|
|
*/
|
|
public function beginTransaction(): void { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
|
$this->mysql_on_sqlite_driver->begin_transaction();
|
|
}
|
|
|
|
/**
|
|
* A temporary alias for back compatibility.
|
|
*
|
|
* @see self::beginTransaction()
|
|
*/
|
|
public function begin_transaction(): void {
|
|
$this->beginTransaction();
|
|
}
|
|
|
|
/**
|
|
* Commit the current transaction or nested transaction.
|
|
*/
|
|
public function commit(): void {
|
|
$this->mysql_on_sqlite_driver->commit();
|
|
}
|
|
|
|
/**
|
|
* Rollback the current transaction or nested transaction.
|
|
*/
|
|
public function rollback(): void {
|
|
$this->mysql_on_sqlite_driver->rollback();
|
|
}
|
|
|
|
/**
|
|
* Proxy also the private property "$main_db_name", as it is used in tests.
|
|
*/
|
|
public function __set( string $name, $value ): void {
|
|
if ( 'main_db_name' === $name ) {
|
|
$closure = function ( string $value ) {
|
|
$this->main_db_name = $value;
|
|
};
|
|
$closure->call( $this->mysql_on_sqlite_driver, $value );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Proxy also this private method, as it is used in tests.
|
|
*/
|
|
private function quote_mysql_utf8_string_literal( string $utf8_literal ): string {
|
|
$closure = function ( string $utf8_literal ) {
|
|
return $this->quote_mysql_utf8_string_literal( $utf8_literal );
|
|
};
|
|
return $closure->call( $this->mysql_on_sqlite_driver, $utf8_literal );
|
|
}
|
|
}
|