diff --git a/src/Container/AdapterFactory.php b/src/Container/AdapterFactory.php index 016898d..5e07601 100644 --- a/src/Container/AdapterFactory.php +++ b/src/Container/AdapterFactory.php @@ -6,6 +6,7 @@ use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Adapter\Driver\DriverInterface; +use Laminas\Db\Adapter\Exception\RuntimeException; use Laminas\Db\Adapter\Mysql\Adapter; use Laminas\Db\Adapter\Platform\PlatformInterface; use Laminas\Db\Adapter\Profiler\ProfilerInterface; @@ -19,8 +20,19 @@ public function __invoke(ContainerInterface $container): AdapterInterface { /** @var AdapterManager $adapterManager */ $adapterManager = $container->get(AdapterManager::class); + /** @var array $config */ + $config = $container->get('config'); + if (! isset($config['db']['driver'])) { + throw new RuntimeException('Database driver configuration is missing.'); + } + if (! $adapterManager->has($config['db']['driver'])) { + throw new RuntimeException(sprintf( + 'Database driver "%s" is not registered in the adapter manager.', + $config['db']['driver'] + )); + } return new Adapter( - $adapterManager->get(DriverInterface::class), + $adapterManager->get($config['db']['driver']), $adapterManager->get(PlatformInterface::class), $adapterManager->get(ResultSetInterface::class), $adapterManager->get(ProfilerInterface::class) diff --git a/src/Container/AdapterManagerDelegator.php b/src/Container/AdapterManagerDelegator.php index e270d6d..fca4845 100644 --- a/src/Container/AdapterManagerDelegator.php +++ b/src/Container/AdapterManagerDelegator.php @@ -5,9 +5,11 @@ namespace Laminas\Db\Adapter\Mysql\Container; use Laminas\Db\Adapter\AdapterInterface; -use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\DriverInterface; -use Laminas\Db\Adapter\Driver\ResultInterface; +use Laminas\Db\Adapter\Driver\PdoDriverInterface; +use Laminas\Db\Adapter\Driver\Pdo\Result; +use Laminas\Db\Adapter\Driver\Pdo\Statement as PdoStatement; +use Laminas\Db\Adapter\Mysql\Driver; use Laminas\Db\Adapter\Platform\PlatformInterface; use Laminas\Db\Adapter\Profiler; use Laminas\Db\Container\AdapterManager; @@ -27,17 +29,32 @@ public function __invoke( $adapterManager = $callback(); $adapterManager->configure([ 'aliases' => [ + 'MySqli' => Driver\Mysqli\Mysqli::class, + 'MySQLi' => Driver\Mysqli\Mysqli::class, + 'mysqli' => Driver\Mysqli\Mysqli::class, + 'Pdo_Mysql' => Driver\Pdo\Pdo::class, + 'pdo_mysql' => Driver\Pdo\Pdo::class, + 'pdomysql' => Driver\Pdo\Pdo::class, + 'pdodriver' => Driver\Pdo\Pdo::class, + 'pdo' => Driver\Pdo\Pdo::class, + DriverInterface::class => Driver\Mysqli\Mysqli::class, + PdoDriverInterface::class => Driver\Pdo\Pdo::class, Profiler\ProfilerInterface::class => Profiler\Profiler::class, ResultSet\ResultSetInterface::class => ResultSet\ResultSet::class, ], 'factories' => [ - AdapterInterface::class => AdapterFactory::class, - ConnectionInterface::class => ConnectionInterfaceFactory::class, - DriverInterface::class => DriverInterfaceFactory::class, - PlatformInterface::class => PlatformInterfaceFactory::class, - Profiler\Profiler::class => InvokableFactory::class, - ResultInterface::class => ResultInterfaceFactory::class, - ResultSet\ResultSet::class => InvokableFactory::class, + AdapterInterface::class => AdapterFactory::class, + Driver\Mysqli\Mysqli::class => MysqliDriverFactory::class, + Driver\Mysqli\Connection::class => MysqliConnectionFactory::class, + Driver\Mysqli\Result::class => MysqliResultFactory::class, + Driver\Mysqli\Statement::class => MysqliStatementFactory::class, + Driver\Pdo\Pdo::class => PdoDriverFactory::class, + Driver\Pdo\Connection::class => PdoConnectionFactory::class, + Result::class => PdoResultFactory::class, + PdoStatement::class => PdoStatementFactory::class, + PlatformInterface::class => PlatformInterfaceFactory::class, + Profiler\Profiler::class => InvokableFactory::class, + ResultSet\ResultSet::class => InvokableFactory::class, ], ]); diff --git a/src/Container/ConnectionInterfaceFactory.php b/src/Container/ConnectionInterfaceFactory.php deleted file mode 100644 index 1469fa5..0000000 --- a/src/Container/ConnectionInterfaceFactory.php +++ /dev/null @@ -1,20 +0,0 @@ -get(AdapterManager::class); - return $this->getConnection($adapterManager); - } -} diff --git a/src/Container/InterfaceFactoryTrait.php b/src/Container/InterfaceFactoryTrait.php index 056a68f..0a7f457 100644 --- a/src/Container/InterfaceFactoryTrait.php +++ b/src/Container/InterfaceFactoryTrait.php @@ -36,9 +36,9 @@ private function getDriver(AdapterManager $adapterManager): DriverInterface $adapterManager->get(ConnectionInterface::class) ); } - return new Driver\Mysqli\Mysqli( - $adapterManager->get(ConnectionInterface::class) - ); + // return new Driver\Mysqli\Mysqli( + // $adapterManager->get(ConnectionInterface::class) + // ); } private function getResult(AdapterManager $adapterManager): ResultInterface diff --git a/src/Container/MysqliConnectionFactory.php b/src/Container/MysqliConnectionFactory.php new file mode 100644 index 0000000..b06d3b3 --- /dev/null +++ b/src/Container/MysqliConnectionFactory.php @@ -0,0 +1,19 @@ +get('config')['db']['connection'] ?? []; + + return new Connection($dbConfig); + } +} diff --git a/src/Container/DriverInterfaceFactory.php b/src/Container/MysqliDriverFactory.php similarity index 51% rename from src/Container/DriverInterfaceFactory.php rename to src/Container/MysqliDriverFactory.php index 9cfda7a..88cb1fa 100644 --- a/src/Container/DriverInterfaceFactory.php +++ b/src/Container/MysqliDriverFactory.php @@ -5,17 +5,22 @@ namespace Laminas\Db\Adapter\Mysql\Container; use Laminas\Db\Adapter\Driver\DriverInterface; +use Laminas\Db\Adapter\Mysql\Driver\Mysqli; use Laminas\Db\Container\AdapterManager; use Psr\Container\ContainerInterface; -final class DriverInterfaceFactory +final class MysqliDriverFactory { - use InterfaceFactoryTrait; - public function __invoke(ContainerInterface $container): DriverInterface { /** @var AdapterManager $adapterManager */ $adapterManager = $container->get(AdapterManager::class); - return $this->getDriver($adapterManager); + $options = $container->get('config')['db']['options'] ?? []; + return new Mysqli\Mysqli( + $adapterManager->get(Mysqli\Connection::class), + $adapterManager->get(Mysqli\Statement::class), + $adapterManager->get(Mysqli\Result::class), + $options + ); } } diff --git a/src/Container/MysqliResultFactory.php b/src/Container/MysqliResultFactory.php new file mode 100644 index 0000000..823e413 --- /dev/null +++ b/src/Container/MysqliResultFactory.php @@ -0,0 +1,17 @@ +get('config')['db']['options']['buffer_results'] ?? false; + return new Statement($bufferResults); + } +} diff --git a/src/Container/PdoConnectionFactory.php b/src/Container/PdoConnectionFactory.php new file mode 100644 index 0000000..680522f --- /dev/null +++ b/src/Container/PdoConnectionFactory.php @@ -0,0 +1,17 @@ +get('config')['db']['connection'] ?? []; + return new Connection($dbConfig); + } +} diff --git a/src/Container/PdoDriverFactory.php b/src/Container/PdoDriverFactory.php new file mode 100644 index 0000000..bfe255b --- /dev/null +++ b/src/Container/PdoDriverFactory.php @@ -0,0 +1,10 @@ +get(AdapterManager::class); - return $this->getResult($adapterManager); - } -} diff --git a/src/Driver/Mysqli/Mysqli.php b/src/Driver/Mysqli/Mysqli.php index 3b867ad..7de29c9 100644 --- a/src/Driver/Mysqli/Mysqli.php +++ b/src/Driver/Mysqli/Mysqli.php @@ -32,20 +32,22 @@ class Mysqli implements DriverInterface, ProfilerAwareInterface ]; public function __construct( - protected ConnectionInterface|\mysqli|array $connection, - protected ?StatementInterface $statementPrototype = null, - protected ?ResultInterface $resultPrototype = null, + protected readonly ConnectionInterface&Connection $connection, + protected readonly StatementInterface&Statement $statementPrototype, + protected readonly ResultInterface $resultPrototype, array $options = [] ) { - if (! $connection instanceof Connection) { - $connection = new Connection($connection); - } + + $this->checkEnvironment(); $options = array_intersect_key(array_merge($this->options, $options), $this->options); - $this->registerConnection($connection); - $this->registerStatementPrototype($statementPrototype ?: new Statement($options['buffer_results'])); - $this->registerResultPrototype($resultPrototype ?: new Result()); + if ($this->connection instanceof DriverAwareInterface) { + $this->connection->setDriver($this); + } + if ($this->statementPrototype instanceof DriverAwareInterface) { + $this->statementPrototype->setDriver($this); + } } /** @@ -72,50 +74,22 @@ public function getProfiler(): ?ProfilerInterface * Register connection * * @return $this Provides a fluent interface + * @deprecated as of 3.0.0, this method is no longer used. */ public function registerConnection(ConnectionInterface $connection): DriverInterface { - $this->connection = $connection; - if ($this->connection instanceof DriverAwareInterface) { - $this->connection->setDriver($this); - } - return $this; - } - - /** - * Register statement prototype - */ - public function registerStatementPrototype(StatementInterface $statementPrototype): static - { - $this->statementPrototype = $statementPrototype; - if ($this->statementPrototype instanceof DriverAwareInterface) { - $this->statementPrototype->setDriver($this); - } return $this; } /** * Get statement prototype - * - * @return null|Statement */ - public function getStatementPrototype() + public function getStatementPrototype(): StatementInterface&Statement { return $this->statementPrototype; } - /** - * Register result prototype - */ - public function registerResultPrototype(Result $resultPrototype) - { - $this->resultPrototype = $resultPrototype; - } - - /** - * @return null|Result - */ - public function getResultPrototype() + public function getResultPrototype(): ResultInterface&Result { return $this->resultPrototype; } @@ -124,7 +98,6 @@ public function getResultPrototype() * Check environment * * @throws Exception\RuntimeException - * @return void */ public function checkEnvironment(): bool { @@ -136,7 +109,7 @@ public function checkEnvironment(): bool return true; } - public function getConnection(): ConnectionInterface + public function getConnection(): ConnectionInterface&Connection { return $this->connection; } @@ -145,9 +118,8 @@ public function getConnection(): ConnectionInterface * Create statement * * @param string $sqlOrResource - * @return Statement */ - public function createStatement($sqlOrResource = null): StatementInterface + public function createStatement($sqlOrResource = null): StatementInterface&Statement { /** * @todo Resource tracking @@ -166,7 +138,9 @@ public function createStatement($sqlOrResource = null): StatementInterface if (! $this->connection->isConnected()) { $this->connection->connect(); } - $statement->initialize($this->connection->getResource()); + /** @var \mysqli $resource */ + $resource = $this->connection->getResource(); + $statement->initialize($resource); } return $statement; } @@ -176,10 +150,10 @@ public function createStatement($sqlOrResource = null): StatementInterface * * @param resource $resource * @param null|bool $isBuffered - * @return Result */ - public function createResult($resource, $isBuffered = null): ResultInterface + public function createResult($resource, $isBuffered = null): ResultInterface&Result { + /** @var Result $result */ $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered); return $result; diff --git a/src/Driver/Pdo/Connection.php b/src/Driver/Pdo/Connection.php index 757e59f..65dbccb 100644 --- a/src/Driver/Pdo/Connection.php +++ b/src/Driver/Pdo/Connection.php @@ -4,6 +4,7 @@ namespace Laminas\Db\Adapter\Mysql\Driver\Pdo; +use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\Pdo\AbstractPdoConnection; use Laminas\Db\Adapter\Exception; use Override; @@ -13,9 +14,8 @@ use function array_diff_key; use function implode; use function is_int; -use function str_replace; +use function is_string; use function strtolower; -use function substr; class Connection extends AbstractPdoConnection { @@ -45,7 +45,7 @@ public function getCurrentSchema(): string|bool * @throws Exception\RuntimeException */ #[Override] - public function connect(): static + public function connect(): ConnectionInterface { if ($this->resource) { return $this; @@ -56,17 +56,7 @@ public function connect(): static foreach ($this->connectionParameters as $key => $value) { switch (strtolower($key)) { case 'dsn': - $dsn = $value; - break; - case 'driver': - $value = strtolower((string) $value); - if (str_starts_with($value, 'pdo')) { - $pdoDriver = str_replace(['-', '_', ' '], '', $value); - $pdoDriver = substr($pdoDriver, 3) ?: ''; - } - break; - case 'pdodriver': - $pdoDriver = (string) $value; + $dsn = (string) $value; break; case 'user': case 'username': @@ -97,7 +87,6 @@ public function connect(): static $version = (string) $value; break; case 'driver_options': - case 'options': $value = (array) $value; $options = array_diff_key($options, $value) + $value; break; @@ -114,7 +103,7 @@ public function connect(): static ); } - if (! isset($dsn) && isset($pdoDriver)) { + if (! isset($dsn)) { $dsn = []; if (isset($database)) { $dsn[] = "dbname={$database}"; @@ -125,7 +114,7 @@ public function connect(): static if (isset($port)) { $dsn[] = "port={$port}"; } - if (isset($charset) && $pdoDriver !== 'pgsql') { + if (isset($charset)) { $dsn[] = "charset={$charset}"; } if (isset($unixSocket)) { @@ -134,8 +123,10 @@ public function connect(): static if (isset($version)) { $dsn[] = "version={$version}"; } - $dsn = $pdoDriver . ':' . implode(';', $dsn); - } elseif (! isset($dsn)) { + $dsn = 'mysql:' . implode(';', $dsn); + } + + if (! is_string($dsn)) { throw new Exception\InvalidConnectionParametersException( 'A dsn was not provided or could not be constructed from your parameters', $this->connectionParameters