Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?php

/*
* PDO uses camel case naming, enable non-snake case:
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
*/

class WP_MySQL_On_SQLite_Exception extends PDOException {
/**
* The MySQL-on-SQLite driver that originated the exception.
Expand All @@ -15,19 +20,40 @@ class WP_MySQL_On_SQLite_Exception extends PDOException {
* @param string $message The exception message.
* @param int|string $code The exception code. In PDO, it can be a string with value of SQLSTATE.
* @param Throwable|null $previous The previous throwable used for the exception chaining.
* @param array|null $error_info PDO-style error information.
*/
public function __construct(
WP_MySQL_On_SQLite $driver,
string $message,
$code = 0,
?Throwable $previous = null
?Throwable $previous = null,
?array $error_info = null
) {
parent::__construct( $message, 0, $previous );
$this->code = $code;
$this->driver = $driver;
$this->code = $code;
$this->driver = $driver;
$this->errorInfo = $error_info ?? $this->create_error_info( $message, $code, $previous );
}

public function get_driver(): WP_MySQL_On_SQLite {
return $this->driver;
}

/**
* Create PDO-style error information from an originating exception or from
* the emulated driver error.
*
* @param string $message The exception message.
* @param int|string $code The exception code.
* @param Throwable|null $previous The previous throwable.
* @return array PDO-style error information.
*/
private function create_error_info( string $message, $code, ?Throwable $previous ): array {
if ( $previous instanceof PDOException && is_array( $previous->errorInfo ) ) {
return $previous->errorInfo;
}

$sqlstate = is_string( $code ) && 5 === strlen( $code ) ? $code : 'HY000';
return array( $sqlstate, 1105, $message );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* PDO uses camel case naming, enable non-snake case:
* phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
* phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
*
* PDO uses $class as a variable name, enable it:
* phpcs:disable Universal.NamingConventions.NoReservedKeywordParameterNames.classFound
Expand Down Expand Up @@ -118,7 +119,7 @@ public function fetchAll( $mode = PDO::FETCH_DEFAULT, ...$args ): array {
* - PDO::FETCH_BOUND: bind values to PHP variables, can't be used with fetchAll()
* - PDO::FETCH_FUNC: custom function, only works with fetchAll(), can't be default [1 extra arg]
*/
class WP_MySQL_On_SQLite_Statement extends PDOStatement {
class WP_MySQL_On_SQLite_Statement extends PDOStatement implements IteratorAggregate {
use WP_MySQL_On_SQLite_Statement_PHP_Compat;

/**
Expand All @@ -128,6 +129,20 @@ class WP_MySQL_On_SQLite_Statement extends PDOStatement {
*/
private $statement;

/**
* Resolve MySQL-compatible metadata by column index.
*
* @var callable
*/
private $column_meta_resolver;

/**
* Resolved MySQL-compatible metadata, keyed by column index.
*
* @var array<int, array|false>
*/
private $resolved_column_meta = array();

/**
* The number of affected rows.
*
Expand All @@ -138,15 +153,24 @@ class WP_MySQL_On_SQLite_Statement extends PDOStatement {
/**
* Constructor.
*
* @param PDOStatement $statement The original PDO statement.
* @param int $affected_rows The number of affected rows.
* @param PDOStatement $statement The original PDO statement.
* @param string $query The original MySQL query.
* @param callable $column_meta_resolver Resolves metadata by column index.
* @param int|null $affected_rows The number of affected rows.
*/
public function __construct(
PDOStatement $statement,
string $query,
callable $column_meta_resolver,
?int $affected_rows = null
) {
$this->statement = $statement;
$this->affected_rows = $affected_rows;
$this->statement = $statement;
// Userland can only initialize PDOStatement::$queryString on PHP 8.1+.
if ( PHP_VERSION_ID >= 80100 ) {
$this->queryString = $query;
}
$this->column_meta_resolver = $column_meta_resolver;
$this->affected_rows = $affected_rows;
}

/**
Expand Down Expand Up @@ -228,8 +252,15 @@ public function fetchObject( $class = 'stdClass', $constructorArgs = array() ) {
* @return array|false The column metadata as an associative array,
* or false if the column does not exist.
*/
public function getColumnMeta( $column ): array {
throw new RuntimeException( 'Not implemented' );
#[ReturnTypeWillChange]
public function getColumnMeta( $column ) {
if ( ! array_key_exists( $column, $this->resolved_column_meta ) ) {
$this->resolved_column_meta[ $column ] = call_user_func(
$this->column_meta_resolver,
$column
);
}
return $this->resolved_column_meta[ $column ];
}

/**
Expand All @@ -239,7 +270,7 @@ public function getColumnMeta( $column ): array {
* or null if there is no error.
*/
public function errorCode(): ?string {
throw new RuntimeException( 'Not implemented' );
return $this->statement->errorCode();
}

/**
Expand All @@ -251,7 +282,10 @@ public function errorCode(): ?string {
* 2: Driver-specific error message.
*/
public function errorInfo(): array {
throw new RuntimeException( 'Not implemented' );
if ( '00000' === $this->statement->errorCode() ) {
return array( '00000', null, null );
}
return $this->statement->errorInfo();
}

/**
Expand Down Expand Up @@ -282,7 +316,9 @@ public function setAttribute( $attribute, $value ): bool {
* @return Iterator The iterator for the result set.
*/
public function getIterator(): Iterator {
throw new RuntimeException( 'Not implemented' );
foreach ( $this->statement as $row ) {
yield $row;
}
}

/**
Expand All @@ -291,7 +327,7 @@ public function getIterator(): Iterator {
* @return bool True on success, false on failure.
*/
public function nextRowset(): bool {
throw new RuntimeException( 'Not implemented' );
return $this->statement->nextRowset();
}

/**
Expand All @@ -300,7 +336,7 @@ public function nextRowset(): bool {
* @return bool True on success, false on failure.
*/
public function closeCursor(): bool {
throw new RuntimeException( 'Not implemented' );
return $this->statement->closeCursor();
}

/**
Expand All @@ -313,8 +349,8 @@ public function closeCursor(): bool {
* @param mixed $driverOptions Optional parameters for the driver.
* @return bool True on success, false on failure.
*/
public function bindColumn( $column, &$var, $type = null, $maxLength = null, $driverOptions = null ): bool {
throw new RuntimeException( 'Not implemented' );
public function bindColumn( $column, &$var, $type = PDO::PARAM_STR, $maxLength = 0, $driverOptions = null ): bool {
return $this->statement->bindColumn( $column, $var, $type, $maxLength, $driverOptions );
}

/**
Expand Down Expand Up @@ -351,7 +387,7 @@ public function bindValue( $param, $value, $type = PDO::PARAM_STR ): bool {
* @return bool|null Returns null, or false on failure.
*/
public function debugDumpParams(): ?bool {
throw new RuntimeException( 'Not implemented' );
return $this->statement->debugDumpParams();
}

/**
Expand Down
Loading
Loading