rfc:pdo_driver_specific_subclasses
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:pdo_driver_specific_subclasses [2022/06/21 12:02] – danack | rfc:pdo_driver_specific_subclasses [2024/02/12 14:24] (current) – derick | ||
---|---|---|---|
Line 3: | Line 3: | ||
* Date: 2022-06-20 | * Date: 2022-06-20 | ||
* Author: Danack | * Author: Danack | ||
- | * Status: | + | * Status: |
* First Published at: https:// | * First Published at: https:// | ||
+ | * Target: PHP 8.4 | ||
Line 17: | Line 18: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | The proposal has three parts: | + | The proposal has two parts: |
+ | |||
+ | * Add new subclasses of PDO with driver specific methods. | ||
+ | * Add PDO:: | ||
- | * Add new subclasses of PDO | ||
- | * Add PDO:: | ||
- | * Add DB specific function to those subclasses. | ||
==== Add new subclasses of PDO ==== | ==== Add new subclasses of PDO ==== | ||
- | There will be one subclasse each for the SQLite | + | All of the PDO extensions that are part of the PHP src repository |
+ | |||
+ | Some of these subclasses will expose functionality that exists that is peculiar to that DB, and not present in the generic PDO class. e.g. PdoSqlite:: | ||
+ | |||
+ | |||
+ | <code php> | ||
+ | class PdoDblib extends PDO | ||
+ | { | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code php> | ||
+ | class PdoFirebird extends PDO | ||
+ | { | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code php> | ||
+ | class PdoMySql extends PDO | ||
+ | { | ||
+ | public function getWarningCount(): int {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code php> | ||
+ | class PdoOci extends PDO | ||
+ | { | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code php> | ||
+ | class PdoOdbc extends PDO | ||
+ | { | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code php> | ||
+ | class PdoPgsql extends PDO | ||
+ | { | ||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PDO_PGSQL_ATTR_DISABLE_PREPARES | ||
+ | */ | ||
+ | public const ATTR_DISABLE_PREPARES = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PGSQL_TRANSACTION_IDLE | ||
+ | */ | ||
+ | public const TRANSACTION_IDLE = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PGSQL_TRANSACTION_ACTIVE | ||
+ | */ | ||
+ | public const TRANSACTION_ACTIVE = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PGSQL_TRANSACTION_INTRANS | ||
+ | */ | ||
+ | public const TRANSACTION_INTRANS = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PGSQL_TRANSACTION_INERROR | ||
+ | */ | ||
+ | public const TRANSACTION_INERROR = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname PGSQL_TRANSACTION_UNKNOWN | ||
+ | */ | ||
+ | public const TRANSACTION_UNKNOWN = UNKNOWN; | ||
+ | |||
+ | public function escapeIdentifier(string $input): string {} | ||
+ | |||
+ | public function copyFromArray(string $tableName, array $rows, string $separator = " | ||
+ | |||
+ | public function copyFromFile(string $tableName, string $filename, string $separator = " | ||
+ | |||
+ | public function copyToArray(string $tableName, string $separator = " | ||
+ | |||
+ | public function copyToFile(string $tableName, string $filename, string $separator = " | ||
+ | |||
+ | public function lobCreate(): | ||
+ | |||
+ | // Opens an existing large object stream. Must be called inside a transaction. | ||
+ | /** @return resource|false */ | ||
+ | public function lobOpen(string $oid, string $mode = " | ||
+ | |||
+ | public function lobUnlink(string $oid): bool {} | ||
+ | |||
+ | public function getNotify(int $fetchMode = PDO:: | ||
+ | |||
+ | public function getPid(): int {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | <code php> | ||
+ | class PdoSqlite extends PDO | ||
+ | { | ||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_DETERMINISTIC | ||
+ | */ | ||
+ | public const DETERMINISTIC = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_ATTR_OPEN_FLAGS | ||
+ | */ | ||
+ | public const ATTR_OPEN_FLAGS = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_OPEN_READONLY | ||
+ | */ | ||
+ | public const OPEN_READONLY = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_OPEN_READWRITE | ||
+ | */ | ||
+ | public const OPEN_READWRITE = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_OPEN_CREATE | ||
+ | */ | ||
+ | public const OPEN_CREATE = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname SQLITE_ATTR_READONLY_STATEMENT | ||
+ | */ | ||
+ | public const ATTR_READONLY_STATEMENT = UNKNOWN; | ||
+ | |||
+ | /** | ||
+ | * @var int | ||
+ | * @cname | ||
+ | */ | ||
+ | public const ATTR_EXTENDED_RESULT_CODES = 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 {} | ||
+ | |||
+ | // Whether SQLITE_OMIT_LOAD_EXTENSION is defined or not depends on how | ||
+ | // SQLite was compiled: https:// | ||
+ | #ifndef SQLITE_OMIT_LOAD_EXTENSION | ||
+ | public function loadExtension(string $name): bool {} | ||
+ | #endif | ||
+ | |||
+ | public function openBlob( | ||
+ | string $table, | ||
+ | string $column, | ||
+ | int $rowid, | ||
+ | ?string $dbname = " | ||
+ | int $flags = PdoSqlite:: | ||
+ | ): mixed /* resource|false */ {} | ||
+ | } | ||
+ | </ | ||
- | Each of these subclasses will expose functionality that exists that is peculiar to that DB, and not present in the generic PDO class. e.g. PDOSqlite:: | ||
- | Although there may be DB specific functionality that could be exposed for the other database types that PDO support, this RFC does not intend to expose them. | + | Although there may be DB specific functionality that could be exposed for the other database types that PDO supports, this RFC does not intend to expose them. |
==== Add a way of creating them through PDO static factory method ==== | ==== Add a way of creating them through PDO static factory method ==== | ||
- | Add a static factory method to PDO called connect. During the connect process, the exact type of database being connected to will be checked, and if it is a DB that has a specific sub-class, return that sub-class instead of a generic PDO object | + | Add a static factory method to PDO called connect. During the connect process, the exact type of database being connected to will be checked, and if it is a DB that has a specific sub-class |
<code php> | <code php> | ||
Line 41: | Line 222: | ||
if (connecting to SQLite DB) { | if (connecting to SQLite DB) { | ||
- | return new PDOSqlite(...); | + | return new PdoSqlite(...); |
} | } | ||
Line 55: | Line 236: | ||
<code php> | <code php> | ||
- | $db = new PDOSqlite($dsn, $username, $password, $options); | + | $db = new PdoSqlite($dsn, $username, $password, $options); |
</ | </ | ||
Line 61: | Line 242: | ||
The code will throw an exception if the type of database being connected to isn't of the correct type for the class. | The code will throw an exception if the type of database being connected to isn't of the correct type for the class. | ||
- | ==== Add DB specific function to those subclasses. ==== | ||
+ | ==== Sqlite Extension directory ini setting ==== | ||
+ | The Sqlite3 extension requires users to set an ini setting to allow SQLite extensions to be loaded, presumably from a desire to keep things ' | ||
- | === Postgres === | + | Additionally, |
- | These methods already exist as magic functions on PDO: | + | <code c> |
+ | sqlite3_db_config(db, | ||
+ | </ | ||
- | * PDOPostgres:: | + | is used to temporarily enable extension loading, before loading the extension, which only enables it through the C api, whereas the Sqlite3 extension uses the code: |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | * PDOPostgres:: | + | |
- | === SQLIte === | + | <code c> |
- | + | sqlite3_enable_load_extension(sqlite_handle, | |
- | These functions already exist as magic functions on PDO: | + | </ |
- | + | ||
- | * PDOSQLite:: | + | |
- | * PDOSQLite:: | + | |
- | * PDOSQLite:: | + | |
- | + | ||
- | These will be two new methods | + | |
- | * PDOSqlite:: | + | which affects both the C api and loading extensions through SQL code. |
- | * PDOSqlite:: | + | |
Line 100: | Line 269: | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | PHP 8.2 | + | PHP 8.3 |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
Line 113: | Line 282: | ||
These are the known current issues. | These are the known current issues. | ||
- | ==== Should the sub-classes only be available when support for that DB is compiled in? ==== | ||
- | e.g. should PDOSqlite exist if PHP was compiled without PDO_SQLITE compilted in? Probaby not. | + | ===== Unaffected |
- | ==== Create all DB sub-classes? | + | Everything not PDO |
- | Should all DBs have sub-classes created now, or should they be added when someone | + | ===== Frequently asked questions ===== |
+ | |||
+ | ==== if someone | ||
+ | |||
+ | No. | ||
+ | |||
+ | ===== Future Scope ===== | ||
==== When to deprecate old function on PDO ==== | ==== When to deprecate old function on PDO ==== | ||
- | The method PDO:: | + | The method PDO:: |
- | 8.2 - PDO subclassses become available 9.0 - calls to PDO:: | + | Removing the methods that magically exist or not depending on the specific driver created would save some complication in the PDO code. So although there' |
- | Removing | + | Choosing |
- | ==== PQescapeIdentifier | + | ==== Quoting identifiers |
- | Postgres has a slightly different set of rules for escaping identifiers | + | During the discussion, a point was raised that currently there is no " |
- | ===== Unaffected PHP Functionality ===== | ||
- | Everything not PDO | + | ==== SQLite constants ==== |
- | ===== Future Scope ===== | + | There are SQLite constants that are not currently exposed in the SQLite3 extension including: |
+ | |||
+ | * SQLITE_DIRECTONLY | ||
+ | * SQLITE_INNOCUOUS | ||
+ | * SQLITE_SUBTYPE | ||
+ | |||
+ | I don't intend to add these as I don't understand them. | ||
+ | |||
+ | ==== PdoSqlite aggregations, | ||
+ | |||
+ | The code for these functions has been copied from the Sqlite3 extension. Although SQLite allows creating these with different flags to indicate what character set data should be in, the implementation is hard-coded to use the SQLITE_UTF8 flag. | ||
+ | |||
+ | It would be possible to expose, and allow users to set, the flags of SQLITE_UTF16, | ||
- | This RFC considers adding subclasses for any other PDO database that isn't explicitly listed above as out of scope. People who use a particular database driver and would like to see a subclass that exposes methods peculiar to that database could propose an RFC similar to this one, for that database. | ||
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
Line 146: | Line 330: | ||
Accept the RFC or not. | Accept the RFC or not. | ||
- | ===== Patches and Tests ===== | + | <doodle title="PDO driver specific subclasses" |
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
- | WIP code https:// | + | Voting closes at 2023-07-17T17: |
+ | ===== Patches and Tests ===== | ||
+ | |||
+ | https:// | ||
+ | https:// | ||
===== Implementation ===== | ===== Implementation ===== | ||
- | After the project is implemented, | + | |
- | - the version(s) it was merged into | + | Implemented for PHP 8.4 (https:// |
- | | + | |
- | - a link to the PHP manual entry for the feature | + | |
- | - a link to the language specification section (if any) | + | |
===== References ===== | ===== References ===== | ||
- | A proprosal | + | A proposal |
===== Rejected Features ===== | ===== Rejected Features ===== | ||
Keep this updated with features that were discussed on the mail lists. | Keep this updated with features that were discussed on the mail lists. |
rfc/pdo_driver_specific_subclasses.1655812946.txt.gz · Last modified: 2022/06/21 12:02 by danack