From d8aaa35c459150ecf2c84c0ed8636e8bfb7be252 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 19 Apr 2025 05:10:40 -0500 Subject: [PATCH 01/32] latest changes. Pdo named arguments are broken Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- .../{Adapter.php => AbstractAdapter.php} | 24 +++---------------- src/Adapter/AdapterAwareInterface.php | 2 +- src/Adapter/AdapterInterface.php | 19 +++++++++++++++ src/Adapter/AdapterServiceDelegator.php | 2 +- .../Driver/{Mysqli => _Mysqli}/Connection.php | 0 .../Driver/{Mysqli => _Mysqli}/Mysqli.php | 0 .../Driver/{Mysqli => _Mysqli}/Result.php | 0 .../Driver/{Mysqli => _Mysqli}/Statement.php | 0 .../Driver/{Pdo => _Pdo}/Connection.php | 0 .../Feature/OracleRowCounter.php | 0 .../Feature/SqliteRowCounter.php | 0 src/Adapter/Driver/{Pdo => _Pdo}/Pdo.php | 0 src/Adapter/Driver/{Pdo => _Pdo}/Result.php | 0 .../Driver/{Pdo => _Pdo}/Statement.php | 0 ...php => _AdapterAbstractServiceFactory.php} | 2 +- ...Factory.php => _AdapterServiceFactory.php} | 0 src/Metadata/Source/AbstractSource.php | 4 ++-- src/Metadata/Source/Factory.php | 4 ++-- src/Metadata/Source/MysqlMetadata.php | 18 +++++++------- 19 files changed, 38 insertions(+), 37 deletions(-) rename src/Adapter/{Adapter.php => AbstractAdapter.php} (93%) rename src/Adapter/Driver/{Mysqli => _Mysqli}/Connection.php (100%) rename src/Adapter/Driver/{Mysqli => _Mysqli}/Mysqli.php (100%) rename src/Adapter/Driver/{Mysqli => _Mysqli}/Result.php (100%) rename src/Adapter/Driver/{Mysqli => _Mysqli}/Statement.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Connection.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Feature/OracleRowCounter.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Feature/SqliteRowCounter.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Pdo.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Result.php (100%) rename src/Adapter/Driver/{Pdo => _Pdo}/Statement.php (100%) rename src/Adapter/{AdapterAbstractServiceFactory.php => _AdapterAbstractServiceFactory.php} (98%) rename src/Adapter/{AdapterServiceFactory.php => _AdapterServiceFactory.php} (100%) diff --git a/src/Adapter/Adapter.php b/src/Adapter/AbstractAdapter.php similarity index 93% rename from src/Adapter/Adapter.php rename to src/Adapter/AbstractAdapter.php index ad3c7c0e1..a092c1360 100644 --- a/src/Adapter/Adapter.php +++ b/src/Adapter/AbstractAdapter.php @@ -17,26 +17,8 @@ * @property Driver\DriverInterface $driver * @property Platform\PlatformInterface $platform */ -class Adapter implements AdapterInterface, Profiler\ProfilerAwareInterface +abstract class AbstractAdapter implements AdapterInterface, Profiler\ProfilerAwareInterface { - /** - * Query Mode Constants - */ - public const QUERY_MODE_EXECUTE = 'execute'; - public const QUERY_MODE_PREPARE = 'prepare'; - - /** - * Prepare Type Constants - */ - public const PREPARE_TYPE_POSITIONAL = 'positional'; - public const PREPARE_TYPE_NAMED = 'named'; - - public const FUNCTION_FORMAT_PARAMETER_NAME = 'formatParameterName'; - public const FUNCTION_QUOTE_IDENTIFIER = 'quoteIdentifier'; - public const FUNCTION_QUOTE_VALUE = 'quoteValue'; - - public const VALUE_QUOTE_SEPARATOR = 'quoteSeparator'; - /** @var Driver\DriverInterface */ protected $driver; @@ -230,9 +212,9 @@ public function getHelpers() public function __get(string $name) { return match (strtolower($name)) { - 'driver' => $this->driver, + 'driver' => $this->driver, 'platform' => $this->platform, - default => throw new Exception\InvalidArgumentException('Invalid magic property on adapter'), + default => throw new Exception\InvalidArgumentException('Invalid magic property on adapter'), }; } diff --git a/src/Adapter/AdapterAwareInterface.php b/src/Adapter/AdapterAwareInterface.php index e5342a5d3..e598d9e61 100644 --- a/src/Adapter/AdapterAwareInterface.php +++ b/src/Adapter/AdapterAwareInterface.php @@ -9,5 +9,5 @@ interface AdapterAwareInterface * * @return AdapterAwareInterface */ - public function setDbAdapter(Adapter $adapter); + public function setDbAdapter(AdapterInterface $adapter); } diff --git a/src/Adapter/AdapterInterface.php b/src/Adapter/AdapterInterface.php index 50980d656..64f13353d 100644 --- a/src/Adapter/AdapterInterface.php +++ b/src/Adapter/AdapterInterface.php @@ -8,6 +8,25 @@ */ interface AdapterInterface { + /** + * Query Mode Constants + */ + public const QUERY_MODE_EXECUTE = 'execute'; + public const QUERY_MODE_PREPARE = 'prepare'; + + /** + * Prepare Type Constants + */ + public const PREPARE_TYPE_POSITIONAL = 'positional'; + public const PREPARE_TYPE_NAMED = 'named'; + + public const FUNCTION_FORMAT_PARAMETER_NAME = 'formatParameterName'; + public const FUNCTION_QUOTE_IDENTIFIER = 'quoteIdentifier'; + public const FUNCTION_QUOTE_VALUE = 'quoteValue'; + + public const VALUE_QUOTE_SEPARATOR = 'quoteSeparator'; + + /** * @return Driver\DriverInterface */ diff --git a/src/Adapter/AdapterServiceDelegator.php b/src/Adapter/AdapterServiceDelegator.php index 0ca99e83f..32e20e1a8 100644 --- a/src/Adapter/AdapterServiceDelegator.php +++ b/src/Adapter/AdapterServiceDelegator.php @@ -38,7 +38,7 @@ public function __invoke( $databaseAdapter = $container->get($this->adapterName); - if (! $databaseAdapter instanceof Adapter) { + if (! $databaseAdapter instanceof AdapterInterface) { return $instance; } diff --git a/src/Adapter/Driver/Mysqli/Connection.php b/src/Adapter/Driver/_Mysqli/Connection.php similarity index 100% rename from src/Adapter/Driver/Mysqli/Connection.php rename to src/Adapter/Driver/_Mysqli/Connection.php diff --git a/src/Adapter/Driver/Mysqli/Mysqli.php b/src/Adapter/Driver/_Mysqli/Mysqli.php similarity index 100% rename from src/Adapter/Driver/Mysqli/Mysqli.php rename to src/Adapter/Driver/_Mysqli/Mysqli.php diff --git a/src/Adapter/Driver/Mysqli/Result.php b/src/Adapter/Driver/_Mysqli/Result.php similarity index 100% rename from src/Adapter/Driver/Mysqli/Result.php rename to src/Adapter/Driver/_Mysqli/Result.php diff --git a/src/Adapter/Driver/Mysqli/Statement.php b/src/Adapter/Driver/_Mysqli/Statement.php similarity index 100% rename from src/Adapter/Driver/Mysqli/Statement.php rename to src/Adapter/Driver/_Mysqli/Statement.php diff --git a/src/Adapter/Driver/Pdo/Connection.php b/src/Adapter/Driver/_Pdo/Connection.php similarity index 100% rename from src/Adapter/Driver/Pdo/Connection.php rename to src/Adapter/Driver/_Pdo/Connection.php diff --git a/src/Adapter/Driver/Pdo/Feature/OracleRowCounter.php b/src/Adapter/Driver/_Pdo/Feature/OracleRowCounter.php similarity index 100% rename from src/Adapter/Driver/Pdo/Feature/OracleRowCounter.php rename to src/Adapter/Driver/_Pdo/Feature/OracleRowCounter.php diff --git a/src/Adapter/Driver/Pdo/Feature/SqliteRowCounter.php b/src/Adapter/Driver/_Pdo/Feature/SqliteRowCounter.php similarity index 100% rename from src/Adapter/Driver/Pdo/Feature/SqliteRowCounter.php rename to src/Adapter/Driver/_Pdo/Feature/SqliteRowCounter.php diff --git a/src/Adapter/Driver/Pdo/Pdo.php b/src/Adapter/Driver/_Pdo/Pdo.php similarity index 100% rename from src/Adapter/Driver/Pdo/Pdo.php rename to src/Adapter/Driver/_Pdo/Pdo.php diff --git a/src/Adapter/Driver/Pdo/Result.php b/src/Adapter/Driver/_Pdo/Result.php similarity index 100% rename from src/Adapter/Driver/Pdo/Result.php rename to src/Adapter/Driver/_Pdo/Result.php diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/_Pdo/Statement.php similarity index 100% rename from src/Adapter/Driver/Pdo/Statement.php rename to src/Adapter/Driver/_Pdo/Statement.php diff --git a/src/Adapter/AdapterAbstractServiceFactory.php b/src/Adapter/_AdapterAbstractServiceFactory.php similarity index 98% rename from src/Adapter/AdapterAbstractServiceFactory.php rename to src/Adapter/_AdapterAbstractServiceFactory.php index 6b238f162..624feb42a 100644 --- a/src/Adapter/AdapterAbstractServiceFactory.php +++ b/src/Adapter/_AdapterAbstractServiceFactory.php @@ -2,9 +2,9 @@ namespace Laminas\Db\Adapter; -use Interop\Container\ContainerInterface; use Laminas\ServiceManager\AbstractFactoryInterface; use Laminas\ServiceManager\ServiceLocatorInterface; +use Psr\Container\ContainerInterface; use function is_array; diff --git a/src/Adapter/AdapterServiceFactory.php b/src/Adapter/_AdapterServiceFactory.php similarity index 100% rename from src/Adapter/AdapterServiceFactory.php rename to src/Adapter/_AdapterServiceFactory.php diff --git a/src/Metadata/Source/AbstractSource.php b/src/Metadata/Source/AbstractSource.php index 13de76eb1..b6f515942 100644 --- a/src/Metadata/Source/AbstractSource.php +++ b/src/Metadata/Source/AbstractSource.php @@ -3,7 +3,7 @@ namespace Laminas\Db\Metadata\Source; use Exception; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Metadata\MetadataInterface; use Laminas\Db\Metadata\Object\ColumnObject; use Laminas\Db\Metadata\Object\ConstraintKeyObject; @@ -32,7 +32,7 @@ abstract class AbstractSource implements MetadataInterface /** * Constructor */ - public function __construct(Adapter $adapter) + public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; $this->defaultSchema = $adapter->getCurrentSchema() ?: self::DEFAULT_SCHEMA; diff --git a/src/Metadata/Source/Factory.php b/src/Metadata/Source/Factory.php index fd2ef863b..650d14112 100644 --- a/src/Metadata/Source/Factory.php +++ b/src/Metadata/Source/Factory.php @@ -2,7 +2,7 @@ namespace Laminas\Db\Metadata\Source; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Exception\InvalidArgumentException; use Laminas\Db\Metadata\MetadataInterface; @@ -17,7 +17,7 @@ class Factory * @return MetadataInterface * @throws InvalidArgumentException If adapter platform name not recognized. */ - public static function createSourceFromAdapter(Adapter $adapter) + public static function createSourceFromAdapter(AdapterInterface $adapter) { $platformName = $adapter->getPlatform()->getName(); diff --git a/src/Metadata/Source/MysqlMetadata.php b/src/Metadata/Source/MysqlMetadata.php index ff2687897..435bc5485 100644 --- a/src/Metadata/Source/MysqlMetadata.php +++ b/src/Metadata/Source/MysqlMetadata.php @@ -3,7 +3,7 @@ namespace Laminas\Db\Metadata\Source; use DateTime; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AdapterInterface; use function array_change_key_case; use function array_walk; @@ -32,7 +32,7 @@ protected function loadSchemaData() . ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME') . ' != \'INFORMATION_SCHEMA\''; - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $schemas = []; foreach ($results->toArray() as $row) { @@ -87,7 +87,7 @@ protected function loadTableNameData($schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $tables = []; foreach ($results->toArray() as $row) { @@ -152,7 +152,7 @@ protected function loadColumnData($table, $schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $columns = []; foreach ($results->toArray() as $row) { $erratas = []; @@ -268,7 +268,7 @@ protected function loadConstraintData($table, $schema) . ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']); - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $realName = null; $constraints = []; @@ -348,7 +348,7 @@ protected function loadConstraintDataNames($schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { @@ -403,7 +403,7 @@ protected function loadConstraintDataKeys($schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { @@ -466,7 +466,7 @@ protected function loadConstraintReferences($table, $schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { @@ -526,7 +526,7 @@ protected function loadTriggerData($schema) . ' != \'INFORMATION_SCHEMA\''; } - $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { From 3d24705e00ded8a1be37ba672748f7a8977be8fc Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 22 Apr 2025 19:57:06 -0500 Subject: [PATCH 02/32] Update StatementInterface prepare signature Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/StatementInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/StatementInterface.php b/src/Adapter/Driver/StatementInterface.php index 3ccb988f6..83db4c7ac 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -19,7 +19,7 @@ public function getResource(); * * @param string $sql */ - public function prepare($sql = null); + public function prepare(?string $sql = null): ?self; /** * Check if is prepared From c239faad3fed0a0bd9d8f0f592ab8f713e1857e5 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 22 Apr 2025 21:57:56 -0500 Subject: [PATCH 03/32] fix config provider Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/ConfigProvider.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 3d76b87b0..3ec0fdfda 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -23,16 +23,16 @@ public function __invoke() */ public function getDependencyConfig() { - return [ - 'abstract_factories' => [ - Adapter\AdapterAbstractServiceFactory::class, - ], - 'factories' => [ - Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, - ], - 'aliases' => [ - Adapter\Adapter::class => Adapter\AdapterInterface::class, - ], - ]; - } + // return [ + // 'abstract_factories' => [ + // Adapter\AdapterAbstractServiceFactory::class, + // ], + // 'factories' => [ + // Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, + // ], + // 'aliases' => [ + // Adapter\Adapter::class => Adapter\AdapterInterface::class, + // ], + // ]; + // } } From 446f46e3e264f3753939a29630b53d3e33d3730a Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 26 Apr 2025 17:58:29 -0500 Subject: [PATCH 04/32] Fixes regression of "mapped" parameters thanks to @simon-mundy Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/PdoDriverInterface.php | 7 +++++++ src/Sql/Insert.php | 9 ++++----- src/Sql/Update.php | 13 ++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 src/Adapter/Driver/PdoDriverInterface.php diff --git a/src/Adapter/Driver/PdoDriverInterface.php b/src/Adapter/Driver/PdoDriverInterface.php new file mode 100644 index 000000000..329fa04d6 --- /dev/null +++ b/src/Adapter/Driver/PdoDriverInterface.php @@ -0,0 +1,7 @@ +select) { @@ -187,7 +186,7 @@ protected function processInsert( if (is_scalar($value) && $parameterContainer) { // use incremental value instead of column name for PDO // @see https://github.com/zendframework/zend-db/issues/35 - if ($driver instanceof Pdo) { + if ($driver instanceof Driver\PdoDriverInterface) { $column = 'c_' . $i++; } $values[] = $driver->formatParameterName($column); @@ -211,7 +210,7 @@ protected function processInsert( protected function processSelect( PlatformInterface $platform, - ?DriverInterface $driver = null, + ?Driver\DriverInterface $driver = null, ?ParameterContainer $parameterContainer = null ) { if (! $this->select) { diff --git a/src/Sql/Update.php b/src/Sql/Update.php index d85ca8661..96935bd8b 100644 --- a/src/Sql/Update.php +++ b/src/Sql/Update.php @@ -3,8 +3,7 @@ namespace Laminas\Db\Sql; use Closure; -use Laminas\Db\Adapter\Driver\DriverInterface; -use Laminas\Db\Adapter\Driver\Pdo\Pdo; +use Laminas\Db\Adapter\Driver; use Laminas\Db\Adapter\ParameterContainer; use Laminas\Db\Adapter\Platform\PlatformInterface; use Laminas\Db\Sql\Predicate\PredicateInterface; @@ -166,7 +165,7 @@ public function getRawState($key = null) /** @return string */ protected function processUpdate( PlatformInterface $platform, - ?DriverInterface $driver = null, + ?Driver\DriverInterface $driver = null, ?ParameterContainer $parameterContainer = null ) { return sprintf( @@ -178,7 +177,7 @@ protected function processUpdate( /** @return string */ protected function processSet( PlatformInterface $platform, - ?DriverInterface $driver = null, + ?Driver\DriverInterface $driver = null, ?ParameterContainer $parameterContainer = null ) { $setSql = []; @@ -199,7 +198,7 @@ protected function processSet( if (is_scalar($value) && $parameterContainer) { // use incremental value instead of column name for PDO // @see https://github.com/zendframework/zend-db/issues/35 - if ($driver instanceof Pdo) { + if ($driver instanceof Driver\PdoDriverInterface) { $column = 'c_' . $i++; } $setSql[] = $prefix . $driver->formatParameterName($column); @@ -222,7 +221,7 @@ protected function processSet( protected function processWhere( PlatformInterface $platform, - ?DriverInterface $driver = null, + ?Driver\DriverInterface $driver = null, ?ParameterContainer $parameterContainer = null ) { if ($this->where->count() === 0) { @@ -237,7 +236,7 @@ protected function processWhere( /** @return null|string[] */ protected function processJoins( PlatformInterface $platform, - ?DriverInterface $driver = null, + ?Driver\DriverInterface $driver = null, ?ParameterContainer $parameterContainer = null ) { return $this->processJoin($this->joins, $platform, $driver, $parameterContainer); From db1cd25ea65cc3e3800c8ad696c2b294f00589c1 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 6 May 2025 12:12:15 -0500 Subject: [PATCH 05/32] Introduces Driver\Pdo\AbstractPdo Introduces Laminas\Db\Adapter\Platform\PlatformInterface::getSqlPlatformDecorator() Improves typing around surface area methods Adds strict typing to all touched files. Signed-off-by: Joey Smith --- ....php => AdapterAbstractServiceFactory.php} | 26 +- src/Adapter/AdapterInterface.php | 4 +- ...eFactory.php => AdapterServiceFactory.php} | 0 .../{_Pdo/Pdo.php => Pdo/AbstractPdo.php} | 112 ++--- .../Driver/Pdo/AbstractPdoConnection.php | 428 ++++++++++++++++++ src/Adapter/Driver/{_Pdo => Pdo}/Result.php | 0 .../Driver/{_Pdo => Pdo}/Statement.php | 15 +- .../_Feature}/OracleRowCounter.php | 0 .../_Feature}/SqliteRowCounter.php | 0 src/Adapter/Driver/StatementInterface.php | 2 +- src/Adapter/Driver/_Pdo/Connection.php | 428 ------------------ src/Adapter/Platform/PlatformInterface.php | 10 + .../Platform/{Mysql.php => _Mysql.php} | 0 src/Adapter/StatementContainerInterface.php | 4 +- .../{MysqlMetadata.php => _MysqlMetadata.php} | 0 src/Sql/Platform/Platform.php | 33 +- .../Ddl/AlterTableDecorator.php | 0 .../Ddl/CreateTableDecorator.php | 0 src/Sql/Platform/{Mysql => _Mysql}/Mysql.php | 0 .../{Mysql => _Mysql}/SelectDecorator.php | 0 20 files changed, 530 insertions(+), 532 deletions(-) rename src/Adapter/{_AdapterAbstractServiceFactory.php => AdapterAbstractServiceFactory.php} (73%) rename src/Adapter/{_AdapterServiceFactory.php => AdapterServiceFactory.php} (100%) rename src/Adapter/Driver/{_Pdo/Pdo.php => Pdo/AbstractPdo.php} (78%) create mode 100644 src/Adapter/Driver/Pdo/AbstractPdoConnection.php rename src/Adapter/Driver/{_Pdo => Pdo}/Result.php (100%) rename src/Adapter/Driver/{_Pdo => Pdo}/Statement.php (95%) rename src/Adapter/Driver/{_Pdo/Feature => Pdo/_Feature}/OracleRowCounter.php (100%) rename src/Adapter/Driver/{_Pdo/Feature => Pdo/_Feature}/SqliteRowCounter.php (100%) delete mode 100644 src/Adapter/Driver/_Pdo/Connection.php rename src/Adapter/Platform/{Mysql.php => _Mysql.php} (100%) rename src/Metadata/Source/{MysqlMetadata.php => _MysqlMetadata.php} (100%) rename src/Sql/Platform/{Mysql => _Mysql}/Ddl/AlterTableDecorator.php (100%) rename src/Sql/Platform/{Mysql => _Mysql}/Ddl/CreateTableDecorator.php (100%) rename src/Sql/Platform/{Mysql => _Mysql}/Mysql.php (100%) rename src/Sql/Platform/{Mysql => _Mysql}/SelectDecorator.php (100%) diff --git a/src/Adapter/_AdapterAbstractServiceFactory.php b/src/Adapter/AdapterAbstractServiceFactory.php similarity index 73% rename from src/Adapter/_AdapterAbstractServiceFactory.php rename to src/Adapter/AdapterAbstractServiceFactory.php index 624feb42a..798bc18df 100644 --- a/src/Adapter/_AdapterAbstractServiceFactory.php +++ b/src/Adapter/AdapterAbstractServiceFactory.php @@ -2,7 +2,7 @@ namespace Laminas\Db\Adapter; -use Laminas\ServiceManager\AbstractFactoryInterface; +use Laminas\ServiceManager\Factory\AbstractFactoryInterface; use Laminas\ServiceManager\ServiceLocatorInterface; use Psr\Container\ContainerInterface; @@ -36,18 +36,6 @@ public function canCreate(ContainerInterface $container, $requestedName) && ! empty($config[$requestedName]); } - /** - * Determine if we can create a service with name (SM v2 compatibility) - * - * @param string $name - * @param string $requestedName - * @return bool - */ - public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) - { - return $this->canCreate($serviceLocator, $requestedName); - } - /** * Create a DB adapter * @@ -60,18 +48,6 @@ public function __invoke(ContainerInterface $container, $requestedName, ?array $ return new Adapter($config[$requestedName]); } - /** - * Create service with name - * - * @param string $name - * @param string $requestedName - * @return Adapter - */ - public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) - { - return $this($serviceLocator, $requestedName); - } - /** * Get db configuration, if any * diff --git a/src/Adapter/AdapterInterface.php b/src/Adapter/AdapterInterface.php index 64f13353d..ee8957745 100644 --- a/src/Adapter/AdapterInterface.php +++ b/src/Adapter/AdapterInterface.php @@ -1,5 +1,7 @@ connection = $connection; - $this->connection->setDriver($this); - return $this; - } + // public function registerConnection(Connection $connection) + // { + // $this->connection = $connection; + // $this->connection->setDriver($this); + // return $this; + // } /** * Register statement prototype @@ -146,21 +146,21 @@ public function addFeature($name, $feature) * * @return $this Provides a fluent interface */ - public function setupDefaultFeatures() - { - $driverName = $this->connection->getDriverName(); - if ($driverName === 'sqlite') { - $this->addFeature(null, new Feature\SqliteRowCounter()); - return $this; - } - - if ($driverName === 'oci') { - $this->addFeature(null, new Feature\OracleRowCounter()); - return $this; - } - - return $this; - } + // public function setupDefaultFeatures() + // { + // $driverName = $this->connection->getDriverName(); + // if ($driverName === 'sqlite') { + // $this->addFeature(null, new Feature\SqliteRowCounter()); + // return $this; + // } + + // if ($driverName === 'oci') { + // $this->addFeature(null, new Feature\OracleRowCounter()); + // return $this; + // } + + // return $this; + // } /** * Get feature @@ -182,39 +182,39 @@ public function getFeature($name) * @param string $nameFormat * @return string */ - public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) - { - $name = $this->getConnection()->getDriverName(); - if ($nameFormat === self::NAME_FORMAT_CAMELCASE) { - switch ($name) { - case 'pgsql': - return 'Postgresql'; - case 'oci': - return 'Oracle'; - case 'dblib': - case 'sqlsrv': - return 'SqlServer'; - default: - return ucfirst($name); - } - } else { - switch ($name) { - case 'sqlite': - return 'SQLite'; - case 'mysql': - return 'MySQL'; - case 'pgsql': - return 'PostgreSQL'; - case 'oci': - return 'Oracle'; - case 'dblib': - case 'sqlsrv': - return 'SQLServer'; - default: - return ucfirst($name); - } - } - } + // public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) + // { + // $name = $this->getConnection()->getDriverName(); + // if ($nameFormat === self::NAME_FORMAT_CAMELCASE) { + // switch ($name) { + // case 'pgsql': + // return 'Postgresql'; + // case 'oci': + // return 'Oracle'; + // case 'dblib': + // case 'sqlsrv': + // return 'SqlServer'; + // default: + // return ucfirst($name); + // } + // } else { + // switch ($name) { + // case 'sqlite': + // return 'SQLite'; + // case 'mysql': + // return 'MySQL'; + // case 'pgsql': + // return 'PostgreSQL'; + // case 'oci': + // return 'Oracle'; + // case 'dblib': + // case 'sqlsrv': + // return 'SQLServer'; + // default: + // return ucfirst($name); + // } + // } + // } /** * Check environment diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php new file mode 100644 index 000000000..80cb8abe7 --- /dev/null +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -0,0 +1,428 @@ +setConnectionParameters($connectionParameters); + } elseif ($connectionParameters instanceof \PDO) { + $this->setResource($connectionParameters); + } elseif (null !== $connectionParameters) { + throw new Exception\InvalidArgumentException( + '$connection must be an array of parameters, a PDO object or null' + ); + } + } + + /** + * Set driver + * + * @return $this Provides a fluent interface + */ + public function setDriver(Pdo $driver) + { + $this->driver = $driver; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function setConnectionParameters(array $connectionParameters) + { + $this->connectionParameters = $connectionParameters; + if (isset($connectionParameters['dsn'])) { + $this->driverName = substr( + $connectionParameters['dsn'], + 0, + strpos($connectionParameters['dsn'], ':') + ); + } elseif (isset($connectionParameters['pdodriver'])) { + $this->driverName = strtolower($connectionParameters['pdodriver']); + } elseif (isset($connectionParameters['driver'])) { + $this->driverName = strtolower(substr( + str_replace(['-', '_', ' '], '', $connectionParameters['driver']), + 3 + )); + } + } + + /** + * Get the dsn string for this connection + * + * @throws RuntimeException + * @return string + */ + public function getDsn() + { + if (! $this->dsn) { + throw new Exception\RuntimeException( + 'The DSN has not been set or constructed from parameters in connect() for this Connection' + ); + } + + return $this->dsn; + } + + /** + * {@inheritDoc} + */ + // public function getCurrentSchema() + // { + // if (! $this->isConnected()) { + // $this->connect(); + // } + + // switch ($this->driverName) { + // case 'mysql': + // $sql = 'SELECT DATABASE()'; + // break; + // case 'sqlite': + // return 'main'; + // case 'sqlsrv': + // case 'dblib': + // $sql = 'SELECT SCHEMA_NAME()'; + // break; + // case 'pgsql': + // default: + // $sql = 'SELECT CURRENT_SCHEMA'; + // break; + // } + + // /** @var PDOStatement $result */ + // $result = $this->resource->query($sql); + // if ($result instanceof PDOStatement) { + // return $result->fetchColumn(); + // } + + // return false; + // } + + /** + * Set resource + * + * @return $this Provides a fluent interface + */ + public function setResource(\PDO $resource) + { + $this->resource = $resource; + $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); + + return $this; + } + + /** + * {@inheritDoc} + * + * @throws Exception\InvalidConnectionParametersException + * @throws Exception\RuntimeException + */ + // public function connect() + // { + // if ($this->resource) { + // return $this; + // } + + // $dsn = $username = $password = $hostname = $database = null; + // $options = []; + // foreach ($this->connectionParameters as $key => $value) { + // switch (strtolower($key)) { + // case 'dsn': + // $dsn = $value; + // break; + // case 'driver': + // $value = strtolower((string) $value); + // if (strpos($value, 'pdo') === 0) { + // $pdoDriver = str_replace(['-', '_', ' '], '', $value); + // $pdoDriver = substr($pdoDriver, 3) ?: ''; + // } + // break; + // case 'pdodriver': + // $pdoDriver = (string) $value; + // break; + // case 'user': + // case 'username': + // $username = (string) $value; + // break; + // case 'pass': + // case 'password': + // $password = (string) $value; + // break; + // case 'host': + // case 'hostname': + // $hostname = (string) $value; + // break; + // case 'port': + // $port = (int) $value; + // break; + // case 'database': + // case 'dbname': + // $database = (string) $value; + // break; + // case 'charset': + // $charset = (string) $value; + // break; + // case 'unix_socket': + // $unixSocket = (string) $value; + // break; + // case 'version': + // $version = (string) $value; + // break; + // case 'driver_options': + // case 'options': + // $value = (array) $value; + // $options = array_diff_key($options, $value) + $value; + // break; + // default: + // $options[$key] = $value; + // break; + // } + // } + + // if (isset($hostname) && isset($unixSocket)) { + // throw new Exception\InvalidConnectionParametersException( + // 'Ambiguous connection parameters, both hostname and unix_socket parameters were set', + // $this->connectionParameters + // ); + // } + + // if (! isset($dsn) && isset($pdoDriver)) { + // $dsn = []; + // switch ($pdoDriver) { + // case 'sqlite': + // $dsn[] = $database; + // break; + // case 'sqlsrv': + // if (isset($database)) { + // $dsn[] = "database={$database}"; + // } + // if (isset($hostname)) { + // $dsn[] = "server={$hostname}"; + // } + // break; + // default: + // if (isset($database)) { + // $dsn[] = "dbname={$database}"; + // } + // if (isset($hostname)) { + // $dsn[] = "host={$hostname}"; + // } + // if (isset($port)) { + // $dsn[] = "port={$port}"; + // } + // if (isset($charset) && $pdoDriver !== 'pgsql') { + // $dsn[] = "charset={$charset}"; + // } + // if (isset($unixSocket)) { + // $dsn[] = "unix_socket={$unixSocket}"; + // } + // if (isset($version)) { + // $dsn[] = "version={$version}"; + // } + // break; + // } + // $dsn = $pdoDriver . ':' . implode(';', $dsn); + // } elseif (! isset($dsn)) { + // throw new Exception\InvalidConnectionParametersException( + // 'A dsn was not provided or could not be constructed from your parameters', + // $this->connectionParameters + // ); + // } + + // $this->dsn = $dsn; + + // try { + // $this->resource = new \PDO($dsn, $username, $password, $options); + // $this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + // if (isset($charset) && $pdoDriver === 'pgsql') { + // $this->resource->exec('SET NAMES ' . $this->resource->quote($charset)); + // } + // $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); + // } catch (PDOException $e) { + // $code = $e->getCode(); + // if (! is_int($code)) { + // $code = 0; + // } + // throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e); + // } + + // return $this; + // } + + /** + * {@inheritDoc} + */ + public function isConnected() + { + return $this->resource instanceof \PDO; + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + if (! $this->isConnected()) { + $this->connect(); + } + + if (0 === $this->nestedTransactionsCount) { + $this->resource->beginTransaction(); + $this->inTransaction = true; + } + + $this->nestedTransactionsCount++; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function commit() + { + if (! $this->isConnected()) { + $this->connect(); + } + + if ($this->inTransaction) { + $this->nestedTransactionsCount -= 1; + } + + /* + * This shouldn't check for being in a transaction since + * after issuing a SET autocommit=0; we have to commit too. + */ + if (0 === $this->nestedTransactionsCount) { + $this->resource->commit(); + $this->inTransaction = false; + } + + return $this; + } + + /** + * {@inheritDoc} + * + * @throws Exception\RuntimeException + */ + public function rollback() + { + if (! $this->isConnected()) { + throw new Exception\RuntimeException('Must be connected before you can rollback'); + } + + if (! $this->inTransaction()) { + throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); + } + + $this->resource->rollBack(); + + $this->inTransaction = false; + $this->nestedTransactionsCount = 0; + + return $this; + } + + /** + * {@inheritDoc} + * + * @throws Exception\InvalidQueryException + */ + public function execute($sql) + { + if (! $this->isConnected()) { + $this->connect(); + } + + if ($this->profiler) { + $this->profiler->profilerStart($sql); + } + + $resultResource = $this->resource->query($sql); + + if ($this->profiler) { + $this->profiler->profilerFinish($sql); + } + + if ($resultResource === false) { + $errorInfo = $this->resource->errorInfo(); + throw new Exception\InvalidQueryException($errorInfo[2]); + } + + return $this->driver->createResult($resultResource, $sql); + } + + /** + * Prepare + * + * @param string $sql + * @return Statement + */ + public function prepare(string $sql) + { + if (! $this->isConnected()) { + $this->connect(); + } + + return $this->driver->createStatement($sql); + } + + /** + * {@inheritDoc} + * + * @param string $name + * @return string|null|false + */ + // public function getLastGeneratedValue($name = null) + // { + // if ( + // $name === null + // && ($this->driverName === 'pgsql' || $this->driverName === 'firebird') + // ) { + // return; + // } + + // try { + // return $this->resource->lastInsertId($name); + // } catch (\Exception $e) { + // // do nothing + // } + + // return false; + // } +} diff --git a/src/Adapter/Driver/_Pdo/Result.php b/src/Adapter/Driver/Pdo/Result.php similarity index 100% rename from src/Adapter/Driver/_Pdo/Result.php rename to src/Adapter/Driver/Pdo/Result.php diff --git a/src/Adapter/Driver/_Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php similarity index 95% rename from src/Adapter/Driver/_Pdo/Statement.php rename to src/Adapter/Driver/Pdo/Statement.php index 4606de40b..9d9d08e47 100644 --- a/src/Adapter/Driver/_Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -2,6 +2,7 @@ namespace Laminas\Db\Adapter\Driver\Pdo; +use Laminas\Db\Adapter\Driver\PdoDriverInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\ParameterContainer; @@ -48,7 +49,7 @@ class Statement implements StatementInterface, Profiler\ProfilerAwareInterface * * @return $this Provides a fluent interface */ - public function setDriver(Pdo $driver) + public function setDriver(PdoDriverInterface $driver): self { $this->driver = $driver; return $this; @@ -57,7 +58,7 @@ public function setDriver(Pdo $driver) /** * @return $this Provides a fluent interface */ - public function setProfiler(Profiler\ProfilerInterface $profiler) + public function setProfiler(Profiler\ProfilerInterface $profiler): self { $this->profiler = $profiler; return $this; @@ -66,7 +67,7 @@ public function setProfiler(Profiler\ProfilerInterface $profiler) /** * @return null|Profiler\ProfilerInterface */ - public function getProfiler() + public function getProfiler(): ?Profiler\ProfilerInterface { return $this->profiler; } @@ -109,7 +110,7 @@ public function getResource() * @param string $sql * @return $this Provides a fluent interface */ - public function setSql($sql) + public function setSql($sql): static { $this->sql = $sql; return $this; @@ -120,7 +121,7 @@ public function setSql($sql) * * @return string */ - public function getSql() + public function getSql(): ?string { return $this->sql; } @@ -146,7 +147,7 @@ public function getParameterContainer() * @param string $sql * @throws Exception\RuntimeException */ - public function prepare($sql = null) + public function prepare(?string $sql = null): ?static { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); @@ -164,6 +165,8 @@ public function prepare($sql = null) } $this->isPrepared = true; + + return $this; } /** diff --git a/src/Adapter/Driver/_Pdo/Feature/OracleRowCounter.php b/src/Adapter/Driver/Pdo/_Feature/OracleRowCounter.php similarity index 100% rename from src/Adapter/Driver/_Pdo/Feature/OracleRowCounter.php rename to src/Adapter/Driver/Pdo/_Feature/OracleRowCounter.php diff --git a/src/Adapter/Driver/_Pdo/Feature/SqliteRowCounter.php b/src/Adapter/Driver/Pdo/_Feature/SqliteRowCounter.php similarity index 100% rename from src/Adapter/Driver/_Pdo/Feature/SqliteRowCounter.php rename to src/Adapter/Driver/Pdo/_Feature/SqliteRowCounter.php diff --git a/src/Adapter/Driver/StatementInterface.php b/src/Adapter/Driver/StatementInterface.php index 83db4c7ac..298742f44 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -19,7 +19,7 @@ public function getResource(); * * @param string $sql */ - public function prepare(?string $sql = null): ?self; + public function prepare(?string $sql = null): ?static; /** * Check if is prepared diff --git a/src/Adapter/Driver/_Pdo/Connection.php b/src/Adapter/Driver/_Pdo/Connection.php deleted file mode 100644 index 26e1baa83..000000000 --- a/src/Adapter/Driver/_Pdo/Connection.php +++ /dev/null @@ -1,428 +0,0 @@ -setConnectionParameters($connectionParameters); - } elseif ($connectionParameters instanceof \PDO) { - $this->setResource($connectionParameters); - } elseif (null !== $connectionParameters) { - throw new Exception\InvalidArgumentException( - '$connection must be an array of parameters, a PDO object or null' - ); - } - } - - /** - * Set driver - * - * @return $this Provides a fluent interface - */ - public function setDriver(Pdo $driver) - { - $this->driver = $driver; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function setConnectionParameters(array $connectionParameters) - { - $this->connectionParameters = $connectionParameters; - if (isset($connectionParameters['dsn'])) { - $this->driverName = substr( - $connectionParameters['dsn'], - 0, - strpos($connectionParameters['dsn'], ':') - ); - } elseif (isset($connectionParameters['pdodriver'])) { - $this->driverName = strtolower($connectionParameters['pdodriver']); - } elseif (isset($connectionParameters['driver'])) { - $this->driverName = strtolower(substr( - str_replace(['-', '_', ' '], '', $connectionParameters['driver']), - 3 - )); - } - } - - /** - * Get the dsn string for this connection - * - * @throws RuntimeException - * @return string - */ - public function getDsn() - { - if (! $this->dsn) { - throw new Exception\RuntimeException( - 'The DSN has not been set or constructed from parameters in connect() for this Connection' - ); - } - - return $this->dsn; - } - - /** - * {@inheritDoc} - */ - public function getCurrentSchema() - { - if (! $this->isConnected()) { - $this->connect(); - } - - switch ($this->driverName) { - case 'mysql': - $sql = 'SELECT DATABASE()'; - break; - case 'sqlite': - return 'main'; - case 'sqlsrv': - case 'dblib': - $sql = 'SELECT SCHEMA_NAME()'; - break; - case 'pgsql': - default: - $sql = 'SELECT CURRENT_SCHEMA'; - break; - } - - /** @var PDOStatement $result */ - $result = $this->resource->query($sql); - if ($result instanceof PDOStatement) { - return $result->fetchColumn(); - } - - return false; - } - - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(\PDO $resource) - { - $this->resource = $resource; - $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); - - return $this; - } - - /** - * {@inheritDoc} - * - * @throws Exception\InvalidConnectionParametersException - * @throws Exception\RuntimeException - */ - public function connect() - { - if ($this->resource) { - return $this; - } - - $dsn = $username = $password = $hostname = $database = null; - $options = []; - foreach ($this->connectionParameters as $key => $value) { - switch (strtolower($key)) { - case 'dsn': - $dsn = $value; - break; - case 'driver': - $value = strtolower((string) $value); - if (strpos($value, 'pdo') === 0) { - $pdoDriver = str_replace(['-', '_', ' '], '', $value); - $pdoDriver = substr($pdoDriver, 3) ?: ''; - } - break; - case 'pdodriver': - $pdoDriver = (string) $value; - break; - case 'user': - case 'username': - $username = (string) $value; - break; - case 'pass': - case 'password': - $password = (string) $value; - break; - case 'host': - case 'hostname': - $hostname = (string) $value; - break; - case 'port': - $port = (int) $value; - break; - case 'database': - case 'dbname': - $database = (string) $value; - break; - case 'charset': - $charset = (string) $value; - break; - case 'unix_socket': - $unixSocket = (string) $value; - break; - case 'version': - $version = (string) $value; - break; - case 'driver_options': - case 'options': - $value = (array) $value; - $options = array_diff_key($options, $value) + $value; - break; - default: - $options[$key] = $value; - break; - } - } - - if (isset($hostname) && isset($unixSocket)) { - throw new Exception\InvalidConnectionParametersException( - 'Ambiguous connection parameters, both hostname and unix_socket parameters were set', - $this->connectionParameters - ); - } - - if (! isset($dsn) && isset($pdoDriver)) { - $dsn = []; - switch ($pdoDriver) { - case 'sqlite': - $dsn[] = $database; - break; - case 'sqlsrv': - if (isset($database)) { - $dsn[] = "database={$database}"; - } - if (isset($hostname)) { - $dsn[] = "server={$hostname}"; - } - break; - default: - if (isset($database)) { - $dsn[] = "dbname={$database}"; - } - if (isset($hostname)) { - $dsn[] = "host={$hostname}"; - } - if (isset($port)) { - $dsn[] = "port={$port}"; - } - if (isset($charset) && $pdoDriver !== 'pgsql') { - $dsn[] = "charset={$charset}"; - } - if (isset($unixSocket)) { - $dsn[] = "unix_socket={$unixSocket}"; - } - if (isset($version)) { - $dsn[] = "version={$version}"; - } - break; - } - $dsn = $pdoDriver . ':' . implode(';', $dsn); - } elseif (! isset($dsn)) { - throw new Exception\InvalidConnectionParametersException( - 'A dsn was not provided or could not be constructed from your parameters', - $this->connectionParameters - ); - } - - $this->dsn = $dsn; - - try { - $this->resource = new \PDO($dsn, $username, $password, $options); - $this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - if (isset($charset) && $pdoDriver === 'pgsql') { - $this->resource->exec('SET NAMES ' . $this->resource->quote($charset)); - } - $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); - } catch (PDOException $e) { - $code = $e->getCode(); - if (! is_int($code)) { - $code = 0; - } - throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e); - } - - return $this; - } - - /** - * {@inheritDoc} - */ - public function isConnected() - { - return $this->resource instanceof \PDO; - } - - /** - * {@inheritDoc} - */ - public function beginTransaction() - { - if (! $this->isConnected()) { - $this->connect(); - } - - if (0 === $this->nestedTransactionsCount) { - $this->resource->beginTransaction(); - $this->inTransaction = true; - } - - $this->nestedTransactionsCount++; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function commit() - { - if (! $this->isConnected()) { - $this->connect(); - } - - if ($this->inTransaction) { - $this->nestedTransactionsCount -= 1; - } - - /* - * This shouldn't check for being in a transaction since - * after issuing a SET autocommit=0; we have to commit too. - */ - if (0 === $this->nestedTransactionsCount) { - $this->resource->commit(); - $this->inTransaction = false; - } - - return $this; - } - - /** - * {@inheritDoc} - * - * @throws Exception\RuntimeException - */ - public function rollback() - { - if (! $this->isConnected()) { - throw new Exception\RuntimeException('Must be connected before you can rollback'); - } - - if (! $this->inTransaction()) { - throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); - } - - $this->resource->rollBack(); - - $this->inTransaction = false; - $this->nestedTransactionsCount = 0; - - return $this; - } - - /** - * {@inheritDoc} - * - * @throws Exception\InvalidQueryException - */ - public function execute($sql) - { - if (! $this->isConnected()) { - $this->connect(); - } - - if ($this->profiler) { - $this->profiler->profilerStart($sql); - } - - $resultResource = $this->resource->query($sql); - - if ($this->profiler) { - $this->profiler->profilerFinish($sql); - } - - if ($resultResource === false) { - $errorInfo = $this->resource->errorInfo(); - throw new Exception\InvalidQueryException($errorInfo[2]); - } - - return $this->driver->createResult($resultResource, $sql); - } - - /** - * Prepare - * - * @param string $sql - * @return Statement - */ - public function prepare($sql) - { - if (! $this->isConnected()) { - $this->connect(); - } - - return $this->driver->createStatement($sql); - } - - /** - * {@inheritDoc} - * - * @param string $name - * @return string|null|false - */ - public function getLastGeneratedValue($name = null) - { - if ( - $name === null - && ($this->driverName === 'pgsql' || $this->driverName === 'firebird') - ) { - return; - } - - try { - return $this->resource->lastInsertId($name); - } catch (\Exception $e) { - // do nothing - } - - return false; - } -} diff --git a/src/Adapter/Platform/PlatformInterface.php b/src/Adapter/Platform/PlatformInterface.php index fdc193b28..98c774c29 100644 --- a/src/Adapter/Platform/PlatformInterface.php +++ b/src/Adapter/Platform/PlatformInterface.php @@ -1,7 +1,11 @@ defaultPlatform = $adapter->getPlatform(); - - $mySqlPlatform = new Mysql\Mysql(); - $sqlServerPlatform = new SqlServer\SqlServer(); - $oraclePlatform = new Oracle\Oracle(); - $ibmDb2Platform = new IbmDb2\IbmDb2(); - $sqlitePlatform = new Sqlite\Sqlite(); - - $this->decorators['mysql'] = $mySqlPlatform->getDecorators(); - $this->decorators['sqlserver'] = $sqlServerPlatform->getDecorators(); - $this->decorators['oracle'] = $oraclePlatform->getDecorators(); - $this->decorators['ibmdb2'] = $ibmDb2Platform->getDecorators(); - $this->decorators['sqlite'] = $sqlitePlatform->getDecorators(); + // todo: sat-migration this all seems redundant + $this->defaultPlatform = $adapter->getPlatform(); + $platformName = $this->resolvePlatformName($adapter); + $this->decorators[$platformName] = $this->defaultPlatform->getSqlPlatformDecorator(); + + /** + * todo: sat-migration + * The following is deprecated and will be removed during cleanup + */ + // $mySqlPlatform = new Mysql\Mysql(); + // $sqlServerPlatform = new SqlServer\SqlServer(); + // $oraclePlatform = new Oracle\Oracle(); + // $ibmDb2Platform = new IbmDb2\IbmDb2(); + // $sqlitePlatform = new Sqlite\Sqlite(); + + // $this->decorators['mysql'] = $mySqlPlatform->getDecorators(); + // $this->decorators['sqlserver'] = $sqlServerPlatform->getDecorators(); + // $this->decorators['oracle'] = $oraclePlatform->getDecorators(); + // $this->decorators['ibmdb2'] = $ibmDb2Platform->getDecorators(); + // $this->decorators['sqlite'] = $sqlitePlatform->getDecorators(); } /** diff --git a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php b/src/Sql/Platform/_Mysql/Ddl/AlterTableDecorator.php similarity index 100% rename from src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php rename to src/Sql/Platform/_Mysql/Ddl/AlterTableDecorator.php diff --git a/src/Sql/Platform/Mysql/Ddl/CreateTableDecorator.php b/src/Sql/Platform/_Mysql/Ddl/CreateTableDecorator.php similarity index 100% rename from src/Sql/Platform/Mysql/Ddl/CreateTableDecorator.php rename to src/Sql/Platform/_Mysql/Ddl/CreateTableDecorator.php diff --git a/src/Sql/Platform/Mysql/Mysql.php b/src/Sql/Platform/_Mysql/Mysql.php similarity index 100% rename from src/Sql/Platform/Mysql/Mysql.php rename to src/Sql/Platform/_Mysql/Mysql.php diff --git a/src/Sql/Platform/Mysql/SelectDecorator.php b/src/Sql/Platform/_Mysql/SelectDecorator.php similarity index 100% rename from src/Sql/Platform/Mysql/SelectDecorator.php rename to src/Sql/Platform/_Mysql/SelectDecorator.php From db979f5d98f951279d430862831e0d79f2ee4df4 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 6 May 2025 12:32:26 -0500 Subject: [PATCH 06/32] Missed strict types Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Sql/Platform/AbstractPlatform.php | 2 ++ src/Sql/Platform/Platform.php | 2 ++ src/Sql/Platform/_Mysql/Mysql.php | 2 ++ src/Sql/Sql.php | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/Sql/Platform/AbstractPlatform.php b/src/Sql/Platform/AbstractPlatform.php index 62f809f54..c5d374f0d 100644 --- a/src/Sql/Platform/AbstractPlatform.php +++ b/src/Sql/Platform/AbstractPlatform.php @@ -1,5 +1,7 @@ Date: Mon, 12 May 2025 22:02:51 -0500 Subject: [PATCH 07/32] Adding temp debug comments Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 6 +++--- src/Sql/AbstractPreparableSql.php | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index fabca6d93..1da7f5cca 100644 --- a/composer.json +++ b/composer.json @@ -32,13 +32,13 @@ }, "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "laminas/laminas-servicemanager": "^4.0.0", "laminas/laminas-stdlib": "^3.20.0" }, "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", "laminas/laminas-eventmanager": "^3.14.0", - "laminas/laminas-hydrator": "^4.16.0", - "laminas/laminas-servicemanager": "^3.23.0", + "laminas/laminas-servicemanager": "^4.0.0", "phpunit/phpunit": "^11.5.12", "psalm/plugin-phpunit": "^0.19.2", "rector/rector": "^2.0", @@ -46,7 +46,7 @@ }, "suggest": { "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^3.2 || ^4.3) Laminas\\Hydrator component for using HydratingResultSets", + "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets", "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" }, "autoload": { diff --git a/src/Sql/AbstractPreparableSql.php b/src/Sql/AbstractPreparableSql.php index 6bf2e8197..5b8ada160 100644 --- a/src/Sql/AbstractPreparableSql.php +++ b/src/Sql/AbstractPreparableSql.php @@ -15,11 +15,13 @@ abstract class AbstractPreparableSql extends AbstractSql implements PreparableSq */ public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer) { + // todo: parameterContainer is not instanceof ParameterContainer when + // Mysqli is used? $parameterContainer = $statementContainer->getParameterContainer(); if (! $parameterContainer instanceof ParameterContainer) { $parameterContainer = new ParameterContainer(); - + // todo: setting empty parameter container with mapped parameters and mysqli adapter $statementContainer->setParameterContainer($parameterContainer); } From 61c04d1ec3bf4e4ce536b6ab5b7c5aee25ae0812 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Wed, 14 May 2025 00:28:25 -0500 Subject: [PATCH 08/32] Removes MySQL related code that has been migrated to laminas-db-adapter-mysql Introduces Container\MetadataFactory to replace deprecated Metadata\Source\Factory Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 6 - src/Adapter/Driver/_Mysqli/Connection.php | 297 ---------- src/Adapter/Driver/_Mysqli/Mysqli.php | 241 -------- src/Adapter/Driver/_Mysqli/Result.php | 344 ----------- src/Adapter/Driver/_Mysqli/Statement.php | 295 ---------- src/Adapter/Platform/_Mysql.php | 126 ---- src/ConfigProvider.php | 38 -- src/Container/MetadataFactory.php | 28 + src/Metadata/Source/Factory.php | 1 + src/Metadata/Source/_MysqlMetadata.php | 542 ------------------ src/Module.php | 19 - src/TableGateway/Feature/MetadataFeature.php | 16 +- .../AdapterAbstractServiceFactoryTest.php | 4 +- 13 files changed, 34 insertions(+), 1923 deletions(-) delete mode 100644 src/Adapter/Driver/_Mysqli/Connection.php delete mode 100644 src/Adapter/Driver/_Mysqli/Mysqli.php delete mode 100644 src/Adapter/Driver/_Mysqli/Result.php delete mode 100644 src/Adapter/Driver/_Mysqli/Statement.php delete mode 100644 src/Adapter/Platform/_Mysql.php delete mode 100644 src/ConfigProvider.php create mode 100644 src/Container/MetadataFactory.php delete mode 100644 src/Metadata/Source/_MysqlMetadata.php delete mode 100644 src/Module.php diff --git a/composer.json b/composer.json index 1da7f5cca..d3aa8c506 100644 --- a/composer.json +++ b/composer.json @@ -24,12 +24,6 @@ "dealerdirect/phpcodesniffer-composer-installer": true } }, - "extra": { - "laminas": { - "component": "Laminas\\Db", - "config-provider": "Laminas\\Db\\ConfigProvider" - } - }, "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "laminas/laminas-servicemanager": "^4.0.0", diff --git a/src/Adapter/Driver/_Mysqli/Connection.php b/src/Adapter/Driver/_Mysqli/Connection.php deleted file mode 100644 index 85277e051..000000000 --- a/src/Adapter/Driver/_Mysqli/Connection.php +++ /dev/null @@ -1,297 +0,0 @@ -setConnectionParameters($connectionInfo); - } elseif ($connectionInfo instanceof \mysqli) { - $this->setResource($connectionInfo); - } elseif (null !== $connectionInfo) { - throw new Exception\InvalidArgumentException( - '$connection must be an array of parameters, a mysqli object or null' - ); - } - } - - /** - * @return $this Provides a fluent interface - */ - public function setDriver(Mysqli $driver) - { - $this->driver = $driver; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function getCurrentSchema() - { - if (! $this->isConnected()) { - $this->connect(); - } - - $result = $this->resource->query('SELECT DATABASE()'); - $r = $result->fetch_row(); - - return $r[0]; - } - - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(\mysqli $resource) - { - $this->resource = $resource; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function connect() - { - if ($this->resource instanceof \mysqli) { - return $this; - } - - // localize - $p = $this->connectionParameters; - - // given a list of key names, test for existence in $p - $findParameterValue = function (array $names) use ($p) { - foreach ($names as $name) { - if (isset($p[$name])) { - return $p[$name]; - } - } - - return null; - }; - - $hostname = $findParameterValue(['hostname', 'host']); - $username = $findParameterValue(['username', 'user']); - $password = $findParameterValue(['password', 'passwd', 'pw']); - $database = $findParameterValue(['database', 'dbname', 'db', 'schema']); - $port = isset($p['port']) ? (int) $p['port'] : null; - $socket = $p['socket'] ?? null; - - // phpcs:ignore WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - $useSSL = $p['use_ssl'] ?? 0; - $clientKey = $p['client_key'] ?? ''; - $clientCert = $p['client_cert'] ?? ''; - $caCert = $p['ca_cert'] ?? ''; - $caPath = $p['ca_path'] ?? ''; - $cipher = $p['cipher'] ?? ''; - - $this->resource = $this->createResource(); - - if (! empty($p['driver_options'])) { - foreach ($p['driver_options'] as $option => $value) { - if (is_string($option)) { - $option = strtoupper($option); - if (! defined($option)) { - continue; - } - $option = constant($option); - } - $this->resource->options($option, $value); - } - } - - $flags = null; - - // phpcs:ignore WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - if ($useSSL && ! $socket) { - // Even though mysqli docs are not quite clear on this, MYSQLI_CLIENT_SSL - // needs to be set to make sure SSL is used. ssl_set can also cause it to - // be implicitly set, but only when any of the parameters is non-empty. - $flags = MYSQLI_CLIENT_SSL; - $this->resource->ssl_set($clientKey, $clientCert, $caCert, $caPath, $cipher); - //MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT is not valid option, needs to be set as flag - if ( - isset($p['driver_options']) - && isset($p['driver_options'][MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT]) - ) { - $flags |= MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; - } - } - - try { - $flags === null - ? $this->resource->real_connect($hostname, $username, $password, $database, $port, $socket) - : $this->resource->real_connect($hostname, $username, $password, $database, $port, $socket, $flags); - } catch (GenericException $e) { - throw new Exception\RuntimeException( - 'Connection error', - $this->resource->connect_errno, - new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno) - ); - } - - if ($this->resource->connect_error) { - throw new Exception\RuntimeException( - 'Connection error', - $this->resource->connect_errno, - new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno) - ); - } - - if (! empty($p['charset'])) { - $this->resource->set_charset($p['charset']); - } - - return $this; - } - - /** - * {@inheritDoc} - */ - public function isConnected() - { - return $this->resource instanceof \mysqli; - } - - /** - * {@inheritDoc} - */ - public function disconnect() - { - if ($this->resource instanceof \mysqli) { - $this->resource->close(); - } - $this->resource = null; - } - - /** - * {@inheritDoc} - */ - public function beginTransaction() - { - if (! $this->isConnected()) { - $this->connect(); - } - - $this->resource->autocommit(false); - $this->inTransaction = true; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function commit() - { - if (! $this->isConnected()) { - $this->connect(); - } - - $this->resource->commit(); - $this->inTransaction = false; - $this->resource->autocommit(true); - - return $this; - } - - /** - * {@inheritDoc} - */ - public function rollback() - { - if (! $this->isConnected()) { - throw new Exception\RuntimeException('Must be connected before you can rollback.'); - } - - if (! $this->inTransaction) { - throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.'); - } - - $this->resource->rollback(); - $this->resource->autocommit(true); - $this->inTransaction = false; - - return $this; - } - - /** - * {@inheritDoc} - * - * @throws Exception\InvalidQueryException - */ - public function execute($sql) - { - if (! $this->isConnected()) { - $this->connect(); - } - - if ($this->profiler) { - $this->profiler->profilerStart($sql); - } - - $resultResource = $this->resource->query($sql); - - if ($this->profiler) { - $this->profiler->profilerFinish($sql); - } - - // if the returnValue is something other than a mysqli_result, bypass wrapping it - if ($resultResource === false) { - throw new Exception\InvalidQueryException($this->resource->error); - } - - return $this->driver->createResult($resultResource === true ? $this->resource : $resultResource); - } - - /** - * {@inheritDoc} - */ - public function getLastGeneratedValue($name = null) - { - return $this->resource->insert_id; - } - - /** - * Create a new mysqli resource - * - * @return \mysqli - */ - protected function createResource() - { - return new \mysqli(); - } -} diff --git a/src/Adapter/Driver/_Mysqli/Mysqli.php b/src/Adapter/Driver/_Mysqli/Mysqli.php deleted file mode 100644 index 3221306ae..000000000 --- a/src/Adapter/Driver/_Mysqli/Mysqli.php +++ /dev/null @@ -1,241 +0,0 @@ - false, - ]; - - /** - * Constructor - * - * @param array|Connection|\mysqli $connection - */ - public function __construct( - $connection, - ?Statement $statementPrototype = null, - ?Result $resultPrototype = null, - array $options = [] - ) { - if (! $connection instanceof Connection) { - $connection = new Connection($connection); - } - - $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()); - } - - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler) - { - $this->profiler = $profiler; - if ($this->connection instanceof Profiler\ProfilerAwareInterface) { - $this->connection->setProfiler($profiler); - } - if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { - $this->statementPrototype->setProfiler($profiler); - } - return $this; - } - - /** - * @return null|Profiler\ProfilerInterface - */ - public function getProfiler() - { - return $this->profiler; - } - - /** - * Register connection - * - * @return $this Provides a fluent interface - */ - public function registerConnection(Connection $connection) - { - $this->connection = $connection; - $this->connection->setDriver($this); // needs access to driver to createStatement() - return $this; - } - - /** - * Register statement prototype - */ - public function registerStatementPrototype(Statement $statementPrototype) - { - $this->statementPrototype = $statementPrototype; - $this->statementPrototype->setDriver($this); // needs access to driver to createResult() - } - - /** - * Get statement prototype - * - * @return null|Statement - */ - public function getStatementPrototype() - { - return $this->statementPrototype; - } - - /** - * Register result prototype - */ - public function registerResultPrototype(Result $resultPrototype) - { - $this->resultPrototype = $resultPrototype; - } - - /** - * @return null|Result - */ - public function getResultPrototype() - { - return $this->resultPrototype; - } - - /** - * Get database platform name - * - * @param string $nameFormat - * @return string - */ - public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) - { - if ($nameFormat === self::NAME_FORMAT_CAMELCASE) { - return 'Mysql'; - } - - return 'MySQL'; - } - - /** - * Check environment - * - * @throws Exception\RuntimeException - * @return void - */ - public function checkEnvironment() - { - if (! extension_loaded('mysqli')) { - throw new Exception\RuntimeException( - 'The Mysqli extension is required for this adapter but the extension is not loaded' - ); - } - } - - /** - * Get connection - * - * @return Connection - */ - public function getConnection() - { - return $this->connection; - } - - /** - * Create statement - * - * @param string $sqlOrResource - * @return Statement - */ - public function createStatement($sqlOrResource = null) - { - /** - * @todo Resource tracking - if (is_resource($sqlOrResource) && !in_array($sqlOrResource, $this->resources, true)) { - $this->resources[] = $sqlOrResource; - } - */ - - $statement = clone $this->statementPrototype; - if ($sqlOrResource instanceof mysqli_stmt) { - $statement->setResource($sqlOrResource); - } else { - if (is_string($sqlOrResource)) { - $statement->setSql($sqlOrResource); - } - if (! $this->connection->isConnected()) { - $this->connection->connect(); - } - $statement->initialize($this->connection->getResource()); - } - return $statement; - } - - /** - * Create result - * - * @param resource $resource - * @param null|bool $isBuffered - * @return Result - */ - public function createResult($resource, $isBuffered = null) - { - $result = clone $this->resultPrototype; - $result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered); - return $result; - } - - /** - * Get prepare type - * - * @return string - */ - public function getPrepareType() - { - return self::PARAMETERIZATION_POSITIONAL; - } - - /** - * Format parameter name - * - * @param string $name - * @param mixed $type - * @return string - */ - public function formatParameterName($name, $type = null) - { - return '?'; - } - - /** - * Get last generated value - * - * @return mixed - */ - public function getLastGeneratedValue() - { - return $this->getConnection()->getLastGeneratedValue(); - } -} diff --git a/src/Adapter/Driver/_Mysqli/Result.php b/src/Adapter/Driver/_Mysqli/Result.php deleted file mode 100644 index 3fcd61746..000000000 --- a/src/Adapter/Driver/_Mysqli/Result.php +++ /dev/null @@ -1,344 +0,0 @@ - null, 'values' => []]; - - /** @var mixed */ - protected $generatedValue; - - /** - * Initialize - * - * @param mixed $resource - * @param mixed $generatedValue - * @param bool|null $isBuffered - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function initialize($resource, $generatedValue, $isBuffered = null) - { - if ( - ! $resource instanceof mysqli - && ! $resource instanceof mysqli_result - && ! $resource instanceof mysqli_stmt - ) { - throw new Exception\InvalidArgumentException('Invalid resource provided.'); - } - - if ($isBuffered !== null) { - $this->isBuffered = $isBuffered; - } else { - if ( - $resource instanceof mysqli || $resource instanceof mysqli_result - || $resource instanceof mysqli_stmt && $resource->num_rows !== 0 - ) { - $this->isBuffered = true; - } - } - - $this->resource = $resource; - $this->generatedValue = $generatedValue; - return $this; - } - - /** - * Force buffering - * - * @throws Exception\RuntimeException - */ - public function buffer() - { - if ($this->resource instanceof mysqli_stmt && $this->isBuffered !== true) { - if ($this->position > 0) { - throw new Exception\RuntimeException('Cannot buffer a result set that has started iteration.'); - } - $this->resource->store_result(); - $this->isBuffered = true; - } - } - - /** - * Check if is buffered - * - * @return bool|null - */ - public function isBuffered() - { - return $this->isBuffered; - } - - /** - * Return the resource - * - * @return mixed - */ - public function getResource() - { - return $this->resource; - } - - /** - * Is query result? - * - * @return bool - */ - public function isQueryResult() - { - return $this->resource->field_count > 0; - } - - /** - * Get affected rows - * - * @return int - */ - public function getAffectedRows() - { - if ($this->resource instanceof mysqli || $this->resource instanceof mysqli_stmt) { - return $this->resource->affected_rows; - } - - return $this->resource->num_rows; - } - - /** - * Current - * - * @return mixed - */ - #[ReturnTypeWillChange] - public function current() - { - if ($this->currentComplete) { - return $this->currentData; - } - - if ($this->resource instanceof mysqli_stmt) { - $this->loadDataFromMysqliStatement(); - return $this->currentData; - } else { - $this->loadFromMysqliResult(); - return $this->currentData; - } - } - - /** - * Mysqli's binding and returning of statement values - * - * Mysqli requires you to bind variables to the extension in order to - * get data out. These values have to be references: - * - * @see http://php.net/manual/en/mysqli-stmt.bind-result.php - * - * @throws Exception\RuntimeException - * @return bool - */ - protected function loadDataFromMysqliStatement() - { - // build the default reference based bind structure, if it does not already exist - if ($this->statementBindValues['keys'] === null) { - $this->statementBindValues['keys'] = []; - $resultResource = $this->resource->result_metadata(); - foreach ($resultResource->fetch_fields() as $col) { - $this->statementBindValues['keys'][] = $col->name; - } - $this->statementBindValues['values'] = array_fill(0, count($this->statementBindValues['keys']), null); - $refs = []; - foreach ($this->statementBindValues['values'] as $i => &$f) { - $refs[$i] = &$f; - } - call_user_func_array([$this->resource, 'bind_result'], $this->statementBindValues['values']); - } - - if (($r = $this->resource->fetch()) === null) { - if (! $this->isBuffered) { - $this->resource->close(); - } - return false; - } elseif ($r === false) { - throw new Exception\RuntimeException($this->resource->error); - } - - // dereference - for ($i = 0, $count = count($this->statementBindValues['keys']); $i < $count; $i++) { - $this->currentData[$this->statementBindValues['keys'][$i]] = $this->statementBindValues['values'][$i]; - } - $this->currentComplete = true; - $this->nextComplete = true; - $this->position++; - return true; - } - - /** - * Load from mysqli result - * - * @return bool - */ - protected function loadFromMysqliResult() - { - $this->currentData = null; - - if (($data = $this->resource->fetch_assoc()) === null) { - return false; - } - - $this->position++; - $this->currentData = $data; - $this->currentComplete = true; - $this->nextComplete = true; - $this->position++; - return true; - } - - /** - * Next - * - * @return void - */ - #[ReturnTypeWillChange] - public function next() - { - $this->currentComplete = false; - - if ($this->nextComplete === false) { - $this->position++; - } - - $this->nextComplete = false; - } - - /** - * Key - * - * @return mixed - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->position; - } - - /** - * Rewind - * - * @throws Exception\RuntimeException - * @return void - */ - #[ReturnTypeWillChange] - public function rewind() - { - if (0 !== $this->position && false === $this->isBuffered) { - throw new Exception\RuntimeException('Unbuffered results cannot be rewound for multiple iterations'); - } - - $this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt - $this->currentComplete = false; - $this->position = 0; - } - - /** - * Valid - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - if ($this->currentComplete) { - return true; - } - - if ($this->resource instanceof mysqli_stmt) { - return $this->loadDataFromMysqliStatement(); - } - - return $this->loadFromMysqliResult(); - } - - /** - * Count - * - * @throws Exception\RuntimeException - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - if ($this->isBuffered === false) { - throw new Exception\RuntimeException('Row count is not available in unbuffered result sets.'); - } - return $this->resource->num_rows; - } - - /** - * Get field count - * - * @return int - */ - public function getFieldCount() - { - return $this->resource->field_count; - } - - /** - * Get generated value - * - * @return mixed|null - */ - public function getGeneratedValue() - { - return $this->generatedValue; - } -} diff --git a/src/Adapter/Driver/_Mysqli/Statement.php b/src/Adapter/Driver/_Mysqli/Statement.php deleted file mode 100644 index 59ae62aaa..000000000 --- a/src/Adapter/Driver/_Mysqli/Statement.php +++ /dev/null @@ -1,295 +0,0 @@ -bufferResults = (bool) $bufferResults; - } - - /** - * Set driver - * - * @return $this Provides a fluent interface - */ - public function setDriver(Mysqli $driver) - { - $this->driver = $driver; - return $this; - } - - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler) - { - $this->profiler = $profiler; - return $this; - } - - /** - * @return null|Profiler\ProfilerInterface - */ - public function getProfiler() - { - return $this->profiler; - } - - /** - * Initialize - * - * @return $this Provides a fluent interface - */ - public function initialize(\mysqli $mysqli) - { - $this->mysqli = $mysqli; - return $this; - } - - /** - * Set sql - * - * @param string $sql - * @return $this Provides a fluent interface - */ - public function setSql($sql) - { - $this->sql = $sql; - return $this; - } - - /** - * Set Parameter container - * - * @return $this Provides a fluent interface - */ - public function setParameterContainer(ParameterContainer $parameterContainer) - { - $this->parameterContainer = $parameterContainer; - return $this; - } - - /** - * Get resource - * - * @return mixed - */ - public function getResource() - { - return $this->resource; - } - - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(mysqli_stmt $mysqliStatement) - { - $this->resource = $mysqliStatement; - $this->isPrepared = true; - return $this; - } - - /** - * Get sql - * - * @return string - */ - public function getSql() - { - return $this->sql; - } - - /** - * Get parameter count - * - * @return ParameterContainer - */ - public function getParameterContainer() - { - return $this->parameterContainer; - } - - /** - * Is prepared - * - * @return bool - */ - public function isPrepared() - { - return $this->isPrepared; - } - - /** - * Prepare - * - * @param string $sql - * @return $this Provides a fluent interface - * @throws Exception\InvalidQueryException - * @throws Exception\RuntimeException - */ - public function prepare($sql = null) - { - if ($this->isPrepared) { - throw new Exception\RuntimeException('This statement has already been prepared'); - } - - $sql = $sql ?: $this->sql; - - $this->resource = $this->mysqli->prepare($sql); - if (! $this->resource instanceof mysqli_stmt) { - throw new Exception\InvalidQueryException( - 'Statement couldn\'t be produced with sql: ' . $sql, - $this->mysqli->errno, - new Exception\ErrorException($this->mysqli->error, $this->mysqli->errno) - ); - } - - $this->isPrepared = true; - return $this; - } - - /** - * Execute - * - * @param null|array|ParameterContainer $parameters - * @throws Exception\RuntimeException - * @return mixed - */ - public function execute($parameters = null) - { - if (! $this->isPrepared) { - $this->prepare(); - } - - /** START Standard ParameterContainer Merging Block */ - if (! $this->parameterContainer instanceof ParameterContainer) { - if ($parameters instanceof ParameterContainer) { - $this->parameterContainer = $parameters; - $parameters = null; - } else { - $this->parameterContainer = new ParameterContainer(); - } - } - - if (is_array($parameters)) { - $this->parameterContainer->setFromArray($parameters); - } - - if ($this->parameterContainer->count() > 0) { - $this->bindParametersFromContainer(); - } - /** END Standard ParameterContainer Merging Block */ - - if ($this->profiler) { - $this->profiler->profilerStart($this); - } - - $return = $this->resource->execute(); - - if ($this->profiler) { - $this->profiler->profilerFinish(); - } - - if ($return === false) { - throw new Exception\RuntimeException($this->resource->error); - } - - if ($this->bufferResults === true) { - $this->resource->store_result(); - $this->isPrepared = false; - $buffered = true; - } else { - $buffered = false; - } - - return $this->driver->createResult($this->resource, $buffered); - } - - /** - * Bind parameters from container - * - * @return void - */ - protected function bindParametersFromContainer() - { - $parameters = $this->parameterContainer->getNamedArray(); - $type = ''; - $args = []; - - foreach ($parameters as $name => &$value) { - if ($this->parameterContainer->offsetHasErrata($name)) { - switch ($this->parameterContainer->offsetGetErrata($name)) { - case ParameterContainer::TYPE_DOUBLE: - $type .= 'd'; - break; - case ParameterContainer::TYPE_NULL: - $value = null; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148 - case ParameterContainer::TYPE_INTEGER: - $type .= 'i'; - break; - case ParameterContainer::TYPE_STRING: - default: - $type .= 's'; - break; - } - } else { - $type .= 's'; - } - $args[] = &$value; - } - - if ($args) { - array_unshift($args, $type); - call_user_func_array([$this->resource, 'bind_param'], $args); - } - } -} diff --git a/src/Adapter/Platform/_Mysql.php b/src/Adapter/Platform/_Mysql.php deleted file mode 100644 index 6b0bd5470..000000000 --- a/src/Adapter/Platform/_Mysql.php +++ /dev/null @@ -1,126 +0,0 @@ -setDriver($driver); - } - } - - /** - * @param \Laminas\Db\Adapter\Driver\Mysqli\Mysqli|\Laminas\Db\Adapter\Driver\Pdo\Pdo|\mysqli|\PDO $driver - * @return $this Provides a fluent interface - * @throws InvalidArgumentException - */ - public function setDriver($driver) - { - // handle Laminas\Db drivers - if ( - $driver instanceof Mysqli\Mysqli - || ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() === 'Mysql') - || $driver instanceof \mysqli - || ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'mysql') - ) { - $this->driver = $driver; - return $this; - } - - throw new Exception\InvalidArgumentException( - '$driver must be a Mysqli or Mysql PDO Laminas\Db\Adapter\Driver, Mysqli instance or MySQL PDO instance' - ); - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return 'MySQL'; - } - - /** - * {@inheritDoc} - */ - public function quoteIdentifierChain($identifierChain) - { - return '`' . implode('`.`', (array) str_replace('`', '``', $identifierChain)) . '`'; - } - - /** - * {@inheritDoc} - */ - public function quoteValue($value) - { - $quotedViaDriverValue = $this->quoteViaDriver($value); - - return $quotedViaDriverValue ?? parent::quoteValue($value); - } - - /** - * {@inheritDoc} - */ - public function quoteTrustedValue($value) - { - $quotedViaDriverValue = $this->quoteViaDriver($value); - - return $quotedViaDriverValue ?? parent::quoteTrustedValue($value); - } - - /** - * @param string $value - * @return string|null - */ - protected function quoteViaDriver($value) - { - if ($this->driver instanceof DriverInterface) { - $resource = $this->driver->getConnection()->getResource(); - } else { - $resource = $this->driver; - } - - if ($resource instanceof \mysqli) { - return '\'' . $resource->real_escape_string($value) . '\''; - } - if ($resource instanceof \PDO) { - return $resource->quote($value); - } - - return null; - } -} diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php deleted file mode 100644 index 3ec0fdfda..000000000 --- a/src/ConfigProvider.php +++ /dev/null @@ -1,38 +0,0 @@ - $this->getDependencyConfig(), - ]; - } - - /** - * Retrieve laminas-db default dependency configuration. - * - * @return array - */ - public function getDependencyConfig() - { - // return [ - // 'abstract_factories' => [ - // Adapter\AdapterAbstractServiceFactory::class, - // ], - // 'factories' => [ - // Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, - // ], - // 'aliases' => [ - // Adapter\Adapter::class => Adapter\AdapterInterface::class, - // ], - // ]; - // } -} diff --git a/src/Container/MetadataFactory.php b/src/Container/MetadataFactory.php new file mode 100644 index 000000000..6f8d39da3 --- /dev/null +++ b/src/Container/MetadataFactory.php @@ -0,0 +1,28 @@ +has(AdapterInterface::class)) { + throw new ServiceNotFoundException(sprintf( + 'Service "%s" not found in container', + AdapterInterface::class + )); + } + + return new $requestedName( + $container->get(AdapterInterface::class), + ); + } +} diff --git a/src/Metadata/Source/Factory.php b/src/Metadata/Source/Factory.php index 650d14112..1c288c497 100644 --- a/src/Metadata/Source/Factory.php +++ b/src/Metadata/Source/Factory.php @@ -16,6 +16,7 @@ class Factory * * @return MetadataInterface * @throws InvalidArgumentException If adapter platform name not recognized. + * @deprecated to be removed in 3.0.0 */ public static function createSourceFromAdapter(AdapterInterface $adapter) { diff --git a/src/Metadata/Source/_MysqlMetadata.php b/src/Metadata/Source/_MysqlMetadata.php deleted file mode 100644 index 435bc5485..000000000 --- a/src/Metadata/Source/_MysqlMetadata.php +++ /dev/null @@ -1,542 +0,0 @@ -data['schemas'])) { - return; - } - $this->prepareDataHierarchy('schemas'); - - $p = $this->adapter->getPlatform(); - - $sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME') - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'SCHEMATA']) - . ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME') - . ' != \'INFORMATION_SCHEMA\''; - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $schemas = []; - foreach ($results->toArray() as $row) { - $schemas[] = $row['SCHEMA_NAME']; - } - - $this->data['schemas'] = $schemas; - } - - /** - * @param string $schema - * @return void - */ - protected function loadTableNameData($schema) - { - if (isset($this->data['table_names'][$schema])) { - return; - } - $this->prepareDataHierarchy('table_names', $schema); - - $p = $this->adapter->getPlatform(); - - $isColumns = [ - ['T', 'TABLE_NAME'], - ['T', 'TABLE_TYPE'], - ['V', 'VIEW_DEFINITION'], - ['V', 'CHECK_OPTION'], - ['V', 'IS_UPDATABLE'], - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' - - . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'VIEWS']) . ' V' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_NAME']) - - . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')'; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $tables = []; - foreach ($results->toArray() as $row) { - $tables[$row['TABLE_NAME']] = [ - 'table_type' => $row['TABLE_TYPE'], - 'view_definition' => $row['VIEW_DEFINITION'], - 'check_option' => $row['CHECK_OPTION'], - 'is_updatable' => 'YES' === $row['IS_UPDATABLE'], - ]; - } - - $this->data['table_names'][$schema] = $tables; - } - - /** - * @param string $table - * @param string $schema - * @return void - */ - protected function loadColumnData($table, $schema) - { - if (isset($this->data['columns'][$schema][$table])) { - return; - } - $this->prepareDataHierarchy('columns', $schema, $table); - $p = $this->adapter->getPlatform(); - - $isColumns = [ - ['C', 'ORDINAL_POSITION'], - ['C', 'COLUMN_DEFAULT'], - ['C', 'IS_NULLABLE'], - ['C', 'DATA_TYPE'], - ['C', 'CHARACTER_MAXIMUM_LENGTH'], - ['C', 'CHARACTER_OCTET_LENGTH'], - ['C', 'NUMERIC_PRECISION'], - ['C', 'NUMERIC_SCALE'], - ['C', 'COLUMN_NAME'], - ['C', 'COLUMN_TYPE'], - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'COLUMNS']) . 'C' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_NAME']) - . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')' - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteTrustedValue($table); - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - $columns = []; - foreach ($results->toArray() as $row) { - $erratas = []; - $matches = []; - if (preg_match('/^(?:enum|set)\((.+)\)$/i', $row['COLUMN_TYPE'], $matches)) { - $permittedValues = $matches[1]; - if ( - preg_match_all( - "/\\s*'((?:[^']++|'')*+)'\\s*(?:,|\$)/", - $permittedValues, - $matches, - PREG_PATTERN_ORDER - ) - ) { - $permittedValues = str_replace("''", "'", $matches[1]); - } else { - $permittedValues = [$permittedValues]; - } - $erratas['permitted_values'] = $permittedValues; - } - $columns[$row['COLUMN_NAME']] = [ - 'ordinal_position' => $row['ORDINAL_POSITION'], - 'column_default' => $row['COLUMN_DEFAULT'], - 'is_nullable' => 'YES' === $row['IS_NULLABLE'], - 'data_type' => $row['DATA_TYPE'], - 'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'], - 'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'], - 'numeric_precision' => $row['NUMERIC_PRECISION'], - 'numeric_scale' => $row['NUMERIC_SCALE'], - 'numeric_unsigned' => false !== strpos($row['COLUMN_TYPE'], 'unsigned'), - 'erratas' => $erratas, - ]; - } - - $this->data['columns'][$schema][$table] = $columns; - } - - /** - * @param string $table - * @param string $schema - * @return void - */ - protected function loadConstraintData($table, $schema) - { - // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - if (isset($this->data['constraints'][$schema][$table])) { - return; - } - - $this->prepareDataHierarchy('constraints', $schema, $table); - - $isColumns = [ - ['T', 'TABLE_NAME'], - ['TC', 'CONSTRAINT_NAME'], - ['TC', 'CONSTRAINT_TYPE'], - ['KCU', 'COLUMN_NAME'], - ['RC', 'MATCH_OPTION'], - ['RC', 'UPDATE_RULE'], - ['RC', 'DELETE_RULE'], - ['KCU', 'REFERENCED_TABLE_SCHEMA'], - ['KCU', 'REFERENCED_TABLE_NAME'], - ['KCU', 'REFERENCED_COLUMN_NAME'], - ]; - - $p = $this->adapter->getPlatform(); - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' T' - - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . ' TC' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) - - . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU' - . ' ON ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) - . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME']) - - . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . ' RC' - . ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) - . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME']) - - . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteTrustedValue($table) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')'; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_TYPE']) - . " WHEN 'PRIMARY KEY' THEN 1" - . " WHEN 'UNIQUE' THEN 2" - . " WHEN 'FOREIGN KEY' THEN 3" - . " ELSE 4 END" - - . ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) - . ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']); - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $realName = null; - $constraints = []; - foreach ($results->toArray() as $row) { - if ($row['CONSTRAINT_NAME'] !== $realName) { - $realName = $row['CONSTRAINT_NAME']; - $isFK = 'FOREIGN KEY' === $row['CONSTRAINT_TYPE']; - if ($isFK) { - $name = $realName; - } else { - $name = '_laminas_' . $row['TABLE_NAME'] . '_' . $realName; - } - $constraints[$name] = [ - 'constraint_name' => $name, - 'constraint_type' => $row['CONSTRAINT_TYPE'], - 'table_name' => $row['TABLE_NAME'], - 'columns' => [], - ]; - if ($isFK) { - $constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA']; - $constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME']; - $constraints[$name]['referenced_columns'] = []; - $constraints[$name]['match_option'] = $row['MATCH_OPTION']; - $constraints[$name]['update_rule'] = $row['UPDATE_RULE']; - $constraints[$name]['delete_rule'] = $row['DELETE_RULE']; - } - } - $constraints[$name]['columns'][] = $row['COLUMN_NAME']; - if ($isFK) { - $constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME']; - } - } - - $this->data['constraints'][$schema][$table] = $constraints; - // phpcs:enable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - } - - /** - * @param string $schema - * @return void - */ - protected function loadConstraintDataNames($schema) - { - if (isset($this->data['constraint_names'][$schema])) { - return; - } - - $this->prepareDataHierarchy('constraint_names', $schema); - - $p = $this->adapter->getPlatform(); - - $isColumns = [ - ['TC', 'TABLE_NAME'], - ['TC', 'CONSTRAINT_NAME'], - ['TC', 'CONSTRAINT_TYPE'], - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . 'TC' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) - . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')'; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $data = []; - foreach ($results->toArray() as $row) { - $data[] = array_change_key_case($row, CASE_LOWER); - } - - $this->data['constraint_names'][$schema] = $data; - } - - /** - * @param string $schema - * @return void - */ - protected function loadConstraintDataKeys($schema) - { - if (isset($this->data['constraint_keys'][$schema])) { - return; - } - - $this->prepareDataHierarchy('constraint_keys', $schema); - - $p = $this->adapter->getPlatform(); - - $isColumns = [ - ['T', 'TABLE_NAME'], - ['KCU', 'CONSTRAINT_NAME'], - ['KCU', 'COLUMN_NAME'], - ['KCU', 'ORDINAL_POSITION'], - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' - - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) - - . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')'; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $data = []; - foreach ($results->toArray() as $row) { - $data[] = array_change_key_case($row, CASE_LOWER); - } - - $this->data['constraint_keys'][$schema] = $data; - } - - /** - * @param string $table - * @param string $schema - * @return void - */ - protected function loadConstraintReferences($table, $schema) - { - parent::loadConstraintReferences($table, $schema); - - $p = $this->adapter->getPlatform(); - - $isColumns = [ - ['RC', 'TABLE_NAME'], - ['RC', 'CONSTRAINT_NAME'], - ['RC', 'UPDATE_RULE'], - ['RC', 'DELETE_RULE'], - ['KCU', 'REFERENCED_TABLE_SCHEMA'], - ['KCU', 'REFERENCED_TABLE_NAME'], - ['KCU', 'REFERENCED_COLUMN_NAME'], - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifierChain($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . 'FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' - - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . 'RC' - . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME']) - - . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU' - . ' ON ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) - . ' AND ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) - . ' AND ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME']) - . ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME']) - - . 'WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) - . ' IN (\'BASE TABLE\', \'VIEW\')'; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $data = []; - foreach ($results->toArray() as $row) { - $data[] = array_change_key_case($row, CASE_LOWER); - } - - $this->data['constraint_references'][$schema] = $data; - } - - /** - * @param string $schema - * @return void - */ - protected function loadTriggerData($schema) - { - if (isset($this->data['triggers'][$schema])) { - return; - } - - $this->prepareDataHierarchy('triggers', $schema); - - $p = $this->adapter->getPlatform(); - - $isColumns = [ - // 'TRIGGER_CATALOG', - // 'TRIGGER_SCHEMA', - 'TRIGGER_NAME', - 'EVENT_MANIPULATION', - 'EVENT_OBJECT_CATALOG', - 'EVENT_OBJECT_SCHEMA', - 'EVENT_OBJECT_TABLE', - 'ACTION_ORDER', - 'ACTION_CONDITION', - 'ACTION_STATEMENT', - 'ACTION_ORIENTATION', - 'ACTION_TIMING', - 'ACTION_REFERENCE_OLD_TABLE', - 'ACTION_REFERENCE_NEW_TABLE', - 'ACTION_REFERENCE_OLD_ROW', - 'ACTION_REFERENCE_NEW_ROW', - 'CREATED', - ]; - - array_walk($isColumns, function (&$c) use ($p) { - $c = $p->quoteIdentifier($c); - }); - - $sql = 'SELECT ' . implode(', ', $isColumns) - . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TRIGGERS']) - . ' WHERE '; - - if ($schema !== self::DEFAULT_SCHEMA) { - $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') - . ' = ' . $p->quoteTrustedValue($schema); - } else { - $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') - . ' != \'INFORMATION_SCHEMA\''; - } - - $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); - - $data = []; - foreach ($results->toArray() as $row) { - $row = array_change_key_case($row, CASE_LOWER); - if (null !== $row['created']) { - $row['created'] = new DateTime($row['created']); - } - $data[$row['trigger_name']] = $row; - } - - $this->data['triggers'][$schema] = $data; - } -} diff --git a/src/Module.php b/src/Module.php deleted file mode 100644 index fc116be43..000000000 --- a/src/Module.php +++ /dev/null @@ -1,19 +0,0 @@ - $provider->getDependencyConfig(), - ]; - } -} diff --git a/src/TableGateway/Feature/MetadataFeature.php b/src/TableGateway/Feature/MetadataFeature.php index 0b3afe713..89da476c4 100644 --- a/src/TableGateway/Feature/MetadataFeature.php +++ b/src/TableGateway/Feature/MetadataFeature.php @@ -5,7 +5,6 @@ use Laminas\Db\Metadata\MetadataInterface; use Laminas\Db\Metadata\Object\ConstraintObject; use Laminas\Db\Metadata\Object\TableObject; -use Laminas\Db\Metadata\Source\Factory as SourceFactory; use Laminas\Db\Sql\TableIdentifier; use Laminas\Db\TableGateway\Exception; @@ -15,17 +14,12 @@ class MetadataFeature extends AbstractFeature { - /** @var MetadataInterface */ - protected $metadata; - /** * Constructor */ - public function __construct(?MetadataInterface $metadata = null) - { - if ($metadata) { - $this->metadata = $metadata; - } + public function __construct( + protected MetadataInterface $metadata + ) { $this->sharedData['metadata'] = [ 'primaryKey' => null, 'columns' => [], @@ -34,10 +28,6 @@ public function __construct(?MetadataInterface $metadata = null) public function postInitialize() { - if ($this->metadata === null) { - $this->metadata = SourceFactory::createSourceFromAdapter($this->tableGateway->adapter); - } - // localize variable for brevity $t = $this->tableGateway; $m = $this->metadata; diff --git a/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php b/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php index fa17bbd65..8baf76151 100644 --- a/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php +++ b/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Adapter; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Adapter\AdapterAbstractServiceFactory; use Laminas\ServiceManager\Config; use Laminas\ServiceManager\Exception\ServiceNotFoundException; @@ -67,7 +67,7 @@ public static function providerInvalidService(): array public function testValidService(string $service): void { $actual = $this->serviceManager->get($service); - self::assertInstanceOf(Adapter::class, $actual); + self::assertInstanceOf(AdapterInterface::class, $actual); } /** From d5b3f4ec3ecbfdc9946a20e49353d4e290571686 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Wed, 14 May 2025 00:30:43 -0500 Subject: [PATCH 09/32] Temp removes ci constraint on which actions trigger workflow runs for the ci action. Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- .github/workflows/continuous-integration.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 9cf175e96..9253d0d48 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -4,8 +4,6 @@ on: pull_request: push: branches: - - '[0-9]+.[0-9]+.x' - - 'refs/pull/*' tags: jobs: From f29d5cfe4bd6f4871df565502f84db123e4843d4 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Thu, 15 May 2025 02:05:33 -0500 Subject: [PATCH 10/32] Refactoring around ConnectionInterface, AbstractConnection, AbstractPdoConnection Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/AbstractConnection.php | 76 +++++----------- src/Adapter/Driver/ConnectionInterface.php | 75 ++++++---------- .../Driver/Pdo/AbstractPdoConnection.php | 86 +++++++------------ 3 files changed, 78 insertions(+), 159 deletions(-) diff --git a/src/Adapter/Driver/AbstractConnection.php b/src/Adapter/Driver/AbstractConnection.php index bd5c0e393..509c4a5e9 100644 --- a/src/Adapter/Driver/AbstractConnection.php +++ b/src/Adapter/Driver/AbstractConnection.php @@ -4,35 +4,26 @@ use Laminas\Db\Adapter\Profiler\ProfilerAwareInterface; use Laminas\Db\Adapter\Profiler\ProfilerInterface; +use Override; abstract class AbstractConnection implements ConnectionInterface, ProfilerAwareInterface { - /** @var array */ - protected $connectionParameters = []; + protected array $connectionParameters = []; - /** @var string|null */ - protected $driverName; + protected ?string $driverName; - /** @var boolean */ - protected $inTransaction = false; + protected bool $inTransaction = false; - /** - * Nested transactions count. - * - * @var integer - */ - protected $nestedTransactionsCount = 0; + /** Nested transactions count. */ + protected int $nestedTransactionsCount = 0; - /** @var ProfilerInterface|null */ - protected $profiler; + protected ?ProfilerInterface $profiler; /** @var resource|null */ protected $resource; - /** - * {@inheritDoc} - */ - public function disconnect() + #[Override] + public function disconnect(): static { if ($this->isConnected()) { $this->resource = null; @@ -41,39 +32,24 @@ public function disconnect() return $this; } - /** - * Get connection parameters - * - * @return array - */ - public function getConnectionParameters() + /** Get connection parameters */ + public function getConnectionParameters(): array { return $this->connectionParameters; } - /** - * Get driver name - * - * @return null|string - */ - public function getDriverName() + /** Get driver name */ + public function getDriverName(): ?string { return $this->driverName; } - /** - * @return null|ProfilerInterface - */ - public function getProfiler() + public function getProfiler(): ?ProfilerInterface { return $this->profiler; } - /** - * {@inheritDoc} - * - * @return resource - */ + #[Override] public function getResource() { if (! $this->isConnected()) { @@ -83,32 +59,22 @@ public function getResource() return $this->resource; } - /** - * Checks whether the connection is in transaction state. - * - * @return boolean - */ - public function inTransaction() + /** Checks whether the connection is in transaction state. */ + public function inTransaction(): bool { return $this->inTransaction; } - /** - * @return $this Provides a fluent interface - */ - public function setConnectionParameters(array $connectionParameters) + public function setConnectionParameters(array $connectionParameters): static { $this->connectionParameters = $connectionParameters; return $this; } - /** - * {@inheritDoc} - * - * @return $this Provides a fluent interface - */ - public function setProfiler(ProfilerInterface $profiler) + /** @inheritDoc */ + #[Override] + public function setProfiler(ProfilerInterface $profiler): static { $this->profiler = $profiler; diff --git a/src/Adapter/Driver/ConnectionInterface.php b/src/Adapter/Driver/ConnectionInterface.php index 39ba2b3fe..563eac4c3 100644 --- a/src/Adapter/Driver/ConnectionInterface.php +++ b/src/Adapter/Driver/ConnectionInterface.php @@ -2,77 +2,54 @@ namespace Laminas\Db\Adapter\Driver; +/** + * + * @property $driver + */ interface ConnectionInterface { /** * Get current schema * - * @return string + * todo: narrow this to string|false when version bumps to PHP 8.2 minimum */ - public function getCurrentSchema(); + public function getCurrentSchema(): string|bool; /** * Get resource * - * @return mixed + * @return resource */ public function getResource(); - /** - * Connect - * - * @return ConnectionInterface - */ - public function connect(); + /** Connect */ + public function connect(): static; - /** - * Is connected - * - * @return bool - */ - public function isConnected(); + /** Is connected */ + public function isConnected(): bool; - /** - * Disconnect - * - * @return ConnectionInterface - */ - public function disconnect(); + /** Disconnect */ + public function disconnect(): static; - /** - * Begin transaction - * - * @return ConnectionInterface - */ - public function beginTransaction(); + /** Begin transaction */ + public function beginTransaction(): static; - /** - * Commit - * - * @return ConnectionInterface - */ - public function commit(); + /** Commit */ + public function commit(): static; - /** - * Rollback - * - * @return ConnectionInterface - */ - public function rollback(); + /** Rollback */ + public function rollback(): static; - /** - * Execute - * - * @param string $sql - * @return ResultInterface - */ - public function execute($sql); + /** Execute */ + public function execute(string $sql): ResultInterface; /** * Get last generated id * - * @param null $name Ignored - * @return int + * @param null $name Ignored (this is not ignored for PDO), imagine that... + * + * todo: narrow this to string|int|bool + * until version bumps to PHP 8.2 minimum then narrow to string|int|false */ - public function getLastGeneratedValue($name = null); + public function getLastGeneratedValue($name = null): string|int|bool|null; } diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php index 80cb8abe7..b7ba1c5b1 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -3,35 +3,32 @@ namespace Laminas\Db\Adapter\Driver\Pdo; use Laminas\Db\Adapter\Driver\AbstractConnection; +use Laminas\Db\Adapter\Driver\PdoDriverInterface; +use Laminas\Db\Adapter\Driver\ResultInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\Exception\RuntimeException; -use PDOException; -use PDOStatement; +use Override; -use function array_diff_key; -use function implode; use function is_array; -use function is_int; use function str_replace; use function strpos; use function strtolower; use function substr; -class AbstractPdoConnection extends AbstractConnection +abstract class AbstractPdoConnection extends AbstractConnection { - /** @var Pdo */ - protected $driver; + protected PdoDriverInterface $driver; /** @var \PDO */ - protected $resource; + protected \PDO $resource; /** @var string */ - protected $dsn; + protected ?string $dsn; /** * Constructor * - * @param array|\PDO|null $connectionParameters + * @param array|\PDO|null $connectionParameters * @throws Exception\InvalidArgumentException */ public function __construct($connectionParameters = null) @@ -42,27 +39,20 @@ public function __construct($connectionParameters = null) $this->setResource($connectionParameters); } elseif (null !== $connectionParameters) { throw new Exception\InvalidArgumentException( - '$connection must be an array of parameters, a PDO object or null' + '$connection must be an array of parameters, a \PDO object or null' ); } } - /** - * Set driver - * - * @return $this Provides a fluent interface - */ - public function setDriver(Pdo $driver) + public function setDriver(PdoDriverInterface $driver): static { $this->driver = $driver; return $this; } - /** - * {@inheritDoc} - */ - public function setConnectionParameters(array $connectionParameters) + #[Override] + public function setConnectionParameters(array $connectionParameters): static { $this->connectionParameters = $connectionParameters; if (isset($connectionParameters['dsn'])) { @@ -79,15 +69,16 @@ public function setConnectionParameters(array $connectionParameters) 3 )); } + + return $this; } /** * Get the dsn string for this connection * * @throws RuntimeException - * @return string */ - public function getDsn() + public function getDsn(): string { if (! $this->dsn) { throw new Exception\RuntimeException( @@ -99,7 +90,7 @@ public function getDsn() } /** - * {@inheritDoc} + * @inheritDoc */ // public function getCurrentSchema() // { @@ -132,12 +123,8 @@ public function getDsn() // return false; // } - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(\PDO $resource) + /** Set resource */ + public function setResource(\PDO $resource): static { $this->resource = $resource; $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); @@ -146,7 +133,7 @@ public function setResource(\PDO $resource) } /** - * {@inheritDoc} + * @inheritDoc * * @throws Exception\InvalidConnectionParametersException * @throws Exception\RuntimeException @@ -283,18 +270,14 @@ public function setResource(\PDO $resource) // return $this; // } - /** - * {@inheritDoc} - */ - public function isConnected() + /** @inheritDoc */ + public function isConnected(): bool { return $this->resource instanceof \PDO; } - /** - * {@inheritDoc} - */ - public function beginTransaction() + /** @inheritDoc */ + public function beginTransaction(): static { if (! $this->isConnected()) { $this->connect(); @@ -310,10 +293,8 @@ public function beginTransaction() return $this; } - /** - * {@inheritDoc} - */ - public function commit() + /** @inheritDoc */ + public function commit(): static { if (! $this->isConnected()) { $this->connect(); @@ -336,11 +317,11 @@ public function commit() } /** - * {@inheritDoc} + * @inheritDoc * * @throws Exception\RuntimeException */ - public function rollback() + public function rollback(): static { if (! $this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback'); @@ -359,11 +340,11 @@ public function rollback() } /** - * {@inheritDoc} + * @inheritDoc * * @throws Exception\InvalidQueryException */ - public function execute($sql) + public function execute($sql): ResultInterface { if (! $this->isConnected()) { $this->connect(); @@ -387,13 +368,8 @@ public function execute($sql) return $this->driver->createResult($resultResource, $sql); } - /** - * Prepare - * - * @param string $sql - * @return Statement - */ - public function prepare(string $sql) + /** Prepare a statement */ + public function prepare(string $sql): Statement { if (! $this->isConnected()) { $this->connect(); From f8baa9ab57d5afd7213ed6ccbbe3554170061404 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Thu, 15 May 2025 02:22:04 -0500 Subject: [PATCH 11/32] Signed-off-by: Joey Smith --- src/Adapter/Driver/ConnectionInterface.php | 1 + src/Adapter/Driver/Pdo/AbstractPdoConnection.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Adapter/Driver/ConnectionInterface.php b/src/Adapter/Driver/ConnectionInterface.php index 563eac4c3..e49e7e5da 100644 --- a/src/Adapter/Driver/ConnectionInterface.php +++ b/src/Adapter/Driver/ConnectionInterface.php @@ -5,6 +5,7 @@ /** * * @property $driver + * @property $resource */ interface ConnectionInterface { diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php index b7ba1c5b1..89be4cbfb 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -19,8 +19,8 @@ abstract class AbstractPdoConnection extends AbstractConnection { protected PdoDriverInterface $driver; - /** @var \PDO */ - protected \PDO $resource; + /** @var ?\PDO $resource */ + protected $resource; /** @var string */ protected ?string $dsn; From 05b6f9982ed1552e0bcdaec403c29d45933eba39 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Thu, 15 May 2025 02:24:38 -0500 Subject: [PATCH 12/32] Signed-off-by: Joey Smith --- src/Adapter/Driver/AbstractConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/AbstractConnection.php b/src/Adapter/Driver/AbstractConnection.php index 509c4a5e9..c0e5dd251 100644 --- a/src/Adapter/Driver/AbstractConnection.php +++ b/src/Adapter/Driver/AbstractConnection.php @@ -17,7 +17,7 @@ abstract class AbstractConnection implements ConnectionInterface, ProfilerAwareI /** Nested transactions count. */ protected int $nestedTransactionsCount = 0; - protected ?ProfilerInterface $profiler; + protected ?ProfilerInterface $profiler = null; /** @var resource|null */ protected $resource; From 6088adf2d39c4fae6d86dee69461e8622a499c34 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 16 May 2025 01:09:34 -0500 Subject: [PATCH 13/32] Refactor AdapterAwareInterface and Trait Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/AdapterAwareInterface.php | 8 ++------ src/Adapter/AdapterAwareTrait.php | 11 +++-------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Adapter/AdapterAwareInterface.php b/src/Adapter/AdapterAwareInterface.php index e598d9e61..018381031 100644 --- a/src/Adapter/AdapterAwareInterface.php +++ b/src/Adapter/AdapterAwareInterface.php @@ -4,10 +4,6 @@ interface AdapterAwareInterface { - /** - * Set db adapter - * - * @return AdapterAwareInterface - */ - public function setDbAdapter(AdapterInterface $adapter); + /** Set db adapter */ + public function setDbAdapter(AdapterInterface $adapter): static; } diff --git a/src/Adapter/AdapterAwareTrait.php b/src/Adapter/AdapterAwareTrait.php index 6cf7e34b7..7a7438a0d 100644 --- a/src/Adapter/AdapterAwareTrait.php +++ b/src/Adapter/AdapterAwareTrait.php @@ -4,15 +4,10 @@ trait AdapterAwareTrait { - /** @var Adapter */ - protected $adapter; + protected AdapterInterface $adapter; - /** - * Set db adapter - * - * @return $this Provides a fluent interface - */ - public function setDbAdapter(Adapter $adapter) + /** Set db adapter */ + public function setDbAdapter(AdapterInterface $adapter): static { $this->adapter = $adapter; From 68d0e22df93bd528c7195d18501f31369d6ea742 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 19 May 2025 23:11:47 -0500 Subject: [PATCH 14/32] DriverInterface::getDatabasePlatformName() signature change Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/DriverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/DriverInterface.php b/src/Adapter/Driver/DriverInterface.php index 914a5c58a..5de11cc64 100644 --- a/src/Adapter/Driver/DriverInterface.php +++ b/src/Adapter/Driver/DriverInterface.php @@ -15,7 +15,7 @@ interface DriverInterface * @param string $nameFormat * @return string */ - public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE); + public function getDatabasePlatformName($nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE); /** * Check environment From 0e01fa0eb657db86bd7fb2750c85f0bed77ad52d Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 19 May 2025 23:21:45 -0500 Subject: [PATCH 15/32] Signed-off-by: Joey Smith --- src/Adapter/Driver/DriverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/DriverInterface.php b/src/Adapter/Driver/DriverInterface.php index 5de11cc64..57f9c8f42 100644 --- a/src/Adapter/Driver/DriverInterface.php +++ b/src/Adapter/Driver/DriverInterface.php @@ -15,7 +15,7 @@ interface DriverInterface * @param string $nameFormat * @return string */ - public function getDatabasePlatformName($nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE); + public function getDatabasePlatformName($nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE): string; /** * Check environment From 674b5968158463f50cc000735f3d18dfd42ffaae Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 19 May 2025 23:26:18 -0500 Subject: [PATCH 16/32] Signed-off-by: Joey Smith --- src/Adapter/Driver/DriverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/DriverInterface.php b/src/Adapter/Driver/DriverInterface.php index 57f9c8f42..4bbb66f97 100644 --- a/src/Adapter/Driver/DriverInterface.php +++ b/src/Adapter/Driver/DriverInterface.php @@ -15,7 +15,7 @@ interface DriverInterface * @param string $nameFormat * @return string */ - public function getDatabasePlatformName($nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE): string; + public function getDatabasePlatformName(string $nameFormat = DriverInterface::NAME_FORMAT_CAMELCASE): string; /** * Check environment From 8bd2bb165491e4ed83eb0cf18b69c1035161f0d6 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 20 May 2025 23:01:05 -0500 Subject: [PATCH 17/32] Updating StatementInterface typing and \Pdo\Statement typing Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- .../Driver/Pdo/AbstractPdoConnection.php | 3 ++- src/Adapter/Driver/Pdo/Statement.php | 16 ++++-------- src/Adapter/Driver/StatementInterface.php | 25 +++++-------------- 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php index 89be4cbfb..364d9c4d8 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -5,6 +5,7 @@ use Laminas\Db\Adapter\Driver\AbstractConnection; use Laminas\Db\Adapter\Driver\PdoDriverInterface; use Laminas\Db\Adapter\Driver\ResultInterface; +use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\Exception\RuntimeException; use Override; @@ -369,7 +370,7 @@ public function execute($sql): ResultInterface } /** Prepare a statement */ - public function prepare(string $sql): Statement + public function prepare(?string $sql = null): StatementInterface { if (! $this->isConnected()) { $this->connect(); diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index 9d9d08e47..074fd08c0 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -3,6 +3,7 @@ namespace Laminas\Db\Adapter\Driver\Pdo; use Laminas\Db\Adapter\Driver\PdoDriverInterface; +use Laminas\Db\Adapter\Driver\ResultInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\ParameterContainer; @@ -147,7 +148,7 @@ public function getParameterContainer() * @param string $sql * @throws Exception\RuntimeException */ - public function prepare(?string $sql = null): ?static + public function prepare(?string $sql = null): StatementInterface { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); @@ -169,20 +170,13 @@ public function prepare(?string $sql = null): ?static return $this; } - /** - * @return bool - */ - public function isPrepared() + public function isPrepared(): bool { return $this->isPrepared; } - /** - * @param null|array|ParameterContainer $parameters - * @throws Exception\InvalidQueryException - * @return Result - */ - public function execute($parameters = null) + /** @throws Exception\InvalidQueryException */ + public function execute(null|array|ParameterContainer $parameters = null): ResultInterface { if (! $this->isPrepared) { $this->prepare(); diff --git a/src/Adapter/Driver/StatementInterface.php b/src/Adapter/Driver/StatementInterface.php index 298742f44..463e84b8a 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -14,25 +14,12 @@ interface StatementInterface extends StatementContainerInterface */ public function getResource(); - /** - * Prepare sql - * - * @param string $sql - */ - public function prepare(?string $sql = null): ?static; + /** Prepare sql */ + public function prepare(?string $sql = null): StatementInterface; - /** - * Check if is prepared - * - * @return bool - */ - public function isPrepared(); + /** Check if is prepared */ + public function isPrepared(): bool; - /** - * Execute - * - * @param null|array|ParameterContainer $parameters - * @return ResultInterface - */ - public function execute($parameters = null); + /** Execute */ + public function execute(null|array|ParameterContainer $parameters = null): ResultInterface; } From 4aed88e65bbcfd7da18d7aac8632569858787182 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Wed, 21 May 2025 00:31:41 -0500 Subject: [PATCH 18/32] Updating StatementInterface::execute to nullable return type Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/StatementInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/StatementInterface.php b/src/Adapter/Driver/StatementInterface.php index 463e84b8a..1ae0592a8 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -21,5 +21,5 @@ public function prepare(?string $sql = null): StatementInterface; public function isPrepared(): bool; /** Execute */ - public function execute(null|array|ParameterContainer $parameters = null): ResultInterface; + public function execute(null|array|ParameterContainer $parameters = null): ?ResultInterface; } From b046b577c5830b77d0df1882e5ee2bf1192aa8c3 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Wed, 21 May 2025 00:34:56 -0500 Subject: [PATCH 19/32] Updating \Pdo\Statement::execute to nullable return type Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/Statement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index 074fd08c0..ce33f5ab7 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -176,7 +176,7 @@ public function isPrepared(): bool } /** @throws Exception\InvalidQueryException */ - public function execute(null|array|ParameterContainer $parameters = null): ResultInterface + public function execute(null|array|ParameterContainer $parameters = null): ?ResultInterface { if (! $this->isPrepared) { $this->prepare(); From 838ef3d06d9a4c79cb4ecea73a8bc5106972ee39 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Thu, 22 May 2025 02:53:27 -0500 Subject: [PATCH 20/32] Refactoring typing \Pdo\AbstractPdo \Pdo\Statement \Driver\DriverInterface \Adapter\StatementContainerInterface Introduces DriverAwareInterface, PdoDriverAwareInterface Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/DriveAwareInterface.php | 11 ++ src/Adapter/Driver/DriverInterface.php | 55 ++---- src/Adapter/Driver/Pdo/AbstractPdo.php | 160 ++++++------------ src/Adapter/Driver/Pdo/Statement.php | 114 ++++--------- .../Driver/PdoDriverAwareInterface.php | 11 ++ src/Adapter/StatementContainerInterface.php | 31 +--- 6 files changed, 124 insertions(+), 258 deletions(-) create mode 100644 src/Adapter/Driver/DriveAwareInterface.php create mode 100644 src/Adapter/Driver/PdoDriverAwareInterface.php diff --git a/src/Adapter/Driver/DriveAwareInterface.php b/src/Adapter/Driver/DriveAwareInterface.php new file mode 100644 index 000000000..8e11713fd --- /dev/null +++ b/src/Adapter/Driver/DriveAwareInterface.php @@ -0,0 +1,11 @@ +registerConnection($connection); - $this->registerStatementPrototype($statementPrototype ?: new Statement()); - $this->registerResultPrototype($resultPrototype ?: new Result()); - if (is_array($features)) { - foreach ($features as $name => $feature) { - $this->addFeature($name, $feature); - } - } elseif ($features instanceof AbstractFeature) { - $this->addFeature($features->getName(), $features); - } elseif ($features === self::FEATURES_DEFAULT) { - $this->setupDefaultFeatures(); - } - } - - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler) + public function setProfiler(Profiler\ProfilerInterface $profiler): static { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { @@ -87,26 +47,11 @@ public function setProfiler(Profiler\ProfilerInterface $profiler) return $this; } - /** - * @return null|Profiler\ProfilerInterface - */ - public function getProfiler() + public function getProfiler(): ?Profiler\ProfilerInterface { return $this->profiler; } - /** - * Register connection - * - * @return $this Provides a fluent interface - */ - // public function registerConnection(Connection $connection) - // { - // $this->connection = $connection; - // $this->connection->setDriver($this); - // return $this; - // } - /** * Register statement prototype */ @@ -219,29 +164,27 @@ public function getFeature($name) /** * Check environment */ - public function checkEnvironment() + public function checkEnvironment(): bool { if (! extension_loaded('PDO')) { throw new Exception\RuntimeException( 'The PDO extension is required for this adapter but the extension is not loaded' ); } + return true; } - /** - * @return Connection - */ - public function getConnection() + public function getConnection(): ConnectionInterface { return $this->connection; } /** * @param string|PDOStatement $sqlOrResource - * @return Statement */ - public function createStatement($sqlOrResource = null) + public function createStatement($sqlOrResource = null): StatementInterface { + /** @var Statement */ $statement = clone $this->statementPrototype; if ($sqlOrResource instanceof PDOStatement) { $statement->setResource($sqlOrResource); @@ -252,7 +195,9 @@ public function createStatement($sqlOrResource = null) if (! $this->connection->isConnected()) { $this->connection->connect(); } - $statement->initialize($this->connection->getResource()); + /** @var \PDO */ + $resource = $this->connection->getResource(); + $statement->initialize($resource); } return $statement; } @@ -262,32 +207,32 @@ public function createStatement($sqlOrResource = null) * @param mixed $context * @return Result */ - public function createResult($resource, $context = null) - { - $result = clone $this->resultPrototype; - $rowCount = null; - - // special feature, sqlite PDO counter - if ( - $this->connection->getDriverName() === 'sqlite' - && ($sqliteRowCounter = $this->getFeature('SqliteRowCounter')) - && $resource->columnCount() > 0 - ) { - $rowCount = $sqliteRowCounter->getRowCountClosure($context); - } + // public function createResult($resource, $context = null): ResultInterface + // { + // $result = clone $this->resultPrototype; + // $rowCount = null; + + // // special feature, sqlite PDO counter + // if ( + // $this->connection->getDriverName() === 'sqlite' + // && ($sqliteRowCounter = $this->getFeature('SqliteRowCounter')) + // && $resource->columnCount() > 0 + // ) { + // $rowCount = $sqliteRowCounter->getRowCountClosure($context); + // } - // special feature, oracle PDO counter - if ( - $this->connection->getDriverName() === 'oci' - && ($oracleRowCounter = $this->getFeature('OracleRowCounter')) - && $resource->columnCount() > 0 - ) { - $rowCount = $oracleRowCounter->getRowCountClosure($context); - } + // // special feature, oracle PDO counter + // if ( + // $this->connection->getDriverName() === 'oci' + // && ($oracleRowCounter = $this->getFeature('OracleRowCounter')) + // && $resource->columnCount() > 0 + // ) { + // $rowCount = $oracleRowCounter->getRowCountClosure($context); + // } - $result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount); - return $result; - } + // $result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount); + // return $result; + // } /** * @return Result @@ -300,17 +245,12 @@ public function getResultPrototype() /** * @return string */ - public function getPrepareType() + public function getPrepareType(): string { return self::PARAMETERIZATION_NAMED; } - /** - * @param string $name - * @param string|null $type - * @return string - */ - public function formatParameterName($name, $type = null) + public function formatParameterName(string $name, ?string $type = null): string { if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { $name = ltrim($name, ':'); @@ -329,11 +269,7 @@ public function formatParameterName($name, $type = null) return '?'; } - /** - * @param string|null $name - * @return string|null|false - */ - public function getLastGeneratedValue($name = null) + public function getLastGeneratedValue(?string $name = null): int|string|null|false { return $this->connection->getLastGeneratedValue($name); } diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index ce33f5ab7..6a05062dc 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -2,12 +2,14 @@ namespace Laminas\Db\Adapter\Driver\Pdo; +use Laminas\Db\Adapter\Driver\PdoDriverAwareInterface; use Laminas\Db\Adapter\Driver\PdoDriverInterface; use Laminas\Db\Adapter\Driver\ResultInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\ParameterContainer; use Laminas\Db\Adapter\Profiler; +use PDO; use PDOException; use PDOStatement; @@ -16,138 +18,88 @@ use function is_bool; use function is_int; -class Statement implements StatementInterface, Profiler\ProfilerAwareInterface +class Statement implements StatementInterface, PdoDriverAwareInterface, Profiler\ProfilerAwareInterface { - /** @var \PDO */ - protected $pdo; + protected PDO $pdo; - /** @var Profiler\ProfilerInterface */ - protected $profiler; + protected Profiler\ProfilerInterface $profiler; - /** @var Pdo */ - protected $driver; + protected PdoDriverInterface $driver; - /** @var string */ - protected $sql = ''; + protected string $sql = ''; - /** @var bool */ - protected $isQuery; + protected bool $isQuery; - /** @var ParameterContainer */ - protected $parameterContainer; + protected ParameterContainer $parameterContainer; - /** @var bool */ - protected $parametersBound = false; + protected bool $parametersBound = false; - /** @var PDOStatement */ - protected $resource; + protected ?PDOStatement $resource; - /** @var bool */ - protected $isPrepared = false; + protected bool $isPrepared = false; - /** - * Set driver - * - * @return $this Provides a fluent interface - */ - public function setDriver(PdoDriverInterface $driver): self + public function setDriver(PdoDriverInterface $driver): static { $this->driver = $driver; return $this; } - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler): self + public function setProfiler(Profiler\ProfilerInterface $profiler): static { $this->profiler = $profiler; return $this; } - /** - * @return null|Profiler\ProfilerInterface - */ public function getProfiler(): ?Profiler\ProfilerInterface { return $this->profiler; } - /** - * Initialize - * - * @return $this Provides a fluent interface - */ - public function initialize(\PDO $connectionResource) + /** Initialize */ + public function initialize(PDO $connectionResource): static { $this->pdo = $connectionResource; return $this; } - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(PDOStatement $pdoStatement) + /** Set resource */ + public function setResource(PDOStatement $pdoStatement): static { $this->resource = $pdoStatement; return $this; } - /** - * Get resource - * - * @return mixed - */ - public function getResource() + /** Get resource */ + public function getResource(): ?PDOStatement { return $this->resource; } - /** - * Set sql - * - * @param string $sql - * @return $this Provides a fluent interface - */ - public function setSql($sql): static + /** Set sql */ + public function setSql(?string $sql): static { $this->sql = $sql; return $this; } - /** - * Get sql - * - * @return string - */ + /** Get sql */ public function getSql(): ?string { return $this->sql; } - /** - * @return $this Provides a fluent interface - */ - public function setParameterContainer(ParameterContainer $parameterContainer) + public function setParameterContainer(ParameterContainer $parameterContainer): static { $this->parameterContainer = $parameterContainer; return $this; } - /** - * @return ParameterContainer - */ - public function getParameterContainer() + public function getParameterContainer(): ?ParameterContainer { return $this->parameterContainer; } - /** - * @param string $sql - * @throws Exception\RuntimeException - */ + /** @throws Exception\RuntimeException */ public function prepare(?string $sql = null): StatementInterface { if ($this->isPrepared) { @@ -231,10 +183,8 @@ public function execute(null|array|ParameterContainer $parameters = null): ?Resu return $this->driver->createResult($this->resource, $this); } - /** - * Bind parameters from container - */ - protected function bindParametersFromContainer() + /** Bind parameters from container */ + protected function bindParametersFromContainer(): void { if ($this->parametersBound) { return; @@ -269,12 +219,8 @@ protected function bindParametersFromContainer() } } - /** - * Perform a deep clone - * - * @return void - */ - public function __clone() + /** Perform a deep clone */ + public function __clone(): void { $this->isPrepared = false; $this->parametersBound = false; diff --git a/src/Adapter/Driver/PdoDriverAwareInterface.php b/src/Adapter/Driver/PdoDriverAwareInterface.php new file mode 100644 index 000000000..b60504930 --- /dev/null +++ b/src/Adapter/Driver/PdoDriverAwareInterface.php @@ -0,0 +1,11 @@ + Date: Fri, 23 May 2025 01:00:18 -0500 Subject: [PATCH 21/32] Fixed type in DriverAwareInterface file/class name Fixed Interface return types to reflect the Interface being returned Adds strict typing to all classes / interfaces Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- ...Interface.php => DriverAwareInterface.php} | 4 +- src/Adapter/Driver/Pdo/Statement.php | 49 +++++++++---------- .../Driver/PdoDriverAwareInterface.php | 2 +- .../Profiler/ProfilerAwareInterface.php | 5 +- src/Adapter/StatementContainerInterface.php | 6 ++- 5 files changed, 35 insertions(+), 31 deletions(-) rename src/Adapter/Driver/{DriveAwareInterface.php => DriverAwareInterface.php} (55%) diff --git a/src/Adapter/Driver/DriveAwareInterface.php b/src/Adapter/Driver/DriverAwareInterface.php similarity index 55% rename from src/Adapter/Driver/DriveAwareInterface.php rename to src/Adapter/Driver/DriverAwareInterface.php index 8e11713fd..d8bba4622 100644 --- a/src/Adapter/Driver/DriveAwareInterface.php +++ b/src/Adapter/Driver/DriverAwareInterface.php @@ -4,8 +4,8 @@ namespace Laminas\Db\Adapter\Driver; -interface DriveAwareInterface +interface DriverAwareInterface { /** Implementation should provide a fluent interface */ - public function setDriver(DriverInterface $driver): static; + public function setDriver(DriverInterface $driver): DriverAwareInterface; } diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index 6a05062dc..d1d0142d2 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -1,5 +1,7 @@ driver = $driver; return $this; } - public function setProfiler(Profiler\ProfilerInterface $profiler): static + public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; return $this; } - public function getProfiler(): ?Profiler\ProfilerInterface + public function getProfiler(): ?ProfilerInterface { return $this->profiler; } @@ -76,7 +80,7 @@ public function getResource(): ?PDOStatement } /** Set sql */ - public function setSql(?string $sql): static + public function setSql(?string $sql): StatementContainerInterface { $this->sql = $sql; return $this; @@ -88,7 +92,7 @@ public function getSql(): ?string return $this->sql; } - public function setParameterContainer(ParameterContainer $parameterContainer): static + public function setParameterContainer(ParameterContainer $parameterContainer): StatementContainerInterface { $this->parameterContainer = $parameterContainer; return $this; @@ -153,16 +157,13 @@ public function execute(null|array|ParameterContainer $parameters = null): ?Resu } /** END Standard ParameterContainer Merging Block */ - if ($this->profiler) { - $this->profiler->profilerStart($this); - } + $this->profiler?->profilerStart($this); try { $this->resource->execute(); } catch (PDOException $e) { - if ($this->profiler) { - $this->profiler->profilerFinish(); - } + + $this->profiler?->profilerFinish(); $code = $e->getCode(); if (! is_int($code)) { @@ -176,9 +177,7 @@ public function execute(null|array|ParameterContainer $parameters = null): ?Resu ); } - if ($this->profiler) { - $this->profiler->profilerFinish(); - } + $this->profiler?->profilerFinish(); return $this->driver->createResult($this->resource, $this); } @@ -193,22 +192,22 @@ protected function bindParametersFromContainer(): void $parameters = $this->parameterContainer->getNamedArray(); foreach ($parameters as $name => &$value) { if (is_bool($value)) { - $type = \PDO::PARAM_BOOL; + $type = PDO::PARAM_BOOL; } elseif (is_int($value)) { - $type = \PDO::PARAM_INT; + $type = PDO::PARAM_INT; } else { - $type = \PDO::PARAM_STR; + $type = PDO::PARAM_STR; } if ($this->parameterContainer->offsetHasErrata($name)) { switch ($this->parameterContainer->offsetGetErrata($name)) { case ParameterContainer::TYPE_INTEGER: - $type = \PDO::PARAM_INT; + $type = PDO::PARAM_INT; break; case ParameterContainer::TYPE_NULL: - $type = \PDO::PARAM_NULL; + $type = PDO::PARAM_NULL; break; case ParameterContainer::TYPE_LOB: - $type = \PDO::PARAM_LOB; + $type = PDO::PARAM_LOB; break; } } diff --git a/src/Adapter/Driver/PdoDriverAwareInterface.php b/src/Adapter/Driver/PdoDriverAwareInterface.php index b60504930..32eb0b55b 100644 --- a/src/Adapter/Driver/PdoDriverAwareInterface.php +++ b/src/Adapter/Driver/PdoDriverAwareInterface.php @@ -7,5 +7,5 @@ interface PdoDriverAwareInterface { /** Implementation should provide a fluent interface */ - public function setDriver(PdoDriverInterface $driver): static; + public function setDriver(PdoDriverInterface $driver): PdoDriverAwareInterface; } diff --git a/src/Adapter/Profiler/ProfilerAwareInterface.php b/src/Adapter/Profiler/ProfilerAwareInterface.php index dcab62d15..f0566f6eb 100644 --- a/src/Adapter/Profiler/ProfilerAwareInterface.php +++ b/src/Adapter/Profiler/ProfilerAwareInterface.php @@ -1,8 +1,11 @@ Date: Fri, 23 May 2025 02:06:58 -0500 Subject: [PATCH 22/32] Interface typing Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/AbstractConnection.php | 6 ++-- src/Adapter/Driver/ConnectionInterface.php | 19 +++++------- .../Driver/Pdo/AbstractPdoConnection.php | 29 +++++++++++-------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Adapter/Driver/AbstractConnection.php b/src/Adapter/Driver/AbstractConnection.php index c0e5dd251..6d42c15c2 100644 --- a/src/Adapter/Driver/AbstractConnection.php +++ b/src/Adapter/Driver/AbstractConnection.php @@ -1,5 +1,7 @@ isConnected()) { $this->resource = null; @@ -74,7 +76,7 @@ public function setConnectionParameters(array $connectionParameters): static /** @inheritDoc */ #[Override] - public function setProfiler(ProfilerInterface $profiler): static + public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; diff --git a/src/Adapter/Driver/ConnectionInterface.php b/src/Adapter/Driver/ConnectionInterface.php index e49e7e5da..4103fdc28 100644 --- a/src/Adapter/Driver/ConnectionInterface.php +++ b/src/Adapter/Driver/ConnectionInterface.php @@ -1,12 +1,9 @@ setConnectionParameters($connectionParameters); - } elseif ($connectionParameters instanceof \PDO) { + } elseif ($connectionParameters instanceof PDO) { $this->setResource($connectionParameters); } elseif (null !== $connectionParameters) { throw new Exception\InvalidArgumentException( @@ -45,7 +50,7 @@ public function __construct($connectionParameters = null) } } - public function setDriver(PdoDriverInterface $driver): static + public function setDriver(PdoDriverInterface $driver): PdoDriverAwareInterface { $this->driver = $driver; @@ -125,10 +130,10 @@ public function getDsn(): string // } /** Set resource */ - public function setResource(\PDO $resource): static + public function setResource(PDO $resource): static { $this->resource = $resource; - $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); + $this->driverName = strtolower($this->resource->getAttribute(PDO::ATTR_DRIVER_NAME)); return $this; } @@ -274,11 +279,11 @@ public function setResource(\PDO $resource): static /** @inheritDoc */ public function isConnected(): bool { - return $this->resource instanceof \PDO; + return $this->resource instanceof PDO; } /** @inheritDoc */ - public function beginTransaction(): static + public function beginTransaction(): ConnectionInterface { if (! $this->isConnected()) { $this->connect(); @@ -295,7 +300,7 @@ public function beginTransaction(): static } /** @inheritDoc */ - public function commit(): static + public function commit(): ConnectionInterface { if (! $this->isConnected()) { $this->connect(); @@ -322,7 +327,7 @@ public function commit(): static * * @throws Exception\RuntimeException */ - public function rollback(): static + public function rollback(): ConnectionInterface { if (! $this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback'); @@ -345,7 +350,7 @@ public function rollback(): static * * @throws Exception\InvalidQueryException */ - public function execute($sql): ResultInterface + public function execute($sql): ?ResultInterface { if (! $this->isConnected()) { $this->connect(); From 213e6d3606c085382dc6a7885496b9ff4f471910 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 23 May 2025 02:35:45 -0500 Subject: [PATCH 23/32] Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdo.php | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index 26ed5ce51..dfcf9650d 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -1,5 +1,7 @@ profiler = $profiler; - if ($this->connection instanceof Profiler\ProfilerAwareInterface) { + if ($this->connection instanceof ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } - if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { + if ($this->statementPrototype instanceof ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } - public function getProfiler(): ?Profiler\ProfilerInterface + public function getProfiler(): ?ProfilerInterface { return $this->profiler; } @@ -55,7 +58,7 @@ public function getProfiler(): ?Profiler\ProfilerInterface /** * Register statement prototype */ - public function registerStatementPrototype(Statement $statementPrototype) + public function registerStatementPrototype(StatementInterface $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); @@ -64,7 +67,7 @@ public function registerStatementPrototype(Statement $statementPrototype) /** * Register result prototype */ - public function registerResultPrototype(Result $resultPrototype) + public function registerResultPrototype(ResultInterface $resultPrototype) { $this->resultPrototype = $resultPrototype; } @@ -72,6 +75,8 @@ public function registerResultPrototype(Result $resultPrototype) /** * Add feature * + * todo: needs improvement + * * @param string $name * @param AbstractFeature $feature * @return $this Provides a fluent interface @@ -180,6 +185,7 @@ public function getConnection(): ConnectionInterface } /** + * todo: this needs improved * @param string|PDOStatement $sqlOrResource */ public function createStatement($sqlOrResource = null): StatementInterface @@ -234,17 +240,11 @@ public function createStatement($sqlOrResource = null): StatementInterface // return $result; // } - /** - * @return Result - */ - public function getResultPrototype() + public function getResultPrototype(): ?ResultInterface { return $this->resultPrototype; } - /** - * @return string - */ public function getPrepareType(): string { return self::PARAMETERIZATION_NAMED; From 1d6a4640a766d9d32833199061aee83bdb8ffc99 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 24 May 2025 11:40:12 -0500 Subject: [PATCH 24/32] Fixing formatParameterName parameter typing for $name Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index dfcf9650d..e7b56c149 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -250,7 +250,7 @@ public function getPrepareType(): string return self::PARAMETERIZATION_NAMED; } - public function formatParameterName(string $name, ?string $type = null): string + public function formatParameterName(string|int $name, ?string $type = null): string { if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { $name = ltrim($name, ':'); From 924aa675d7cca37ad5ec004134f3a40b277635cd Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 24 May 2025 13:07:28 -0500 Subject: [PATCH 25/32] testing temp fix for formatParameterName Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdo.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index e7b56c149..03fbff4ae 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -17,6 +17,7 @@ use PDOStatement; use function extension_loaded; +use function is_int; use function is_numeric; use function is_string; use function ltrim; @@ -253,6 +254,11 @@ public function getPrepareType(): string public function formatParameterName(string|int $name, ?string $type = null): string { if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { + // temporary fix for passing $name as int with type self::PARAMETERIZATION_NAMED + if (is_int($name) && $type === self::PARAMETERIZATION_NAMED) { + $name = (string) $name; + } + // end temporary fix $name = ltrim($name, ':'); // @see https://bugs.php.net/bug.php?id=43130 if (preg_match('/[^a-zA-Z0-9_]/', $name)) { From 3525c630107828dd8d96f10e798e9aea43aa0f42 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 24 May 2025 13:10:06 -0500 Subject: [PATCH 26/32] updating temp fix to proposed fix, see comment in AbstractPdo::formatParameterName Typing at DriverInterface definition remains typed as (string $name) Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index 03fbff4ae..445798d36 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -254,11 +254,11 @@ public function getPrepareType(): string public function formatParameterName(string|int $name, ?string $type = null): string { if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { - // temporary fix for passing $name as int with type self::PARAMETERIZATION_NAMED + // proposed fix for passing $name as int with type self::PARAMETERIZATION_NAMED if (is_int($name) && $type === self::PARAMETERIZATION_NAMED) { $name = (string) $name; } - // end temporary fix + // end proposed fix $name = ltrim($name, ':'); // @see https://bugs.php.net/bug.php?id=43130 if (preg_match('/[^a-zA-Z0-9_]/', $name)) { From 8236c4db216a88a267b726880c5bc2dc56065752 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sat, 24 May 2025 16:31:17 -0500 Subject: [PATCH 27/32] Aligning for integration test Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdoConnection.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php index cbdd460dc..b372b7b99 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -23,7 +23,7 @@ abstract class AbstractPdoConnection extends AbstractConnection implements PdoDriverAwareInterface { - protected PdoDriverInterface $driver; + protected ?PdoDriverInterface $driver = null; /** @var ?PDO $resource */ protected $resource; @@ -34,11 +34,11 @@ abstract class AbstractPdoConnection extends AbstractConnection implements PdoDr /** * Constructor * - * @param array|PDO|null $connectionParameters * @throws Exception\InvalidArgumentException */ - public function __construct($connectionParameters = null) - { + public function __construct( + array|PDO|null $connectionParameters = null + ){ if (is_array($connectionParameters)) { $this->setConnectionParameters($connectionParameters); } elseif ($connectionParameters instanceof PDO) { From a700452ca7fc3465231fd8d8cb131d19d813edbd Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sun, 25 May 2025 04:51:14 -0500 Subject: [PATCH 28/32] Package initialization refactoring Providing AdapterManager via ServiceManager v4 Updates SM dependency to v4 Updates lock file Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 9 +- composer.lock | 881 ++++++++++----------- src/Adapter/AbstractAdapter.php | 263 +++--- src/Adapter/AdapterServiceDelegator.php | 29 +- src/Adapter/AdapterServiceFactory.php | 10 - src/Adapter/ConfigInterface.php | 7 + src/Adapter/Driver/ConnectionInterface.php | 11 +- src/Adapter/SchemaAwareInterface.php | 15 + src/Container/AdapterInterfaceFactory.php | 16 + src/Container/AdapterManager.php | 83 ++ src/Container/AdapterManagerFactory.php | 27 + src/Container/ConfigProvider.php | 24 + src/Metadata/Source/AbstractSource.php | 12 +- 13 files changed, 726 insertions(+), 661 deletions(-) create mode 100644 src/Adapter/ConfigInterface.php create mode 100644 src/Adapter/SchemaAwareInterface.php create mode 100644 src/Container/AdapterInterfaceFactory.php create mode 100644 src/Container/AdapterManager.php create mode 100644 src/Container/AdapterManagerFactory.php create mode 100644 src/Container/ConfigProvider.php diff --git a/composer.json b/composer.json index d3aa8c506..899f7bd1b 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,11 @@ "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } + }, + "extra": { + "laminas": { + "config-provider": "Laminas\\Db\\Container\\ConfigProvider" + } }, "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", @@ -32,7 +37,6 @@ "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", "laminas/laminas-eventmanager": "^3.14.0", - "laminas/laminas-servicemanager": "^4.0.0", "phpunit/phpunit": "^11.5.12", "psalm/plugin-phpunit": "^0.19.2", "rector/rector": "^2.0", @@ -40,8 +44,7 @@ }, "suggest": { "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" + "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 3b43a85c5..3cc8b5a20 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,142 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "25d9661790a6bab19a3198c0f8698fc1", + "content-hash": "730ab75da70f67ee223631a8ce00e3bb", "packages": [ + { + "name": "brick/varexporter", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/brick/varexporter.git", + "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/varexporter/zipball/84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", + "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.3", + "psalm/phar": "5.21.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\VarExporter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A powerful alternative to var_export(), which can export closures and objects without __set_state()", + "keywords": [ + "var_export" + ], + "support": { + "issues": "https://github.com/brick/varexporter/issues", + "source": "https://github.com/brick/varexporter/tree/0.5.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2024-05-10T17:15:19+00:00" + }, + { + "name": "laminas/laminas-servicemanager", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-servicemanager.git", + "reference": "74da44d07e493b834347123242d0047976fb9932" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/74da44d07e493b834347123242d0047976fb9932", + "reference": "74da44d07e493b834347123242d0047976fb9932", + "shasum": "" + }, + "require": { + "brick/varexporter": "^0.3.8 || ^0.4.0 || ^0.5.0", + "laminas/laminas-stdlib": "^3.19", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/container": "^1.1 || ^2.0" + }, + "conflict": { + "laminas/laminas-code": "<4.10.0", + "zendframework/zend-code": "<3.3.1" + }, + "provide": { + "psr/container-implementation": "^1.0 || ^2.0" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11.99.5", + "friendsofphp/proxy-manager-lts": "^1.0.18", + "laminas/laminas-cli": "^1.11", + "laminas/laminas-coding-standard": "~3.0.1", + "laminas/laminas-container-config-test": "^1.0", + "mikey179/vfsstream": "^1.6.12", + "phpbench/phpbench": "^1.4.0", + "phpunit/phpunit": "^10.5.44", + "psalm/plugin-phpunit": "^0.19.2", + "symfony/console": "^6.4.17 || ^7.0", + "vimeo/psalm": "^6.2.0" + }, + "suggest": { + "friendsofphp/proxy-manager-lts": "To handle lazy initialization of services", + "laminas/laminas-cli": "To consume CLI commands provided by this component" + }, + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ServiceManager", + "config-provider": "Laminas\\ServiceManager\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Laminas\\ServiceManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Factory-Driven Dependency Injection Container", + "homepage": "https://laminas.dev", + "keywords": [ + "PSR-11", + "dependency-injection", + "di", + "dic", + "laminas", + "service-manager", + "servicemanager" + ], + "support": { + "chat": "https://laminas.dev/chat", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-servicemanager/issues", + "source": "https://github.com/laminas/laminas-servicemanager/tree/4.4.0" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2025-02-04T06:13:50+00:00" + }, { "name": "laminas/laminas-stdlib", "version": "3.20.0", @@ -64,6 +198,117 @@ } ], "time": "2024-10-29T13:46:07+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + }, + "time": "2024-12-30T11:07:19+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" } ], "packages-dev": [ @@ -875,79 +1120,6 @@ ], "time": "2024-08-03T19:31:26+00:00" }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, { "name": "composer/pcre", "version": "3.3.2", @@ -1387,26 +1559,29 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "1.4.10 || 2.0.3", + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -1426,9 +1601,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.4" + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" }, - "time": "2024-12-07T21:18:45+00:00" + "time": "2025-04-07T20:06:18+00:00" }, { "name": "felixfbecker/language-server-protocol", @@ -1607,16 +1782,16 @@ }, { "name": "laminas/laminas-coding-standard", - "version": "3.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "ac809f5b27f0b22d0c1ec0cbc78cb67f92bfebcb" + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/ac809f5b27f0b22d0c1ec0cbc78cb67f92bfebcb", - "reference": "ac809f5b27f0b22d0c1ec0cbc78cb67f92bfebcb", + "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/d4412caba9ed16c93cdcf301759f5ee71f9d9aea", + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea", "shasum": "" }, "require": { @@ -1656,7 +1831,7 @@ "type": "community_bridge" } ], - "time": "2024-10-16T09:23:09+00:00" + "time": "2025-05-13T08:37:04+00:00" }, { "name": "laminas/laminas-eventmanager", @@ -1726,173 +1901,6 @@ ], "time": "2024-11-21T11:31:22+00:00" }, - { - "name": "laminas/laminas-hydrator", - "version": "4.16.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-hydrator.git", - "reference": "a162bd571924968d67ef1f43aed044b8f9c108ef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-hydrator/zipball/a162bd571924968d67ef1f43aed044b8f9c108ef", - "reference": "a162bd571924968d67ef1f43aed044b8f9c108ef", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.20", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", - "webmozart/assert": "^1.11" - }, - "conflict": { - "laminas/laminas-servicemanager": "<3.14.0", - "zendframework/zend-hydrator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~3.0", - "laminas/laminas-eventmanager": "^3.13.1", - "laminas/laminas-modulemanager": "^2.16.0", - "laminas/laminas-serializer": "^2.17.0", - "laminas/laminas-servicemanager": "^3.23.0", - "phpbench/phpbench": "^1.3.1", - "phpunit/phpunit": "^10.5.38", - "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.26.1" - }, - "suggest": { - "laminas/laminas-eventmanager": "^3.13, to support aggregate hydrator usage", - "laminas/laminas-serializer": "^2.17, to use the SerializableStrategy", - "laminas/laminas-servicemanager": "^3.22, to support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Hydrator", - "config-provider": "Laminas\\Hydrator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Hydrator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Serialize objects to arrays, and vice versa", - "homepage": "https://laminas.dev", - "keywords": [ - "hydrator", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-hydrator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-hydrator/issues", - "rss": "https://github.com/laminas/laminas-hydrator/releases.atom", - "source": "https://github.com/laminas/laminas-hydrator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2024-11-13T14:04:02+00:00" - }, - { - "name": "laminas/laminas-servicemanager", - "version": "3.23.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "a8640182b892b99767d54404d19c5c3b3699f79b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/a8640182b892b99767d54404d19c5c3b3699f79b", - "reference": "a8640182b892b99767d54404d19c5c3b3699f79b", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.19", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<4.10.0", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "friendsofphp/proxy-manager-lts": "^1.0.18", - "laminas/laminas-code": "^4.14.0", - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-container-config-test": "^0.8", - "mikey179/vfsstream": "^1.6.12", - "phpbench/phpbench": "^1.3.1", - "phpunit/phpunit": "^10.5.36", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.26.1" - }, - "suggest": { - "friendsofphp/proxy-manager-lts": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2024-10-28T21:32:16+00:00" - }, { "name": "league/uri", "version": "7.5.1", @@ -2069,16 +2077,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", "shasum": "" }, "require": { @@ -2117,7 +2125,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" }, "funding": [ { @@ -2125,7 +2133,7 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2025-04-29T12:36:36+00:00" }, { "name": "netresearch/jsonmapper", @@ -2178,64 +2186,6 @@ }, "time": "2024-09-08T10:20:00+00:00" }, - { - "name": "nikic/php-parser", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" - }, - "time": "2024-12-30T11:07:19+00:00" - }, { "name": "phar-io/manifest", "version": "2.0.4", @@ -2409,16 +2359,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.1", + "version": "5.6.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", - "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/92dde6a5919e34835c506ac8c523ef095a95ed62", + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62", "shasum": "" }, "require": { @@ -2467,9 +2417,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.2" }, - "time": "2024-12-07T09:39:29+00:00" + "time": "2025-04-13T19:20:35+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -2578,16 +2528,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.11", + "version": "2.1.17", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30" + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8ca5f79a8f63c49b2359065832a654e1ec70ac30", - "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", "shasum": "" }, "require": { @@ -2632,7 +2582,7 @@ "type": "github" } ], - "time": "2025-03-24T13:45:00+00:00" + "time": "2025-05-21T20:55:28+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2959,16 +2909,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.12", + "version": "11.5.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d42785840519401ed2113292263795eb4c0f95da" + "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d42785840519401ed2113292263795eb4c0f95da", - "reference": "d42785840519401ed2113292263795eb4c0f95da", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d565e2cdc21a7db9dc6c399c1fc2083b8010f289", + "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289", "shasum": "" }, "require": { @@ -2978,7 +2928,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.0", + "myclabs/deep-copy": "^1.13.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", @@ -2988,14 +2938,14 @@ "phpunit/php-text-template": "^4.0.1", "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.2", + "sebastian/code-unit": "^3.0.3", "sebastian/comparator": "^6.3.1", "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.0", + "sebastian/environment": "^7.2.1", "sebastian/exporter": "^6.3.0", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.0", + "sebastian/type": "^5.1.2", "sebastian/version": "^5.0.2", "staabm/side-effects-detector": "^1.0.5" }, @@ -3040,7 +2990,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.12" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.21" }, "funding": [ { @@ -3051,43 +3001,49 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2025-03-07T07:31:03+00:00" + "time": "2025-05-21T12:35:00+00:00" }, { "name": "psalm/plugin-phpunit", - "version": "0.19.2", + "version": "0.19.5", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "7b7a5cde988f83ccdbdf3ebaecd88192e01c5eb1" + "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/7b7a5cde988f83ccdbdf3ebaecd88192e01c5eb1", - "reference": "7b7a5cde988f83ccdbdf3ebaecd88192e01c5eb1", + "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", + "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", "shasum": "" }, "require": { - "composer/package-versions-deprecated": "^1.10", - "composer/semver": "^1.4 || ^2.0 || ^3.0", "ext-simplexml": "*", "php": ">=8.1", - "vimeo/psalm": "dev-master || ^6" + "vimeo/psalm": "dev-master || ^6.10.0" }, "conflict": { - "phpunit/phpunit": "<7.5" + "phpspec/prophecy": "<1.20.0", + "phpspec/prophecy-phpunit": "<2.3.0", + "phpunit/phpunit": "<8.5.1" }, "require-dev": { - "codeception/codeception": "^4.0.3", "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", "squizlabs/php_codesniffer": "^3.3.1", - "weirdan/codeception-psalm-module": "^0.11.0", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "type": "psalm-plugin", @@ -3114,57 +3070,9 @@ "description": "Psalm plugin for PHPUnit", "support": { "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.19.2" + "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.19.5" }, - "time": "2025-01-26T11:39:17+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2025-03-31T18:49:55+00:00" }, { "name": "psr/http-factory", @@ -3326,21 +3234,21 @@ }, { "name": "rector/rector", - "version": "2.0.11", + "version": "2.0.16", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "059b827cc648929711606e9824337e41e2f9ed92" + "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/059b827cc648929711606e9824337e41e2f9ed92", - "reference": "059b827cc648929711606e9824337e41e2f9ed92", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", + "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", "shasum": "" }, "require": { "php": "^7.4|^8.0", - "phpstan/phpstan": "^2.1.9" + "phpstan/phpstan": "^2.1.14" }, "conflict": { "rector/rector-doctrine": "*", @@ -3373,7 +3281,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.0.11" + "source": "https://github.com/rectorphp/rector/tree/2.0.16" }, "funding": [ { @@ -3381,7 +3289,7 @@ "type": "github" } ], - "time": "2025-03-28T10:25:17+00:00" + "time": "2025-05-12T16:37:16+00:00" }, { "name": "revolt/event-loop", @@ -3514,16 +3422,16 @@ }, { "name": "sebastian/code-unit", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", "shasum": "" }, "require": { @@ -3559,7 +3467,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" }, "funding": [ { @@ -3567,7 +3475,7 @@ "type": "github" } ], - "time": "2024-12-12T09:59:06+00:00" + "time": "2025-03-19T07:56:08+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -3832,23 +3740,23 @@ }, { "name": "sebastian/environment", - "version": "7.2.0", + "version": "7.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "suggest": { "ext-posix": "*" @@ -3884,15 +3792,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2024-07-03T04:54:44+00:00" + "time": "2025-05-21T11:55:47+00:00" }, { "name": "sebastian/exporter", @@ -4272,16 +4192,16 @@ }, { "name": "sebastian/type", - "version": "5.1.0", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", "shasum": "" }, "require": { @@ -4317,7 +4237,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + "source": "https://github.com/sebastianbergmann/type/tree/5.1.2" }, "funding": [ { @@ -4325,7 +4245,7 @@ "type": "github" } ], - "time": "2024-09-17T13:12:04+00:00" + "time": "2025-03-18T13:35:50+00:00" }, { "name": "sebastian/version", @@ -4383,32 +4303,32 @@ }, { "name": "slevomat/coding-standard", - "version": "8.16.0", + "version": "8.18.1", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "7748a4282df19daf966fda1d8c60a8aec803c83a" + "reference": "06b18b3f64979ab31d27c37021838439f3ed5919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7748a4282df19daf966fda1d8c60a8aec803c83a", - "reference": "7748a4282df19daf966fda1d8c60a8aec803c83a", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/06b18b3f64979ab31d27c37021838439f3ed5919", + "reference": "06b18b3f64979ab31d27c37021838439f3ed5919", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.4 || ^8.0", "phpstan/phpdoc-parser": "^2.1.0", - "squizlabs/php_codesniffer": "^3.11.3" + "squizlabs/php_codesniffer": "^3.13.0" }, "require-dev": { "phing/phing": "3.0.1", "php-parallel-lint/php-parallel-lint": "1.4.0", - "phpstan/phpstan": "2.1.6", - "phpstan/phpstan-deprecation-rules": "2.0.1", - "phpstan/phpstan-phpunit": "2.0.4", - "phpstan/phpstan-strict-rules": "2.0.3", - "phpunit/phpunit": "9.6.8|10.5.45|11.4.4|11.5.9|12.0.4" + "phpstan/phpstan": "2.1.17", + "phpstan/phpstan-deprecation-rules": "2.0.3", + "phpstan/phpstan-phpunit": "2.0.6", + "phpstan/phpstan-strict-rules": "2.0.4", + "phpunit/phpunit": "9.6.8|10.5.45|11.4.4|11.5.21|12.1.3" }, "type": "phpcodesniffer-standard", "extra": { @@ -4432,7 +4352,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.16.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.18.1" }, "funding": [ { @@ -4444,7 +4364,7 @@ "type": "tidelift" } ], - "time": "2025-02-23T18:12:49+00:00" + "time": "2025-05-22T14:32:30+00:00" }, { "name": "spatie/array-to-xml", @@ -4516,16 +4436,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.11.3", + "version": "3.13.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10" + "reference": "65ff2489553b83b4597e89c3b8b721487011d186" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", - "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186", + "reference": "65ff2489553b83b4597e89c3b8b721487011d186", "shasum": "" }, "require": { @@ -4592,11 +4512,11 @@ "type": "open_collective" }, { - "url": "https://thanks.dev/phpcsstandards", + "url": "https://thanks.dev/u/gh/phpcsstandards", "type": "thanks_dev" } ], - "time": "2025-01-23T17:04:15+00:00" + "time": "2025-05-11T03:36:00+00:00" }, { "name": "staabm/side-effects-detector", @@ -4652,16 +4572,16 @@ }, { "name": "symfony/console", - "version": "v7.2.1", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", "shasum": "" }, "require": { @@ -4725,7 +4645,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.1" + "source": "https://github.com/symfony/console/tree/v7.2.6" }, "funding": [ { @@ -4741,7 +4661,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T03:49:26+00:00" + "time": "2025-04-07T19:09:28+00:00" }, { "name": "symfony/deprecation-contracts", @@ -4878,7 +4798,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -4937,7 +4857,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -4957,7 +4877,7 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", @@ -5015,7 +4935,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" }, "funding": [ { @@ -5035,7 +4955,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -5096,7 +5016,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" }, "funding": [ { @@ -5116,19 +5036,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -5176,7 +5097,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -5192,20 +5113,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd" + "reference": "000df7860439609837bbe28670b0be15783b7fbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/e5493eb51311ab0b1cc2243416613f06ed8f18bd", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/000df7860439609837bbe28670b0be15783b7fbf", + "reference": "000df7860439609837bbe28670b0be15783b7fbf", "shasum": "" }, "require": { @@ -5252,7 +5173,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.32.0" }, "funding": [ { @@ -5268,7 +5189,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T12:04:04+00:00" + "time": "2025-02-20T12:04:08+00:00" }, { "name": "symfony/service-contracts", @@ -5355,16 +5276,16 @@ }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", "shasum": "" }, "require": { @@ -5422,7 +5343,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v7.2.6" }, "funding": [ { @@ -5438,7 +5359,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2025-04-20T20:18:16+00:00" }, { "name": "theseer/tokenizer", @@ -5492,16 +5413,16 @@ }, { "name": "vimeo/psalm", - "version": "6.9.1", + "version": "6.11.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "81c8a77c0793d450fee40265cfe68891df11d505" + "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/81c8a77c0793d450fee40265cfe68891df11d505", - "reference": "81c8a77c0793d450fee40265cfe68891df11d505", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", + "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", "shasum": "" }, "require": { @@ -5606,7 +5527,7 @@ "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm" }, - "time": "2025-03-17T09:40:52+00:00" + "time": "2025-05-12T11:30:26+00:00" }, { "name": "webimpress/coding-standard", diff --git a/src/Adapter/AbstractAdapter.php b/src/Adapter/AbstractAdapter.php index a092c1360..2138588e7 100644 --- a/src/Adapter/AbstractAdapter.php +++ b/src/Adapter/AbstractAdapter.php @@ -17,51 +17,32 @@ * @property Driver\DriverInterface $driver * @property Platform\PlatformInterface $platform */ -abstract class AbstractAdapter implements AdapterInterface, Profiler\ProfilerAwareInterface +abstract class AbstractAdapter implements AdapterInterface, Profiler\ProfilerAwareInterface, SchemaAwareInterface { - /** @var Driver\DriverInterface */ - protected $driver; - - /** @var Platform\PlatformInterface */ - protected $platform; - - protected Profiler\ProfilerInterface $profiler; - - protected ResultSet\ResultSetInterface $queryResultSetPrototype; - /** * @throws Exception\InvalidArgumentException */ public function __construct( - Driver\DriverInterface|array $driver, - ?Platform\PlatformInterface $platform = null, - ?ResultSet\ResultSetInterface $queryResultPrototype = null, - ?Profiler\ProfilerInterface $profiler = null + protected Driver\DriverInterface|array $driver, + protected ?Platform\PlatformInterface $platform = null, + protected ?ResultSet\ResultSetInterface $queryResultSetPrototype = null, + protected ?Profiler\ProfilerInterface $profiler = null ) { // first argument can be an array of parameters $parameters = []; - if (is_array($driver)) { - $parameters = $driver; - if ($profiler === null && isset($parameters['profiler'])) { + if (is_array($this->driver)) { + $parameters = $this->driver; + if ($this->profiler === null && isset($parameters['profiler'])) { $profiler = $this->createProfiler($parameters); } - $driver = $this->createDriver($parameters); - } elseif (! $driver instanceof Driver\DriverInterface) { - throw new Exception\InvalidArgumentException( - 'The supplied or instantiated driver object does not implement ' . Driver\DriverInterface::class - ); + $this->driver = $this->createDriver($parameters); } - $driver->checkEnvironment(); - $this->driver = $driver; + $this->driver->checkEnvironment(); - if ($platform === null) { - $platform = $this->createPlatform($parameters); - } - - $this->platform = $platform; - $this->queryResultSetPrototype = $queryResultPrototype ?: new ResultSet\ResultSet(); + $this->platform = $this->platform ?? $this->createPlatform($parameters); + $this->queryResultSetPrototype = $this->queryResultSetPrototype ?? new ResultSet\ResultSet(); if ($profiler) { $this->setProfiler($profiler); @@ -218,116 +199,116 @@ public function __get(string $name) }; } - protected function createDriver(array $parameters): Driver\DriverInterface - { - if (! isset($parameters['driver'])) { - throw new Exception\InvalidArgumentException( - __FUNCTION__ . ' expects a "driver" key to be present inside the parameters' - ); - } - - if ($parameters['driver'] instanceof Driver\DriverInterface) { - return $parameters['driver']; - } - - if (! is_string($parameters['driver'])) { - throw new Exception\InvalidArgumentException( - __FUNCTION__ . ' expects a "driver" to be a string or instance of DriverInterface' - ); - } - - $options = []; - if (isset($parameters['options'])) { - $options = (array) $parameters['options']; - unset($parameters['options']); - } - - $driverName = strtolower($parameters['driver']); - switch ($driverName) { - case 'mysqli': - $driver = new Driver\Mysqli\Mysqli($parameters, null, null, $options); - break; - case 'sqlsrv': - $driver = new Driver\Sqlsrv\Sqlsrv($parameters); - break; - case 'oci8': - $driver = new Driver\Oci8\Oci8($parameters); - break; - case 'pgsql': - $driver = new Driver\Pgsql\Pgsql($parameters); - break; - case 'ibmdb2': - $driver = new Driver\IbmDb2\IbmDb2($parameters); - break; - case 'pdo': - default: - if ($driverName === 'pdo' || str_starts_with($driverName, 'pdo')) { - $driver = new Driver\Pdo\Pdo($parameters); - } - } - - if (! isset($driver) || ! $driver instanceof Driver\DriverInterface) { - throw new Exception\InvalidArgumentException('DriverInterface expected'); - } - - return $driver; - } - - protected function createPlatform(array $parameters): Platform\PlatformInterface - { - if (isset($parameters['platform'])) { - $platformName = $parameters['platform']; - } elseif ($this->driver instanceof Driver\DriverInterface) { - $platformName = $this->driver->getDatabasePlatformName(); - } else { - throw new Exception\InvalidArgumentException( - 'A platform could not be determined from the provided configuration' - ); - } - - // currently only supported by the IbmDb2 & Oracle concrete implementations - $options = $parameters['platform_options'] ?? []; - - switch ($platformName) { - case 'Mysql': - // mysqli or pdo_mysql driver - if ($this->driver instanceof Driver\Mysqli\Mysqli || $this->driver instanceof Driver\Pdo\Pdo) { - $driver = $this->driver; - } else { - $driver = null; - } - return new Platform\Mysql($driver); - case 'SqlServer': - // PDO is only supported driver for quoting values in this platform - return new Platform\SqlServer($this->driver instanceof Driver\Pdo\Pdo ? $this->driver : null); - case 'Oracle': - if ($this->driver instanceof Driver\Oci8\Oci8 || $this->driver instanceof Driver\Pdo\Pdo) { - $driver = $this->driver; - } else { - $driver = null; - } - return new Platform\Oracle($options, $driver); - case 'Sqlite': - // PDO is only supported driver for quoting values in this platform - if ($this->driver instanceof Driver\Pdo\Pdo) { - return new Platform\Sqlite($this->driver); - } - return new Platform\Sqlite(null); - case 'Postgresql': - // pgsql or pdo postgres driver - if ($this->driver instanceof Driver\Pgsql\Pgsql || $this->driver instanceof Driver\Pdo\Pdo) { - $driver = $this->driver; - } else { - $driver = null; - } - return new Platform\Postgresql($driver); - case 'IbmDb2': - // ibm_db2 driver escaping does not need an action connection - return new Platform\IbmDb2($options); - default: - return new Platform\Sql92(); - } - } + // protected function createDriver(array $parameters): Driver\DriverInterface + // { + // if (! isset($parameters['driver'])) { + // throw new Exception\InvalidArgumentException( + // __FUNCTION__ . ' expects a "driver" key to be present inside the parameters' + // ); + // } + + // if ($parameters['driver'] instanceof Driver\DriverInterface) { + // return $parameters['driver']; + // } + + // if (! is_string($parameters['driver'])) { + // throw new Exception\InvalidArgumentException( + // __FUNCTION__ . ' expects a "driver" to be a string or instance of DriverInterface' + // ); + // } + + // $options = []; + // if (isset($parameters['options'])) { + // $options = (array) $parameters['options']; + // unset($parameters['options']); + // } + + // $driverName = strtolower($parameters['driver']); + // switch ($driverName) { + // case 'mysqli': + // $driver = new Driver\Mysqli\Mysqli($parameters, null, null, $options); + // break; + // case 'sqlsrv': + // $driver = new Driver\Sqlsrv\Sqlsrv($parameters); + // break; + // case 'oci8': + // $driver = new Driver\Oci8\Oci8($parameters); + // break; + // case 'pgsql': + // $driver = new Driver\Pgsql\Pgsql($parameters); + // break; + // case 'ibmdb2': + // $driver = new Driver\IbmDb2\IbmDb2($parameters); + // break; + // case 'pdo': + // default: + // if ($driverName === 'pdo' || str_starts_with($driverName, 'pdo')) { + // $driver = new Driver\Pdo\Pdo($parameters); + // } + // } + + // if (! isset($driver) || ! $driver instanceof Driver\DriverInterface) { + // throw new Exception\InvalidArgumentException('DriverInterface expected'); + // } + + // return $driver; + // } + + // protected function createPlatform(array $parameters): Platform\PlatformInterface + // { + // if (isset($parameters['platform'])) { + // $platformName = $parameters['platform']; + // } elseif ($this->driver instanceof Driver\DriverInterface) { + // $platformName = $this->driver->getDatabasePlatformName(); + // } else { + // throw new Exception\InvalidArgumentException( + // 'A platform could not be determined from the provided configuration' + // ); + // } + + // // currently only supported by the IbmDb2 & Oracle concrete implementations + // $options = $parameters['platform_options'] ?? []; + + // switch ($platformName) { + // case 'Mysql': + // // mysqli or pdo_mysql driver + // if ($this->driver instanceof Driver\Mysqli\Mysqli || $this->driver instanceof Driver\Pdo\Pdo) { + // $driver = $this->driver; + // } else { + // $driver = null; + // } + // return new Platform\Mysql($driver); + // case 'SqlServer': + // // PDO is only supported driver for quoting values in this platform + // return new Platform\SqlServer($this->driver instanceof Driver\Pdo\Pdo ? $this->driver : null); + // case 'Oracle': + // if ($this->driver instanceof Driver\Oci8\Oci8 || $this->driver instanceof Driver\Pdo\Pdo) { + // $driver = $this->driver; + // } else { + // $driver = null; + // } + // return new Platform\Oracle($options, $driver); + // case 'Sqlite': + // // PDO is only supported driver for quoting values in this platform + // if ($this->driver instanceof Driver\Pdo\Pdo) { + // return new Platform\Sqlite($this->driver); + // } + // return new Platform\Sqlite(null); + // case 'Postgresql': + // // pgsql or pdo postgres driver + // if ($this->driver instanceof Driver\Pgsql\Pgsql || $this->driver instanceof Driver\Pdo\Pdo) { + // $driver = $this->driver; + // } else { + // $driver = null; + // } + // return new Platform\Postgresql($driver); + // case 'IbmDb2': + // // ibm_db2 driver escaping does not need an action connection + // return new Platform\IbmDb2($options); + // default: + // return new Platform\Sql92(); + // } + // } protected function createProfiler(array $parameters): ?Profiler\ProfilerInterface { diff --git a/src/Adapter/AdapterServiceDelegator.php b/src/Adapter/AdapterServiceDelegator.php index 32e20e1a8..fbe968879 100644 --- a/src/Adapter/AdapterServiceDelegator.php +++ b/src/Adapter/AdapterServiceDelegator.php @@ -1,39 +1,46 @@ adapterName = $adapterName; - } + public function __construct( + protected readonly string $adapterName = AdapterInterface::class + ) {} public static function __set_state(array $state): self { return new self($state['adapterName'] ?? AdapterInterface::class); } - /** @return AdapterInterface */ public function __invoke( ContainerInterface $container, string $name, callable $callback, ?array $options = null - ) { + ): AdapterAwareInterface { $instance = $callback(); if (! $instance instanceof AdapterAwareInterface) { - return $instance; + throw new Exception\RuntimeException(sprintf( + 'Delegated service "%s" must implement %s', + $name, + AdapterAwareInterface::class + )); } if (! $container->has($this->adapterName)) { - return $instance; + throw new ServiceNotFoundException(sprintf( + 'Service "%s" not found in container', + $this->adapterName + )); } $databaseAdapter = $container->get($this->adapterName); diff --git a/src/Adapter/AdapterServiceFactory.php b/src/Adapter/AdapterServiceFactory.php index 470c23725..7708c5acc 100644 --- a/src/Adapter/AdapterServiceFactory.php +++ b/src/Adapter/AdapterServiceFactory.php @@ -19,14 +19,4 @@ public function __invoke(ContainerInterface $container, $requestedName, ?array $ $config = $container->get('config'); return new Adapter($config['db']); } - - /** - * Create db adapter service (v2) - * - * @return Adapter - */ - public function createService(ServiceLocatorInterface $container) - { - return $this($container, Adapter::class); - } } diff --git a/src/Adapter/ConfigInterface.php b/src/Adapter/ConfigInterface.php new file mode 100644 index 000000000..5fcc78d3b --- /dev/null +++ b/src/Adapter/ConfigInterface.php @@ -0,0 +1,7 @@ +get(AdapterManager::class))->get(AdapterInterface::class); + } +} diff --git a/src/Container/AdapterManager.php b/src/Container/AdapterManager.php new file mode 100644 index 000000000..d62916577 --- /dev/null +++ b/src/Container/AdapterManager.php @@ -0,0 +1,83 @@ + [ + // Driver\DriverInterface::class => Driver\DriverServiceDelegator::class, + // Driver\ConnectionInterface::class => Driver\ConnectionServiceDelegator::class, + // Platform\PlatformInterface::class => Platform\PlatformServiceDelegator::class, + // Profiler\ProfilerInterface::class => Profiler\ProfilerServiceDelegator::class, + // Metadata\MetadataInterface::class => Metadata\MetadataServiceDelegator::class, + // ], + // ]; + + public function __construct( + ContainerInterface $container, + array $config = [], + ) { + parent::__construct($container, $config); + } + + /** + * validate the service types this manager can create + */ + #[Override] + public function validate(mixed $instance): void + { + if ($instance instanceof AdapterInterface) { + return; + } + + if ($instance instanceof Driver\DriverInterface) { + return; + } + + if ($instance instanceof Driver\ConnectionInterface) { + return; + } + + if ($instance instanceof Platform\PlatformInterface) { + return; + } + + if ($instance instanceof Profiler\ProfilerInterface) { + return; + } + + if ($instance instanceof Metadata\MetadataInterface) { + return; + } + + throw new Exception\RuntimeException(sprintf( + 'AdapterManager expects an instance of %s, %s, %s, %s, or %s; received %s', + AdapterInterface::class, + Driver\DriverInterface::class, + Driver\ConnectionInterface::class, + Platform\PlatformInterface::class, + Profiler\ProfilerInterface::class, + Metadata\MetadataInterface::class, + get_debug_type($instance) + )); + } +} + diff --git a/src/Container/AdapterManagerFactory.php b/src/Container/AdapterManagerFactory.php new file mode 100644 index 000000000..eb2b8f44c --- /dev/null +++ b/src/Container/AdapterManagerFactory.php @@ -0,0 +1,27 @@ +get('config'); + $dbConfig = $config['db'] ?? []; + + return new AdapterManager( + $container, + [ + 'services' => [ + ConfigInterface::class => $dbConfig, + ], + ] + ); + } +} diff --git a/src/Container/ConfigProvider.php b/src/Container/ConfigProvider.php new file mode 100644 index 000000000..6852d37ba --- /dev/null +++ b/src/Container/ConfigProvider.php @@ -0,0 +1,24 @@ + $this->getDependencies(), + ]; + } + + public function getDependencies(): array + { + return [ + 'factories' => [ + AdapterManager::class => AdapterManagerFactory::class, + ], + ]; + } +} diff --git a/src/Metadata/Source/AbstractSource.php b/src/Metadata/Source/AbstractSource.php index b6f515942..6cb058669 100644 --- a/src/Metadata/Source/AbstractSource.php +++ b/src/Metadata/Source/AbstractSource.php @@ -20,21 +20,17 @@ abstract class AbstractSource implements MetadataInterface { public const DEFAULT_SCHEMA = '__DEFAULT_SCHEMA__'; - /** @var Adapter */ - protected $adapter; - /** @var string */ protected $defaultSchema; - /** @var array */ - protected $data = []; + protected array $data = []; /** * Constructor */ - public function __construct(AdapterInterface $adapter) - { - $this->adapter = $adapter; + public function __construct( + protected AdapterInterface $adapter + ) { $this->defaultSchema = $adapter->getCurrentSchema() ?: self::DEFAULT_SCHEMA; } From 9766886177bf7b37c4f727044d43d8669c0b22e4 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 26 May 2025 03:07:28 -0500 Subject: [PATCH 29/32] Latest revisions Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/Driver/Pdo/AbstractPdo.php | 39 ++++++++++++++++--- src/Container/AdapterInterfaceFactory.php | 16 -------- src/Container/AdapterManager.php | 47 ++++++++--------------- src/Container/AdapterManagerFactory.php | 3 ++ 4 files changed, 52 insertions(+), 53 deletions(-) delete mode 100644 src/Container/AdapterInterfaceFactory.php diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index 445798d36..dd7531bc6 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -28,17 +28,46 @@ abstract class AbstractPdo implements PdoDriverInterface, DriverFeatureInterface { public const FEATURES_DEFAULT = 'default'; - protected ConnectionInterface $connection; + //protected ConnectionInterface $connection; - protected StatementInterface&PdoDriverAwareInterface $statementPrototype; + // protected StatementInterface&PdoDriverAwareInterface $statementPrototype; - protected ResultInterface $resultPrototype; + //protected ResultInterface $resultPrototype; - protected array $features = []; + // protected array $features = []; /** @internal */ public ?ProfilerInterface $profiler; + /** + * @param $connection + * @param string $features + */ + public function __construct( + protected AbstractPdoConnection|\PDO $connection, + protected StatementInterface&PdoDriverAwareInterface $statementPrototype, + protected ResultInterface $resultPrototype, + protected array|string $features = [self::FEATURES_DEFAULT] + ) { + if (! $connection instanceof Connection) { // needs factory + $connection = new Connection($connection); + } + + //$this->registerConnection($connection); + //$this->registerStatementPrototype($statementPrototype ?: new Statement()); + //$this->registerResultPrototype($resultPrototype ?: new Result()); + + if (is_array($features)) { + foreach ($features as $name => $feature) { + $this->addFeature($name, $feature); + } + } elseif ($features instanceof AbstractFeature) { + $this->addFeature($features->getName(), $features); + } elseif ($features === self::FEATURES_DEFAULT) { + $this->setupDefaultFeatures(); + } + } + public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; @@ -59,7 +88,7 @@ public function getProfiler(): ?ProfilerInterface /** * Register statement prototype */ - public function registerStatementPrototype(StatementInterface $statementPrototype) + public function registerStatementPrototype(StatementInterface&PdoDriverAwareInterface $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); diff --git a/src/Container/AdapterInterfaceFactory.php b/src/Container/AdapterInterfaceFactory.php deleted file mode 100644 index d3788f9d0..000000000 --- a/src/Container/AdapterInterfaceFactory.php +++ /dev/null @@ -1,16 +0,0 @@ -get(AdapterManager::class))->get(AdapterInterface::class); - } -} diff --git a/src/Container/AdapterManager.php b/src/Container/AdapterManager.php index d62916577..21c25c60d 100644 --- a/src/Container/AdapterManager.php +++ b/src/Container/AdapterManager.php @@ -44,40 +44,23 @@ public function __construct( #[Override] public function validate(mixed $instance): void { - if ($instance instanceof AdapterInterface) { + if (is_array($instance)) { + // If the instance is an array, we assume it's a configuration array + // and do not validate it as a service instance. return; } - - if ($instance instanceof Driver\DriverInterface) { - return; - } - - if ($instance instanceof Driver\ConnectionInterface) { - return; - } - - if ($instance instanceof Platform\PlatformInterface) { - return; - } - - if ($instance instanceof Profiler\ProfilerInterface) { - return; - } - - if ($instance instanceof Metadata\MetadataInterface) { - return; - } - - throw new Exception\RuntimeException(sprintf( - 'AdapterManager expects an instance of %s, %s, %s, %s, or %s; received %s', - AdapterInterface::class, - Driver\DriverInterface::class, - Driver\ConnectionInterface::class, - Platform\PlatformInterface::class, - Profiler\ProfilerInterface::class, - Metadata\MetadataInterface::class, - get_debug_type($instance) - )); + $validate = match(true) { + $instance instanceof AdapterInterface, + $instance instanceof Driver\DriverInterface, + $instance instanceof Driver\ConnectionInterface, + $instance instanceof Platform\PlatformInterface, + $instance instanceof Profiler\ProfilerInterface, + $instance instanceof Metadata\MetadataInterface => true, + default => throw new Exception\RuntimeException(sprintf( + 'AdapterManager can not create an instance of %s', + get_debug_type($instance) + )), + }; } } diff --git a/src/Container/AdapterManagerFactory.php b/src/Container/AdapterManagerFactory.php index eb2b8f44c..6a43ac0a2 100644 --- a/src/Container/AdapterManagerFactory.php +++ b/src/Container/AdapterManagerFactory.php @@ -18,6 +18,9 @@ public function __invoke(ContainerInterface $container): AdapterManager return new AdapterManager( $container, [ + 'aliases' => [ + 'db' => ConfigInterface::class, + ], 'services' => [ ConfigInterface::class => $dbConfig, ], From 64fb3342db1ccad8603a8d99558f6f46fbd3e199 Mon Sep 17 00:00:00 2001 From: Matthew Setter Date: Mon, 26 May 2025 20:56:05 +1000 Subject: [PATCH 30/32] Fix up types The changes in this commit are aimed to, where practical, fix up or improve the use of types throughout the package. While there are far more to go, this is a solid continuation of the existing work. --- composer.json | 8 +- psalm-baseline.xml | 3728 +---------------- src/Adapter/AdapterAbstractServiceFactory.php | 1 - src/Adapter/AdapterInterface.php | 1 - src/Adapter/Driver/AbstractConnection.php | 8 +- src/Adapter/Driver/IbmDb2/Connection.php | 23 +- src/Adapter/Driver/Pdo/AbstractPdo.php | 28 +- .../Driver/Pdo/AbstractPdoConnection.php | 4 - src/Adapter/Driver/Pdo/Statement.php | 39 +- src/Adapter/Driver/PdoDriverInterface.php | 4 +- src/Adapter/Driver/Pgsql/Pgsql.php | 26 +- src/Adapter/Driver/StatementInterface.php | 16 +- src/Adapter/Platform/AbstractPlatform.php | 20 +- src/Adapter/Platform/PlatformInterface.php | 45 +- src/Adapter/StatementContainer.php | 26 +- src/Adapter/StatementContainerInterface.php | 12 +- src/Container/MetadataFactory.php | 6 +- src/Metadata/Source/Factory.php | 3 +- src/Sql/AbstractSql.php | 2 +- src/Sql/Ddl/CreateTable.php | 2 +- src/Sql/Delete.php | 2 +- src/Sql/Insert.php | 60 +- src/Sql/Select.php | 12 +- src/Sql/Update.php | 87 +- src/TableGateway/Feature/MetadataFeature.php | 10 +- .../AdapterAbstractServiceFactoryTest.php | 2 +- .../Platform/Mysql/SelectDecoratorTest.php | 10 +- test/unit/Sql/Platform/PlatformTest.php | 2 +- test/unit/Sql/SelectTest.php | 20 +- test/unit/Sql/SqlFunctionalTest.php | 2 +- test/unit/Sql/SqlTest.php | 2 +- test/unit/Sql/UpdateTest.php | 10 +- .../TableGateway/AbstractTableGatewayTest.php | 2 +- .../TableGateway/Feature/FeatureSetTest.php | 2 +- .../Feature/SequenceFeatureTest.php | 2 +- test/unit/TableGateway/TableGatewayTest.php | 2 +- 36 files changed, 290 insertions(+), 3939 deletions(-) diff --git a/composer.json b/composer.json index 899f7bd1b..bdd8f83c8 100644 --- a/composer.json +++ b/composer.json @@ -63,15 +63,15 @@ "@cs-check", "@test" ], - "cs-check": "phpcs", + "cs-check": "php -d xdebug.mode=off vendor/bin/phpcs", "cs-fix": "phpcbf", - "test": "phpunit --colors=always --testsuite \"unit test\"", + "test": "php -d xdebug.mode=off vendor/bin/phpunit --colors=always --testsuite \"unit test\"", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "test-integration": "phpunit --colors=always --testsuite \"integration test\"", - "static-analysis": "psalm --shepherd --stats", + "static-analysis": "php -d xdebug.mode=off vendor/bin/psalm", "upload-coverage": "coveralls -v" }, "conflict": { "zendframework/zend-db": "*" } -} +} \ No newline at end of file diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2546eb3cf..46a7c6d69 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,71 +1,12 @@ - - - - - - - driver === null]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - config]]> @@ -110,9 +51,7 @@ - - - + @@ -124,9 +63,7 @@ - - - + resource]]> @@ -135,11 +72,7 @@ - - - - - + @@ -154,12 +87,6 @@ - - - - - - @@ -172,12 +99,6 @@ - - resource)]]> - - - - @@ -202,9 +123,6 @@ DB_NAME ?? '']]> DB_NAME ?? '']]> - - resource)]]> - DB_NAME]]> @@ -339,250 +257,6 @@ profiler]]> - - - - - - - - - resource : $resultResource]]> - - - - resource->insert_id]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - resource->connect_error]]> - - - - - - - - - - - - - resource instanceof \mysqli]]> - resource instanceof \mysqli]]> - - - - resource->connect_error]]> - - - - - - - - - - - - - - - - - - connection->getResource()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - resource->affected_rows]]> - resource->num_rows]]> - resource->num_rows]]> - - - - - - - - - - - - - resource->error]]> - statementBindValues['keys']]]> - - - statementBindValues['keys'][$i]]]> - statementBindValues['values'][$i]]]> - - - currentData[$this->statementBindValues['keys'][$i]]]]> - - - currentData[$this->statementBindValues['keys'][$i]]]]> - - - - - - - - - - - - name]]> - - - resource->num_rows]]> - - - - - - - - - - - - - - - resource->error]]> - resource->num_rows]]> - - - - - - - - - - - - - - resource]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - profiler]]> - - - profiler]]> - - - - - - - - @@ -590,9 +264,6 @@ - - - @@ -644,9 +315,6 @@ - - - @@ -926,193 +594,13 @@ - + + + + - - - - - - - - - - - connectionParameters]]> - connectionParameters]]> - - - - - - - - - - - - resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> - resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> - - - - - - - - dsn]]> - - - - - - - fetchColumn()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - resource]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - connection->getResource()]]> - - - - - - - - - - - - - - - - - - - - - - - - - features[$name]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rowCount instanceof Closure]]> - rowCount)]]> + rowCount instanceof Closure]]> + rowCount)]]> @@ -1152,12 +640,6 @@ - - resource]]> - - - - @@ -1166,25 +648,16 @@ - - - - resource->errorInfo()]]> - - - - - - + @@ -1194,10 +667,6 @@ profiler]]> - - parameterContainer]]> - profiler]]> - @@ -1214,7 +683,6 @@ - resource]]> @@ -1387,9 +855,6 @@ - - - @@ -1648,11 +1113,6 @@ prepareParams[$position]]]> - - - - - @@ -1791,9 +1251,6 @@ quoteIdentifier[0], $this->quoteIdentifierTo, $part)]]> - - - @@ -1821,9 +1278,6 @@ . str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $part) . $this->quoteIdentifier[1]]]> - - - @@ -1832,20 +1286,6 @@ quoteIdentifier[0], $this->quoteIdentifierTo, $part)]]> - - - - - - - - - - - - - - @@ -1853,28 +1293,12 @@ resource]]> - - - - - - - - - - - - - - - - @@ -1883,48 +1307,22 @@ - - - - - - + - - - - - - - - - - - - - - - - - - quoteIdentifier]]> - - - @@ -1939,13 +1337,6 @@ - - - - - - - @@ -2023,11 +1414,6 @@ - - - - - @@ -2428,168 +1814,19 @@ - + - + - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - data['columns'][$schema]]]> - data['columns'][$schema][$table]]]> - data['constraint_keys'][$schema]]]> - data['constraint_names'][$schema]]]> - data['constraint_references'][$schema]]]> - data['constraints'][$schema]]]> - data['constraints'][$schema][$table]]]> - data['table_names'][$schema]]]> - data['triggers'][$schema]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2660,19 +1897,10 @@ constraintTypeMap[$type]]]> - - - - - - - - - @@ -2697,7 +1925,6 @@ - @@ -2779,13 +2006,6 @@ - - - - - - - @@ -2897,13 +2117,6 @@ - - - - - - - @@ -3009,11 +2222,6 @@ - - - - - @@ -3023,14 +2231,6 @@ - - - - - - - - dataSource]]> @@ -3989,12 +3189,6 @@ - - - - - - specifications[static::SPECIFICATION_DELETE]]]> specifications[static::SPECIFICATION_WHERE]]]> @@ -4007,9 +3201,6 @@ specifications[static::SPECIFICATION_DELETE]]]> specifications[static::SPECIFICATION_WHERE]]]> - - - @@ -4047,9 +3238,6 @@ - - - @@ -4057,10 +3245,6 @@ - - specifications[static::SPECIFICATION_INSERT]]]> - specifications[static::SPECIFICATION_SELECT]]]> - @@ -4081,9 +3265,6 @@ : array_combine(array_keys($this->columns), array_values($values))]]> - - - select]]> @@ -4097,7 +3278,6 @@ - @@ -4177,8 +3357,6 @@ - specifications[self::SELECT]]]> - specifications[self::SELECT]]]> @@ -4221,215 +3399,67 @@ - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + processInfo['subselectCount']]]> + processInfo['subselectCount']]]> + processInfo['subselectCount']]]> + - - - - + + + + - - - - + + + + + + + + + + + + + - - + + + + + - + + + + + + + + processInfo['subselectCount']]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - processInfo['paramPrefix']]]> - processInfo['paramPrefix']]]> - - - limit]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - processInfo['subselectCount']]]> - processInfo['subselectCount']]]> - processInfo['subselectCount']]]> - - - - - - - specifications[self::SELECT]]]> - specifications[self::SELECT]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - processInfo['subselectCount']]]> - - - processInfo['subselectCount']]]> - + + processInfo['subselectCount']]]> + @@ -4444,7 +3474,6 @@ - limit]]> @@ -4461,13 +3490,6 @@ - - decorators]]> - decorators]]> - decorators]]> - decorators]]> - decorators]]> - decorators[$platformName]]]> @@ -4548,8 +3570,6 @@ - specifications[self::SELECT]]]> - specifications[self::SELECT]]]> @@ -4577,7 +3597,6 @@ - @@ -4613,7 +3632,6 @@ - @@ -4776,9 +3794,6 @@ - - - nextPredicateCombineOperator]]> nextPredicateCombineOperator]]> @@ -4804,10 +3819,6 @@ - - predicates]]> - predicates]]> - @@ -4826,26 +3837,18 @@ - - predicates[$i + 1]]]> - predicates[$i]]]> - - - joins]]> - limit]]> - offset]]> processInfo['paramPrefix']]]> @@ -4905,14 +3908,6 @@ - - - - - - - - @@ -4926,9 +3921,6 @@ - - - @@ -4950,24 +3942,13 @@ - - - - - - - quantifier]]> - - - - @@ -5146,9 +4127,6 @@ table]]> table]]> - - - @@ -5405,19 +4383,12 @@ - - tableGateway->adapter]]> - - metadata === null]]> table)]]> - - - @@ -5435,7 +4406,6 @@ table]]> - @@ -5565,94 +4535,13 @@ - - - - - - - - - - - - - - - - - - variables]]> - variables]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - adapter]]> - - - - - - - - - - - - - - - - - - current()]]> @@ -5665,79 +4554,12 @@ - - - - - - - - - - - - - - - - - $key]]> - $key]]> - id]]> - name]]> - value]]> - - - adapter]]> - adapter]]> - adapter]]> - adapter]]> - adapter]]> - adapter]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5745,10 +4567,6 @@ adapters]]> adapters]]> - - - - @@ -5769,9 +4587,6 @@ - - - adapters['pgsql'] instanceof PgSqlConnection && ! is_resource($this->adapters['pgsql'])]]> @@ -5780,10 +4595,6 @@ adapters]]> adapters]]> - - - - @@ -5809,9 +4620,6 @@ - - - @@ -5819,9 +4627,6 @@ adapters]]> adapters]]> - - - @@ -5836,12 +4641,6 @@ - - - - - - @@ -5853,12 +4652,6 @@ - - - - - - fixtureFile)]]> @@ -5873,17 +4666,11 @@ - - - - - - @@ -5905,9 +4692,6 @@ - - - @@ -5946,32 +4730,19 @@ - - - [AdapterAbstractServiceFactory::class], ])]]> - - - - - - - - - - @@ -5980,73 +4751,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - adapter->foo]]> - - - - - - - - - - - - - - - - - variables['database']]]> variables['database']]]> @@ -6067,27 +4781,10 @@ getCurrentSchema())]]> - - - - - - - - - - - - - - - - - variables['database']]]> variables['password']]]> @@ -6099,46 +4796,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - variables]]> - - - - - - - @@ -6154,38 +4820,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6196,45 +4836,15 @@ - - - - - - - - - - - getResource())]]> getCurrentSchema())]]> - - - - - - - - - - - - - - - - - - - @@ -6243,66 +4853,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - variables]]> - - - - - - @@ -6324,94 +4887,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6424,19 +4916,10 @@ - - - - - - - - - @@ -6445,20 +4928,6 @@ - - - - - - - - - - - - - - @@ -6468,22 +4937,12 @@ - - - - - - - - - - @@ -6494,42 +4953,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - errorInfo()]]> @@ -6544,47 +4970,12 @@ - - - connection->getResource()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6592,48 +4983,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - adapters['pdo_sqlsrv']]]> - - - - @@ -6642,25 +5000,14 @@ - - - - - - resource)]]> - - - - - @@ -6676,34 +5023,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6716,20 +5036,7 @@ - - - - - - - - - - - - - @@ -6742,37 +5049,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6781,167 +5061,18 @@ parameterContainer]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6959,48 +5090,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - @@ -7009,16 +5101,6 @@ - - - - - - - - - - @@ -7038,51 +5120,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7102,14 +5142,6 @@ - - - - - - - - arraySerializableHydratorClass]]> @@ -7117,9 +5149,6 @@ - - - @@ -7127,15 +5156,6 @@ - - - - - - - - - @@ -7146,34 +5166,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7199,7 +5191,6 @@ - @@ -7212,37 +5203,7 @@ - - - - - - - - - - getMockForAbstractClass(AbstractRowGateway::class)]]> - getMockForAbstractClass(AbstractRowGateway::class)]]> - - - - - - - - - - - - - - - - - - - - + @@ -7269,40 +5230,18 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -7334,14 +5273,8 @@ - - - - - - @@ -7351,323 +5284,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7714,61 +5359,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7788,263 +5389,30 @@ insert->foo]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + - - - - - - - - insert->foo]]> - insert->foo]]> - insert->foo]]> - insert->foo]]> - insert->foo]]> - insert->foo]]> - insert->foo]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Between::TYPE_IDENTIFIER]]]> Between::TYPE_IDENTIFIER]]]> @@ -8053,993 +5421,51 @@ Between::TYPE_VALUE]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $like::TYPE_VALUE]]]> $like::TYPE_IDENTIFIER]]]> - - - - - - - - - - - - - - - - - - - - - - NotBetween::TYPE_IDENTIFIER]]]> - NotBetween::TYPE_IDENTIFIER]]]> - NotBetween::TYPE_VALUE]]]> - - - NotBetween::TYPE_VALUE]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - Operator::TYPE_VALUE]]]> Operator::TYPE_IDENTIFIER]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ', 20), - ])]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - from(new TableIdentifier('foo')) - ->where - ->nest - ->isNull('bar') - ->and]]> - from(new TableIdentifier('foo')) - ->where - ->nest - ->isNull('bar') - ->or]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - from(new TableIdentifier('foo')) - ->where - ->nest]]> - from(new TableIdentifier('foo')) - ->where - ->nest]]> - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - * }, - * MySql: array{ - * string: string, - * prepare: string, - * parameters: array - * }, - * Oracle: array{ - * string: string, - * prepare: string, - * parameters: array - * }, - * SqlServer: array{ - * string: string, - * prepare: string, - * parameters: array - * }, - * } - * }>]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - update->__get('what')]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Adapter/AdapterAbstractServiceFactory.php b/src/Adapter/AdapterAbstractServiceFactory.php index 798bc18df..e45cee3d3 100644 --- a/src/Adapter/AdapterAbstractServiceFactory.php +++ b/src/Adapter/AdapterAbstractServiceFactory.php @@ -3,7 +3,6 @@ namespace Laminas\Db\Adapter; use Laminas\ServiceManager\Factory\AbstractFactoryInterface; -use Laminas\ServiceManager\ServiceLocatorInterface; use Psr\Container\ContainerInterface; use function is_array; diff --git a/src/Adapter/AdapterInterface.php b/src/Adapter/AdapterInterface.php index ee8957745..312c754c9 100644 --- a/src/Adapter/AdapterInterface.php +++ b/src/Adapter/AdapterInterface.php @@ -28,7 +28,6 @@ interface AdapterInterface public const VALUE_QUOTE_SEPARATOR = 'quoteSeparator'; - /** * @return Driver\DriverInterface */ diff --git a/src/Adapter/Driver/AbstractConnection.php b/src/Adapter/Driver/AbstractConnection.php index 6d42c15c2..9abc1d85b 100644 --- a/src/Adapter/Driver/AbstractConnection.php +++ b/src/Adapter/Driver/AbstractConnection.php @@ -12,14 +12,14 @@ abstract class AbstractConnection implements ConnectionInterface, ProfilerAwareI { protected array $connectionParameters = []; - protected ?string $driverName; + protected string|null $driverName; protected bool $inTransaction = false; /** Nested transactions count. */ protected int $nestedTransactionsCount = 0; - protected ?ProfilerInterface $profiler = null; + protected ProfilerInterface|null $profiler = null; /** @var resource|null */ protected $resource; @@ -41,12 +41,12 @@ public function getConnectionParameters(): array } /** Get driver name */ - public function getDriverName(): ?string + public function getDriverName(): string|null { return $this->driverName; } - public function getProfiler(): ?ProfilerInterface + public function getProfiler(): ProfilerInterface|null { return $this->profiler; } diff --git a/src/Adapter/Driver/IbmDb2/Connection.php b/src/Adapter/Driver/IbmDb2/Connection.php index 69dd2108d..e0a464109 100644 --- a/src/Adapter/Driver/IbmDb2/Connection.php +++ b/src/Adapter/Driver/IbmDb2/Connection.php @@ -3,6 +3,8 @@ namespace Laminas\Db\Adapter\Driver\IbmDb2; use Laminas\Db\Adapter\Driver\AbstractConnection; +use Laminas\Db\Adapter\Driver\ConnectionInterface; +use Laminas\Db\Adapter\Driver\ResultInterface; use Laminas\Db\Adapter\Exception; use function get_resource_type; @@ -83,7 +85,7 @@ public function setResource($resource) /** * {@inheritDoc} */ - public function getCurrentSchema() + public function getCurrentSchema(): string|bool { if (! $this->isConnected()) { $this->connect(); @@ -97,7 +99,7 @@ public function getCurrentSchema() /** * {@inheritDoc} */ - public function connect() + public function connect(): ConnectionInterface { if (is_resource($this->resource)) { return $this; @@ -139,7 +141,7 @@ public function connect() /** * {@inheritDoc} */ - public function isConnected() + public function isConnected(): bool { return $this->resource !== null; } @@ -147,7 +149,7 @@ public function isConnected() /** * {@inheritDoc} */ - public function disconnect() + public function disconnect(): ConnectionInterface { if ($this->resource) { db2_close($this->resource); @@ -160,7 +162,7 @@ public function disconnect() /** * {@inheritDoc} */ - public function beginTransaction() + public function beginTransaction(): ConnectionInterface { if ($this->isI5() && ! ini_get('ibm_db2.i5_allow_commit')) { throw new Exception\RuntimeException( @@ -182,7 +184,7 @@ public function beginTransaction() /** * {@inheritDoc} */ - public function commit() + public function commit(): ConnectionInterface { if (! $this->isConnected()) { $this->connect(); @@ -207,7 +209,7 @@ public function commit() * @return $this Provides a fluent interface * @throws Exception\RuntimeException */ - public function rollback() + public function rollback(): static { if (! $this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); @@ -233,7 +235,7 @@ public function rollback() /** * {@inheritDoc} */ - public function execute($sql) + public function execute($sql): ResultInterface|null { if (! $this->isConnected()) { $this->connect(); @@ -243,8 +245,7 @@ public function execute($sql) $this->profiler->profilerStart($sql); } - set_error_handler(function () { - }, E_WARNING); // suppress warnings + set_error_handler(function () {}, E_WARNING); // suppress warnings $resultResource = db2_exec($this->resource, $sql); restore_error_handler(); @@ -263,7 +264,7 @@ public function execute($sql) /** * {@inheritDoc} */ - public function getLastGeneratedValue($name = null) + public function getLastGeneratedValue($name = null): string|int|bool|null { return db2_last_insert_id($this->resource); } diff --git a/src/Adapter/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php index dd7531bc6..25aa2c427 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdo.php +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -34,12 +34,11 @@ abstract class AbstractPdo implements PdoDriverInterface, DriverFeatureInterface //protected ResultInterface $resultPrototype; - // protected array $features = []; + // protected array $features = []; - /** @internal */ - public ?ProfilerInterface $profiler; + public ProfilerInterface|null $profiler; - /** + /** * @param $connection * @param string $features */ @@ -80,7 +79,7 @@ public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface return $this; } - public function getProfiler(): ?ProfilerInterface + public function getProfiler(): ProfilerInterface|null { return $this->profiler; } @@ -107,11 +106,9 @@ public function registerResultPrototype(ResultInterface $resultPrototype) * * todo: needs improvement * - * @param string $name - * @param AbstractFeature $feature * @return $this Provides a fluent interface */ - public function addFeature($name, $feature) + public function addFeature(string $name, AbstractFeature $feature): self { if ($feature instanceof AbstractFeature) { $name = $feature->getName(); // overwrite the name, just in case @@ -144,11 +141,8 @@ public function addFeature($name, $feature) /** * Get feature - * - * @param string $name - * @return AbstractFeature|false */ - public function getFeature($name) + public function getFeature(string $name): AbstractFeature|false { if (isset($this->features[$name])) { return $this->features[$name]; @@ -270,7 +264,7 @@ public function createStatement($sqlOrResource = null): StatementInterface // return $result; // } - public function getResultPrototype(): ?ResultInterface + public function getResultPrototype(): ResultInterface|null { return $this->resultPrototype; } @@ -280,7 +274,7 @@ public function getPrepareType(): string return self::PARAMETERIZATION_NAMED; } - public function formatParameterName(string|int $name, ?string $type = null): string + public function formatParameterName(string|int $name, string|null $type = null): string { if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { // proposed fix for passing $name as int with type self::PARAMETERIZATION_NAMED @@ -293,8 +287,8 @@ public function formatParameterName(string|int $name, ?string $type = null): str if (preg_match('/[^a-zA-Z0-9_]/', $name)) { throw new Exception\RuntimeException(sprintf( 'The PDO param %s contains invalid characters.' - . ' Only alphabetic characters, digits, and underscores (_)' - . ' are allowed.', + . ' Only alphabetic characters, digits, and underscores (_)' + . ' are allowed.', $name )); } @@ -304,7 +298,7 @@ public function formatParameterName(string|int $name, ?string $type = null): str return '?'; } - public function getLastGeneratedValue(?string $name = null): int|string|null|false + public function getLastGeneratedValue(string|null $name = null): int|string|null|false { return $this->connection->getLastGeneratedValue($name); } diff --git a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php index b372b7b99..276269b0b 100644 --- a/src/Adapter/Driver/Pdo/AbstractPdoConnection.php +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -28,7 +28,6 @@ abstract class AbstractPdoConnection extends AbstractConnection implements PdoDr /** @var ?PDO $resource */ protected $resource; - /** @var string */ protected ?string $dsn; /** @@ -140,7 +139,6 @@ public function setResource(PDO $resource): static /** * @inheritDoc - * * @throws Exception\InvalidConnectionParametersException * @throws Exception\RuntimeException */ @@ -324,7 +322,6 @@ public function commit(): ConnectionInterface /** * @inheritDoc - * * @throws Exception\RuntimeException */ public function rollback(): ConnectionInterface @@ -347,7 +344,6 @@ public function rollback(): ConnectionInterface /** * @inheritDoc - * * @throws Exception\InvalidQueryException */ public function execute($sql): ?ResultInterface diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index d1d0142d2..ddc4f339c 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -26,7 +26,7 @@ class Statement implements StatementInterface, PdoDriverAwareInterface, Profiler { protected PDO $pdo; - protected ?ProfilerInterface $profiler = null; + protected ProfilerInterface|null $profiler = null; protected PdoDriverInterface $driver; @@ -34,7 +34,7 @@ class Statement implements StatementInterface, PdoDriverAwareInterface, Profiler protected bool $isQuery; - protected ?ParameterContainer $parameterContainer = null; + protected ParameterContainer|null $parameterContainer = null; protected bool $parametersBound = false; @@ -59,52 +59,52 @@ public function getProfiler(): ?ProfilerInterface return $this->profiler; } - /** Initialize */ public function initialize(PDO $connectionResource): static { $this->pdo = $connectionResource; return $this; } - /** Set resource */ public function setResource(PDOStatement $pdoStatement): static { $this->resource = $pdoStatement; return $this; } - /** Get resource */ - public function getResource(): ?PDOStatement + public function getResource(): PDOStatement|null { return $this->resource; } - /** Set sql */ - public function setSql(?string $sql): StatementContainerInterface + public function setSql(string|null $sql): static { $this->sql = $sql; return $this; } - /** Get sql */ - public function getSql(): ?string + public function getSql(): string|null { return $this->sql; } - public function setParameterContainer(ParameterContainer $parameterContainer): StatementContainerInterface + /** + * @return $this Provides a fluent interface + */ + public function setParameterContainer(ParameterContainer $parameterContainer): self { $this->parameterContainer = $parameterContainer; return $this; } - public function getParameterContainer(): ?ParameterContainer + public function getParameterContainer(): ParameterContainer|null { return $this->parameterContainer; } - /** @throws Exception\RuntimeException */ - public function prepare(?string $sql = null): StatementInterface + /** + * @throws Exception\RuntimeException + */ + public function prepare(string|null $sql = null): static|null { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); @@ -131,8 +131,10 @@ public function isPrepared(): bool return $this->isPrepared; } - /** @throws Exception\InvalidQueryException */ - public function execute(null|array|ParameterContainer $parameters = null): ?ResultInterface + /** + * @throws Exception\InvalidQueryException + */ + public function execute(ParameterContainer|array|null $parameters = null): ResultInterface|null { if (! $this->isPrepared) { $this->prepare(); @@ -182,7 +184,9 @@ public function execute(null|array|ParameterContainer $parameters = null): ?Resu return $this->driver->createResult($this->resource, $this); } - /** Bind parameters from container */ + /** + * Bind parameters from container + */ protected function bindParametersFromContainer(): void { if ($this->parametersBound) { @@ -198,6 +202,7 @@ protected function bindParametersFromContainer(): void } else { $type = PDO::PARAM_STR; } + if ($this->parameterContainer->offsetHasErrata($name)) { switch ($this->parameterContainer->offsetGetErrata($name)) { case ParameterContainer::TYPE_INTEGER: diff --git a/src/Adapter/Driver/PdoDriverInterface.php b/src/Adapter/Driver/PdoDriverInterface.php index 329fa04d6..3b5d9d970 100644 --- a/src/Adapter/Driver/PdoDriverInterface.php +++ b/src/Adapter/Driver/PdoDriverInterface.php @@ -4,4 +4,6 @@ namespace Laminas\Db\Adapter\Driver; -interface PdoDriverInterface extends DriverInterface {} +interface PdoDriverInterface extends DriverInterface +{ +} diff --git a/src/Adapter/Driver/Pgsql/Pgsql.php b/src/Adapter/Driver/Pgsql/Pgsql.php index dd1f8af97..5990b62c6 100644 --- a/src/Adapter/Driver/Pgsql/Pgsql.php +++ b/src/Adapter/Driver/Pgsql/Pgsql.php @@ -2,9 +2,13 @@ namespace Laminas\Db\Adapter\Driver\Pgsql; +use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\DriverInterface; +use Laminas\Db\Adapter\Driver\ResultInterface; +use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Exception; use Laminas\Db\Adapter\Profiler; +use Laminas\Db\Adapter\Profiler\ProfilerAwareInterface; use function extension_loaded; use function is_string; @@ -52,7 +56,7 @@ public function __construct( /** * @return $this Provides a fluent interface */ - public function setProfiler(Profiler\ProfilerInterface $profiler) + public function setProfiler(Profiler\ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { @@ -77,7 +81,7 @@ public function getProfiler() * * @return $this Provides a fluent interface */ - public function registerConnection(Connection $connection) + public function registerConnection(ConnectionInterface $connection): DriverInterface { $this->connection = $connection; $this->connection->setDriver($this); @@ -113,7 +117,7 @@ public function registerResultPrototype(Result $result) * @param string $nameFormat * @return string */ - public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) + public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE): string { if ($nameFormat === self::NAME_FORMAT_CAMELCASE) { return 'Postgresql'; @@ -128,13 +132,15 @@ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCAS * @throws Exception\RuntimeException * @return void */ - public function checkEnvironment() + public function checkEnvironment(): bool { if (! extension_loaded('pgsql')) { throw new Exception\RuntimeException( 'The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded' ); } + + return true; } /** @@ -142,7 +148,7 @@ public function checkEnvironment() * * @return Connection */ - public function getConnection() + public function getConnection(): ConnectionInterface { return $this->connection; } @@ -153,7 +159,7 @@ public function getConnection() * @param string|null $sqlOrResource * @return Statement */ - public function createStatement($sqlOrResource = null) + public function createStatement($sqlOrResource = null): StatementInterface { $statement = clone $this->statementPrototype; @@ -175,7 +181,7 @@ public function createStatement($sqlOrResource = null) * @param resource $resource * @return Result */ - public function createResult($resource) + public function createResult($resource): ResultInterface { $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); @@ -195,7 +201,7 @@ public function getResultPrototype() * * @return string */ - public function getPrepareType() + public function getPrepareType(): string { return self::PARAMETERIZATION_POSITIONAL; } @@ -207,7 +213,7 @@ public function getPrepareType() * @param mixed $type * @return string */ - public function formatParameterName($name, $type = null) + public function formatParameterName($name, $type = null): string { return '$#'; } @@ -218,7 +224,7 @@ public function formatParameterName($name, $type = null) * @param string $name * @return mixed */ - public function getLastGeneratedValue($name = null) + public function getLastGeneratedValue($name = null): int|string|null|false { return $this->connection->getLastGeneratedValue($name); } diff --git a/src/Adapter/Driver/StatementInterface.php b/src/Adapter/Driver/StatementInterface.php index 1ae0592a8..2a84e5bd4 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -14,12 +14,18 @@ interface StatementInterface extends StatementContainerInterface */ public function getResource(); - /** Prepare sql */ - public function prepare(?string $sql = null): StatementInterface; + /** + * Prepare sql + */ + public function prepare(string|null $sql = null): static|null; - /** Check if is prepared */ + /** + * Check if is prepared + */ public function isPrepared(): bool; - /** Execute */ - public function execute(null|array|ParameterContainer $parameters = null): ?ResultInterface; + /** + * Execute + */ + public function execute(null|array|ParameterContainer $parameters = null): ResultInterface|null; } diff --git a/src/Adapter/Platform/AbstractPlatform.php b/src/Adapter/Platform/AbstractPlatform.php index 8868e90a2..7c756c081 100644 --- a/src/Adapter/Platform/AbstractPlatform.php +++ b/src/Adapter/Platform/AbstractPlatform.php @@ -30,7 +30,7 @@ abstract class AbstractPlatform implements PlatformInterface /** * {@inheritDoc} */ - public function quoteIdentifierInFragment($identifier, array $safeWords = []) + public function quoteIdentifierInFragment($identifier, array $safeWords = []): string { if (! $this->quoteIdentifiers) { return $identifier; @@ -65,7 +65,7 @@ public function quoteIdentifierInFragment($identifier, array $safeWords = []) /** * {@inheritDoc} */ - public function quoteIdentifier($identifier) + public function quoteIdentifier($identifier): string { if (! $this->quoteIdentifiers) { return $identifier; @@ -79,7 +79,7 @@ public function quoteIdentifier($identifier) /** * {@inheritDoc} */ - public function quoteIdentifierChain($identifierChain) + public function quoteIdentifierChain($identifierChain): string { return '"' . implode('"."', (array) str_replace('"', '\\"', $identifierChain)) . '"'; } @@ -87,7 +87,7 @@ public function quoteIdentifierChain($identifierChain) /** * {@inheritDoc} */ - public function getQuoteIdentifierSymbol() + public function getQuoteIdentifierSymbol(): string { return $this->quoteIdentifier[0]; } @@ -95,7 +95,7 @@ public function getQuoteIdentifierSymbol() /** * {@inheritDoc} */ - public function getQuoteValueSymbol() + public function getQuoteValueSymbol(): string { return '\''; } @@ -103,11 +103,11 @@ public function getQuoteValueSymbol() /** * {@inheritDoc} */ - public function quoteValue($value) + public function quoteValue($value): string { trigger_error( 'Attempting to quote a value in ' . static::class - . ' without extension/driver support can introduce security vulnerabilities in a production environment' + . ' without extension/driver support can introduce security vulnerabilities in a production environment' ); return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\''; } @@ -115,7 +115,7 @@ public function quoteValue($value) /** * {@inheritDoc} */ - public function quoteTrustedValue($value) + public function quoteTrustedValue($value): string { return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\''; } @@ -123,7 +123,7 @@ public function quoteTrustedValue($value) /** * {@inheritDoc} */ - public function quoteValueList($valueList) + public function quoteValueList($valueList): string { return implode(', ', array_map([$this, 'quoteValue'], (array) $valueList)); } @@ -131,7 +131,7 @@ public function quoteValueList($valueList) /** * {@inheritDoc} */ - public function getIdentifierSeparator() + public function getIdentifierSeparator(): string { return '.'; } diff --git a/src/Adapter/Platform/PlatformInterface.php b/src/Adapter/Platform/PlatformInterface.php index 98c774c29..1fbbf9a83 100644 --- a/src/Adapter/Platform/PlatformInterface.php +++ b/src/Adapter/Platform/PlatformInterface.php @@ -10,56 +10,44 @@ interface PlatformInterface { /** * Get name - * - * @return string */ - public function getName(); + public function getName(): string; /** * todo: sat-migration document * Get Sql platform decorator - */public function getSqlPlatformDecorator(): PlatformDecoratorInterface; + */ + public function getSqlPlatformDecorator(): PlatformDecoratorInterface; /** * Get quote identifier symbol - * - * @return string */ - public function getQuoteIdentifierSymbol(); + public function getQuoteIdentifierSymbol(): string; /** * Quote identifier - * - * @param string $identifier - * @return string */ - public function quoteIdentifier($identifier); + public function quoteIdentifier(string $identifier): string; /** * Quote identifier chain - * - * @param string|string[] $identifierChain - * @return string */ - public function quoteIdentifierChain($identifierChain); + public function quoteIdentifierChain(string|array $identifierChain): string; /** * Get quote value symbol * * @return string */ - public function getQuoteValueSymbol(); + public function getQuoteValueSymbol(): string; /** * Quote value * * Will throw a notice when used in a workflow that can be considered "unsafe" - * - * @param string $value - * @return string */ - public function quoteValue($value); + public function quoteValue(string $value): string; /** * Quote Trusted Value @@ -67,30 +55,21 @@ public function quoteValue($value); * The ability to quote values without notices * * @param scalar $value - * @return string */ - public function quoteTrustedValue($value); + public function quoteTrustedValue($value): string; /** * Quote value list - * - * @param string|string[] $valueList - * @return string */ - public function quoteValueList($valueList); + public function quoteValueList(string|array $valueList): string; /** * Get identifier separator - * - * @return string */ - public function getIdentifierSeparator(); + public function getIdentifierSeparator(): string; /** * Quote identifier in fragment - * - * @param string $identifier - * @return string */ - public function quoteIdentifierInFragment($identifier, array $additionalSafeWords = []); + public function quoteIdentifierInFragment(string $identifier, array $additionalSafeWords = []): string; } diff --git a/src/Adapter/StatementContainer.php b/src/Adapter/StatementContainer.php index 6a57e6292..e498fe664 100644 --- a/src/Adapter/StatementContainer.php +++ b/src/Adapter/StatementContainer.php @@ -10,10 +10,7 @@ class StatementContainer implements StatementContainerInterface /** @var ParameterContainer */ protected $parameterContainer; - /** - * @param string|null $sql - */ - public function __construct($sql = null, ?ParameterContainer $parameterContainer = null) + public function __construct(string|null $sql = null, ?ParameterContainer $parameterContainer = null) { if ($sql) { $this->setSql($sql); @@ -21,37 +18,24 @@ public function __construct($sql = null, ?ParameterContainer $parameterContainer $this->parameterContainer = $parameterContainer ?: new ParameterContainer(); } - /** - * @param string $sql - * @return $this Provides a fluent interface - */ - public function setSql($sql) + public function setSql(string|null $sql): static { $this->sql = $sql; return $this; } - /** - * @return string - */ - public function getSql() + public function getSql(): string|null { return $this->sql; } - /** - * @return $this Provides a fluent interface - */ - public function setParameterContainer(ParameterContainer $parameterContainer) + public function setParameterContainer(ParameterContainer $parameterContainer): static { $this->parameterContainer = $parameterContainer; return $this; } - /** - * @return null|ParameterContainer - */ - public function getParameterContainer() + public function getParameterContainer(): ParameterContainer|null { return $this->parameterContainer; } diff --git a/src/Adapter/StatementContainerInterface.php b/src/Adapter/StatementContainerInterface.php index 10fa1a491..f0b6c4485 100644 --- a/src/Adapter/StatementContainerInterface.php +++ b/src/Adapter/StatementContainerInterface.php @@ -6,15 +6,11 @@ interface StatementContainerInterface { - /** Set sql */ - public function setSql(?string $sql): StatementContainerInterface; + public function setSql(string|null $sql): static; - /** Get sql */ - public function getSql(): ?string; + public function getSql(): string|null; - /** Set parameter container */ - public function setParameterContainer(ParameterContainer $parameterContainer): StatementContainerInterface; + public function setParameterContainer(ParameterContainer $parameterContainer): static; - /** Get parameter container */ - public function getParameterContainer(): ?ParameterContainer; + public function getParameterContainer(): ParameterContainer|null; } diff --git a/src/Container/MetadataFactory.php b/src/Container/MetadataFactory.php index 6f8d39da3..0fc2860d1 100644 --- a/src/Container/MetadataFactory.php +++ b/src/Container/MetadataFactory.php @@ -6,13 +6,15 @@ use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Metadata\MetadataInterface; -use Laminas\ServiceManager\Factory\FactoryInterface; use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Laminas\ServiceManager\Factory\FactoryInterface; use Psr\Container\ContainerInterface; +use function sprintf; + final class MetadataFactory implements FactoryInterface { - public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null): MetadataInterface + public function __invoke(ContainerInterface $container, $requestedName, array|null $options = null): MetadataInterface { if (! $container->has(AdapterInterface::class)) { throw new ServiceNotFoundException(sprintf( diff --git a/src/Metadata/Source/Factory.php b/src/Metadata/Source/Factory.php index 1c288c497..b90a723cd 100644 --- a/src/Metadata/Source/Factory.php +++ b/src/Metadata/Source/Factory.php @@ -14,9 +14,10 @@ class Factory /** * Create source from adapter * + * @deprecated to be removed in 3.0.0 + * * @return MetadataInterface * @throws InvalidArgumentException If adapter platform name not recognized. - * @deprecated to be removed in 3.0.0 */ public static function createSourceFromAdapter(AdapterInterface $adapter) { diff --git a/src/Sql/AbstractSql.php b/src/Sql/AbstractSql.php index b9772d181..eb364326c 100644 --- a/src/Sql/AbstractSql.php +++ b/src/Sql/AbstractSql.php @@ -31,7 +31,7 @@ abstract class AbstractSql implements SqlInterface * * @var string[]|array[] */ - protected $specifications = []; + protected array $specifications = []; /** @var string */ protected $processInfo = ['paramPrefix' => '', 'subselectCount' => 0]; diff --git a/src/Sql/Ddl/CreateTable.php b/src/Sql/Ddl/CreateTable.php index d7cc75be9..0e8df5fd7 100644 --- a/src/Sql/Ddl/CreateTable.php +++ b/src/Sql/Ddl/CreateTable.php @@ -26,7 +26,7 @@ class CreateTable extends AbstractSql implements SqlInterface /** * {@inheritDoc} */ - protected $specifications = [ + protected array $specifications = [ self::TABLE => 'CREATE %1$sTABLE %2$s (', self::COLUMNS => [ "\n %1\$s" => [ diff --git a/src/Sql/Delete.php b/src/Sql/Delete.php index ffc655ed1..759ca6574 100644 --- a/src/Sql/Delete.php +++ b/src/Sql/Delete.php @@ -27,7 +27,7 @@ class Delete extends AbstractPreparableSql /** * {@inheritDoc} */ - protected $specifications = [ + protected array $specifications = [ self::SPECIFICATION_DELETE => 'DELETE FROM %1$s', self::SPECIFICATION_WHERE => 'WHERE %1$s', ]; diff --git a/src/Sql/Insert.php b/src/Sql/Insert.php index 7c0e8f556..fd761cc8e 100644 --- a/src/Sql/Insert.php +++ b/src/Sql/Insert.php @@ -33,27 +33,25 @@ class Insert extends AbstractPreparableSql /**#@-*/ /** @var string[]|array[] $specifications */ - protected $specifications = [ - self::SPECIFICATION_INSERT => 'INSERT INTO %1$s (%2$s) VALUES (%3$s)', - self::SPECIFICATION_SELECT => 'INSERT INTO %1$s %2$s %3$s', - ]; + protected array $specifications = []; - /** @var string|array|TableIdentifier */ protected TableIdentifier|string|array $table = ''; /** @var string[] */ - protected $columns = []; + protected array $columns = []; - /** @var array|Select */ - protected $select; + protected array|Select $select; /** * Constructor - * - * @param null|string|TableIdentifier $table */ - public function __construct($table = null) + public function __construct(null|string|TableIdentifier $table = null) { + $this->specifications = [ + self::SPECIFICATION_INSERT => 'INSERT INTO %1$s (%2$s) VALUES (%3$s)', + self::SPECIFICATION_SELECT => 'INSERT INTO %1$s %2$s %3$s', + ]; + if ($table) { $this->into($table); } @@ -62,10 +60,9 @@ public function __construct($table = null) /** * Create INTO clause * - * @param string|array|TableIdentifier $table * @return $this Provides a fluent interface */ - public function into($table): static + public function into(string|array|TableIdentifier $table): static { $this->table = $table; return $this; @@ -76,7 +73,7 @@ public function into($table): static * * @return $this Provides a fluent interface */ - public function columns(array $columns) + public function columns(array $columns): self { $this->columns = array_flip($columns); return $this; @@ -85,12 +82,11 @@ public function columns(array $columns) /** * Specify values to insert * - * @param array|Select $values * @param string $flag one of VALUES_MERGE or VALUES_SET; defaults to VALUES_SET * @return $this Provides a fluent interface * @throws Exception\InvalidArgumentException */ - public function values($values, $flag = self::VALUES_SET) + public function values(array|Select $values, string $flag = self::VALUES_SET) { if ($values instanceof Select) { if ($flag === self::VALUES_MERGE) { @@ -111,7 +107,7 @@ public function values($values, $flag = self::VALUES_SET) if ($this->select && $flag === self::VALUES_MERGE) { throw new Exception\InvalidArgumentException( 'An array of values cannot be provided with the merge flag when a Laminas\Db\Sql\Select' - . ' instance already exists as the value source' + . ' instance already exists as the value source' ); } @@ -134,7 +130,7 @@ public function values($values, $flag = self::VALUES_SET) * * @return bool */ - private function isAssocativeArray(array $array) + private function isAssocativeArray(array $array): bool { return array_keys($array) !== range(0, count($array) - 1); } @@ -151,11 +147,8 @@ public function select(Select $select) /** * Get raw state - * - * @param string $key - * @return mixed */ - public function getRawState($key = null) + public function getRawState(string|null $key = null): mixed { $rawState = [ 'table' => $this->table, @@ -167,8 +160,8 @@ public function getRawState($key = null) protected function processInsert( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if ($this->select) { return; @@ -210,8 +203,8 @@ protected function processInsert( protected function processSelect( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if (! $this->select) { return; @@ -234,11 +227,10 @@ protected function processSelect( * * Proxies to values, using VALUES_MERGE strategy * - * @param string $name * @param mixed $value * @return $this Provides a fluent interface */ - public function __set($name, $value) + public function __set(string $name, $value) { $this->columns[$name] = $value; return $this; @@ -249,11 +241,9 @@ public function __set($name, $value) * * Proxies to values and columns * - * @param string $name * @throws Exception\InvalidArgumentException - * @return void */ - public function __unset($name) + public function __unset(string $name): void { if (! array_key_exists($name, $this->columns)) { throw new Exception\InvalidArgumentException( @@ -268,11 +258,8 @@ public function __unset($name) * Overloading: variable isset * * Proxies to columns; does a column of that name exist? - * - * @param string $name - * @return bool */ - public function __isset($name) + public function __isset(string $name): bool { return array_key_exists($name, $this->columns); } @@ -282,11 +269,10 @@ public function __isset($name) * * Retrieves value by column name * - * @param string $name * @throws Exception\InvalidArgumentException * @return mixed */ - public function __get($name) + public function __get(string $name) { if (! array_key_exists($name, $this->columns)) { throw new Exception\InvalidArgumentException( diff --git a/src/Sql/Select.php b/src/Sql/Select.php index 7fdf54f43..28e1b3801 100644 --- a/src/Sql/Select.php +++ b/src/Sql/Select.php @@ -71,7 +71,7 @@ class Select extends AbstractPreparableSql /**#@-*/ /** @var string[]|array[] $specifications */ - protected $specifications = [ + protected array $specifications = [ 'statementStart' => '%1$s', self::SELECT => [ 'SELECT %1$s FROM %2$s' => [ @@ -204,7 +204,7 @@ public function quantifier($quantifier) if (! is_string($quantifier) && ! $quantifier instanceof ExpressionInterface) { throw new Exception\InvalidArgumentException( 'Quantifier must be one of DISTINCT, ALL, or some platform specific object implementing ' - . 'ExpressionInterface' + . 'ExpressionInterface' ); } $this->quantifier = $quantifier; @@ -558,8 +558,8 @@ protected function processSelect( foreach ($join['columns'] as $jKey => $jColumn) { $jColumns = []; $jFromTable = is_scalar($jColumn) - ? $joinName . $platform->getIdentifierSeparator() - : ''; + ? $joinName . $platform->getIdentifierSeparator() + : ''; $jColumns[] = $this->resolveColumnValue( [ 'column' => $jColumn, @@ -582,8 +582,8 @@ protected function processSelect( if ($this->quantifier) { $quantifier = $this->quantifier instanceof ExpressionInterface - ? $this->processExpression($this->quantifier, $platform, $driver, $parameterContainer, 'quantifier') - : $this->quantifier; + ? $this->processExpression($this->quantifier, $platform, $driver, $parameterContainer, 'quantifier') + : $this->quantifier; } if (! isset($table)) { diff --git a/src/Sql/Update.php b/src/Sql/Update.php index 96935bd8b..f3d97017f 100644 --- a/src/Sql/Update.php +++ b/src/Sql/Update.php @@ -25,17 +25,17 @@ class Update extends AbstractPreparableSql /**@#++ * @const */ - public const SPECIFICATION_UPDATE = 'update'; - public const SPECIFICATION_SET = 'set'; - public const SPECIFICATION_WHERE = 'where'; - public const SPECIFICATION_JOIN = 'joins'; + public const string SPECIFICATION_UPDATE = 'update'; + public const string SPECIFICATION_SET = 'set'; + public const string SPECIFICATION_WHERE = 'where'; + public const string SPECIFICATION_JOIN = 'joins'; - public const VALUES_MERGE = 'merge'; - public const VALUES_SET = 'set'; + public const string VALUES_MERGE = 'merge'; + public const string VALUES_SET = 'set'; /**@#-**/ /** @var array|array */ - protected $specifications = [ + protected array $specifications = [ self::SPECIFICATION_UPDATE => 'UPDATE %1$s', self::SPECIFICATION_JOIN => [ '%1$s' => [ @@ -46,27 +46,13 @@ class Update extends AbstractPreparableSql self::SPECIFICATION_WHERE => 'WHERE %1$s', ]; - /** @var string|array|TableIdentifier */ protected TableIdentifier|string|array $table = ''; + protected bool $emptyWhereProtection = true; + protected PriorityList $set; + protected string|Where $where; + protected null|Join $joins; - /** @var bool */ - protected $emptyWhereProtection = true; - - /** @var PriorityList */ - protected $set; - - /** @var string|Where */ - protected $where; - - /** @var null|Join */ - protected $joins; - - /** - * Constructor - * - * @param null|string|TableIdentifier $table - */ - public function __construct($table = null) + public function __construct(null|string|TableIdentifier $table = null) { if ($table) { $this->table($table); @@ -80,10 +66,9 @@ public function __construct($table = null) /** * Specify table for statement * - * @param string|array|TableIdentifier $table * @return $this Provides a fluent interface */ - public function table($table): static + public function table(string|array|TableIdentifier $table): static { $this->table = $table; return $this; @@ -97,7 +82,7 @@ public function table($table): static * @return $this Provides a fluent interface * @throws Exception\InvalidArgumentException */ - public function set(array $values, $flag = self::VALUES_SET) + public function set(array $values, string $flag = self::VALUES_SET): static { if ($flag === self::VALUES_SET) { $this->set->clear(); @@ -115,12 +100,10 @@ public function set(array $values, $flag = self::VALUES_SET) /** * Create where clause * - * @param Where|Closure|string|array|PredicateInterface $predicate - * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @return $this Provides a fluent interface * @throws Exception\InvalidArgumentException */ - public function where($predicate, $combination = Predicate\PredicateSet::OP_AND) + public function where(Where|Closure|string|array|PredicateInterface $predicate, string $combination = Predicate\PredicateSet::OP_AND) { if ($predicate instanceof Where) { $this->where = $predicate; @@ -133,13 +116,11 @@ public function where($predicate, $combination = Predicate\PredicateSet::OP_AND) /** * Create join clause * - * @param string|array $name - * @param string $on * @param string $type one of the JOIN_* constants * @return $this Provides a fluent interface * @throws Exception\InvalidArgumentException */ - public function join($name, $on, $type = Join::JOIN_INNER) + public function join(string|array $name, string $on, string $type = Join::JOIN_INNER) { $this->joins->join($name, $on, [], $type); @@ -147,10 +128,9 @@ public function join($name, $on, $type = Join::JOIN_INNER) } /** - * @param null|string $key * @return mixed|array */ - public function getRawState($key = null) + public function getRawState(null|string $key = null) { $rawState = [ 'emptyWhereProtection' => $this->emptyWhereProtection, @@ -162,24 +142,22 @@ public function getRawState($key = null) return isset($key) && array_key_exists($key, $rawState) ? $rawState[$key] : $rawState; } - /** @return string */ protected function processUpdate( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null - ) { + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null + ): string { return sprintf( $this->specifications[static::SPECIFICATION_UPDATE], $this->resolveTable($this->table, $platform, $driver, $parameterContainer) ); } - /** @return string */ protected function processSet( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null - ) { + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null + ): string { $setSql = []; $i = 0; foreach ($this->set as $column => $value) { @@ -221,8 +199,8 @@ protected function processSet( protected function processWhere( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if ($this->where->count() === 0) { return; @@ -236,9 +214,9 @@ protected function processWhere( /** @return null|string[] */ protected function processJoins( PlatformInterface $platform, - ?Driver\DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null - ) { + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null + ): array|null { return $this->processJoin($this->joins, $platform, $driver, $parameterContainer); } @@ -247,10 +225,9 @@ protected function processJoins( * * Proxies to "where" only * - * @param string $name * @return mixed */ - public function __get($name) + public function __get(string $name) { if (strtolower($name) === 'where') { return $this->where; @@ -258,13 +235,9 @@ public function __get($name) } /** - * __clone - * * Resets the where object each time the Update is cloned. - * - * @return void */ - public function __clone() + public function __clone(): void { $this->where = clone $this->where; $this->set = clone $this->set; diff --git a/src/TableGateway/Feature/MetadataFeature.php b/src/TableGateway/Feature/MetadataFeature.php index 89da476c4..92dd41c95 100644 --- a/src/TableGateway/Feature/MetadataFeature.php +++ b/src/TableGateway/Feature/MetadataFeature.php @@ -14,19 +14,15 @@ class MetadataFeature extends AbstractFeature { - /** - * Constructor - */ - public function __construct( - protected MetadataInterface $metadata - ) { + public function __construct(protected MetadataInterface $metadata) + { $this->sharedData['metadata'] = [ 'primaryKey' => null, 'columns' => [], ]; } - public function postInitialize() + public function postInitialize(): void { // localize variable for brevity $t = $this->tableGateway; diff --git a/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php b/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php index 8baf76151..a974c5678 100644 --- a/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php +++ b/test/unit/Adapter/AdapterAbstractServiceFactoryTest.php @@ -2,8 +2,8 @@ namespace LaminasTest\Db\Adapter; -use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Adapter\AdapterAbstractServiceFactory; +use Laminas\Db\Adapter\AdapterInterface; use Laminas\ServiceManager\Config; use Laminas\ServiceManager\Exception\ServiceNotFoundException; use Laminas\ServiceManager\ServiceManager; diff --git a/test/unit/Sql/Platform/Mysql/SelectDecoratorTest.php b/test/unit/Sql/Platform/Mysql/SelectDecoratorTest.php index b48324b1e..941a4b35c 100644 --- a/test/unit/Sql/Platform/Mysql/SelectDecoratorTest.php +++ b/test/unit/Sql/Platform/Mysql/SelectDecoratorTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql\Platform\Mysql; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\Mysqli\Statement; use Laminas\Db\Adapter\Driver\Pdo\Connection; @@ -76,8 +76,8 @@ public function testPrepareStatementForSqlObject( $newStatement = new Statement(); $driver = new Pdo(new Connection()); $mockAdapter = $this->getMockBuilder(Adapter::class) - ->setConstructorArgs([$driver, new TrustingMysqlPlatform()]) - ->getMock(); + ->setConstructorArgs([$driver, new TrustingMysqlPlatform()]) + ->getMock(); $trustingPlatform = new TrustingMysqlPlatform(); $mockAdapter->expects($this->any())->method('getPlatform')->willReturn($trustingPlatform); $mockAdapter->expects($this->any())->method('getDriver')->willReturn($driver); @@ -159,8 +159,8 @@ public static function dataProvider(): array "SELECT (SELECT count(foo1.id) AS `cnt` FROM `foo1` LIMIT ? OFFSET ?) AS `res`" . " FROM `foo` LIMIT ? OFFSET ?"; $expectedPrepareObjectSql3 = - "SELECT (SELECT count(foo1.id) AS `cnt` FROM `foo1` LIMIT :subselect1limit OFFSET :subselect1offset) AS `res`" - . " FROM `foo` LIMIT :limit OFFSET :offset"; + "SELECT (SELECT count(foo1.id) AS `cnt` FROM `foo1` LIMIT :subselect1limit OFFSET :subselect1offset) AS `res`" + . " FROM `foo` LIMIT :limit OFFSET :offset"; $expectedParams3 = [ 'subselect1limit' => 100, 'subselect1offset' => 500, diff --git a/test/unit/Sql/Platform/PlatformTest.php b/test/unit/Sql/Platform/PlatformTest.php index c55b8627b..9df3f12b7 100644 --- a/test/unit/Sql/Platform/PlatformTest.php +++ b/test/unit/Sql/Platform/PlatformTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql\Platform; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\StatementContainer; use Laminas\Db\Sql\Exception\RuntimeException; diff --git a/test/unit/Sql/SelectTest.php b/test/unit/Sql/SelectTest.php index 68340079b..99eaba0e2 100644 --- a/test/unit/Sql/SelectTest.php +++ b/test/unit/Sql/SelectTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\ParameterContainer; @@ -768,7 +768,7 @@ public static function providerData(): array $select0 = new Select(); $select0->from('foo'); $sqlPrep0 = // same - $sqlStr0 = 'SELECT "foo".* FROM "foo"'; + $sqlStr0 = 'SELECT "foo".* FROM "foo"'; $internalTests0 = [ 'processSelect' => [[['"foo".*']], '"foo"'], ]; @@ -777,7 +777,7 @@ public static function providerData(): array $select1 = new Select(); $select1->from(new TableIdentifier('foo', 'bar')); $sqlPrep1 = // same - $sqlStr1 = 'SELECT "bar"."foo".* FROM "bar"."foo"'; + $sqlStr1 = 'SELECT "bar"."foo".* FROM "bar"."foo"'; $internalTests1 = [ 'processSelect' => [[['"bar"."foo".*']], '"bar"."foo"'], ]; @@ -786,7 +786,7 @@ public static function providerData(): array $select2 = new Select(); $select2->from(['f' => 'foo']); $sqlPrep2 = // same - $sqlStr2 = 'SELECT "f".* FROM "foo" AS "f"'; + $sqlStr2 = 'SELECT "f".* FROM "foo" AS "f"'; $internalTests2 = [ 'processSelect' => [[['"f".*']], '"foo" AS "f"'], ]; @@ -795,7 +795,7 @@ public static function providerData(): array $select3 = new Select(); $select3->from(['f' => new TableIdentifier('foo')]); $sqlPrep3 = // same - $sqlStr3 = 'SELECT "f".* FROM "foo" AS "f"'; + $sqlStr3 = 'SELECT "f".* FROM "foo" AS "f"'; $internalTests3 = [ 'processSelect' => [[['"f".*']], '"foo" AS "f"'], ]; @@ -804,7 +804,7 @@ public static function providerData(): array $select4 = new Select(); $select4->from('foo')->columns(['bar', 'baz']); $sqlPrep4 = // same - $sqlStr4 = 'SELECT "foo"."bar" AS "bar", "foo"."baz" AS "baz" FROM "foo"'; + $sqlStr4 = 'SELECT "foo"."bar" AS "bar", "foo"."baz" AS "baz" FROM "foo"'; $internalTests4 = [ 'processSelect' => [[['"foo"."bar"', '"bar"'], ['"foo"."baz"', '"baz"']], '"foo"'], ]; @@ -813,7 +813,7 @@ public static function providerData(): array $select5 = new Select(); $select5->from('foo')->columns(['bar' => 'baz']); $sqlPrep5 = // same - $sqlStr5 = 'SELECT "foo"."baz" AS "bar" FROM "foo"'; + $sqlStr5 = 'SELECT "foo"."baz" AS "bar" FROM "foo"'; $internalTests5 = [ 'processSelect' => [[['"foo"."baz"', '"bar"']], '"foo"'], ]; @@ -822,7 +822,7 @@ public static function providerData(): array $select6 = new Select(); $select6->from('foo')->columns(['bar' => 'baz', 'bam']); $sqlPrep6 = // same - $sqlStr6 = 'SELECT "foo"."baz" AS "bar", "foo"."bam" AS "bam" FROM "foo"'; + $sqlStr6 = 'SELECT "foo"."baz" AS "bar", "foo"."bam" AS "bam" FROM "foo"'; $internalTests6 = [ 'processSelect' => [[['"foo"."baz"', '"bar"'], ['"foo"."bam"', '"bam"']], '"foo"'], ]; @@ -831,7 +831,7 @@ public static function providerData(): array $select7 = new Select(); $select7->from('foo')->columns(['bar' => new Expression('COUNT(some_column)')]); $sqlPrep7 = // same - $sqlStr7 = 'SELECT COUNT(some_column) AS "bar" FROM "foo"'; + $sqlStr7 = 'SELECT COUNT(some_column) AS "bar" FROM "foo"'; $internalTests7 = [ 'processSelect' => [[['COUNT(some_column)', '"bar"']], '"foo"'], ]; @@ -840,7 +840,7 @@ public static function providerData(): array $select8 = new Select(); $select8->from('foo')->columns([new Expression('COUNT(some_column) AS bar')]); $sqlPrep8 = // same - $sqlStr8 = 'SELECT COUNT(some_column) AS bar FROM "foo"'; + $sqlStr8 = 'SELECT COUNT(some_column) AS bar FROM "foo"'; $internalTests8 = [ 'processSelect' => [[['COUNT(some_column) AS bar']], '"foo"'], ]; diff --git a/test/unit/Sql/SqlFunctionalTest.php b/test/unit/Sql/SqlFunctionalTest.php index e5f419a4a..ac5faebb6 100644 --- a/test/unit/Sql/SqlFunctionalTest.php +++ b/test/unit/Sql/SqlFunctionalTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql; -use Laminas\Db\Adapter; +use Laminas\Db\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\ParameterContainer; diff --git a/test/unit/Sql/SqlTest.php b/test/unit/Sql/SqlTest.php index dfd19e713..216c569ab 100644 --- a/test/unit/Sql/SqlTest.php +++ b/test/unit/Sql/SqlTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\ResultInterface; diff --git a/test/unit/Sql/UpdateTest.php b/test/unit/Sql/UpdateTest.php index 289f0c53a..90afd8723 100644 --- a/test/unit/Sql/UpdateTest.php +++ b/test/unit/Sql/UpdateTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\Sql; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\ParameterContainer; @@ -282,8 +282,8 @@ public function testCloneUpdate(): void { $update1 = clone $this->update; $update1->table('foo') - ->set(['bar' => 'baz']) - ->where('x = y'); + ->set(['bar' => 'baz']) + ->where('x = y'); $update2 = clone $this->update; $update2->table('foo') @@ -368,7 +368,7 @@ public function testJoin(): void self::assertEquals( 'UPDATE "Document" INNER JOIN "User" ON "User"."UserId" = "Document"."UserId" ' - . 'LEFT JOIN "Category" ON "Category"."CategoryId" = "Document"."CategoryId" SET "x" = \'y\'', + . 'LEFT JOIN "Category" ON "Category"."CategoryId" = "Document"."CategoryId" SET "x" = \'y\'', $this->update->getSqlString(new TrustingSql92Platform()) ); } @@ -394,7 +394,7 @@ public function testJoinMultiUpdate(): void self::assertEquals( 'UPDATE "Document" INNER JOIN "User" ON "User"."UserId" = "Document"."UserId" ' - . 'LEFT JOIN "Category" ON "Category"."CategoryId" = "Document"."CategoryId" SET "Documents"."x" = \'y\'', + . 'LEFT JOIN "Category" ON "Category"."CategoryId" = "Document"."CategoryId" SET "Documents"."x" = \'y\'', $this->update->getSqlString(new TrustingSql92Platform()) ); } diff --git a/test/unit/TableGateway/AbstractTableGatewayTest.php b/test/unit/TableGateway/AbstractTableGatewayTest.php index 69a21994a..da605cde7 100644 --- a/test/unit/TableGateway/AbstractTableGatewayTest.php +++ b/test/unit/TableGateway/AbstractTableGatewayTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\TableGateway; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\ResultInterface; diff --git a/test/unit/TableGateway/Feature/FeatureSetTest.php b/test/unit/TableGateway/Feature/FeatureSetTest.php index 6549d89ff..12663003f 100644 --- a/test/unit/TableGateway/Feature/FeatureSetTest.php +++ b/test/unit/TableGateway/Feature/FeatureSetTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\TableGateway\Feature; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\Pgsql\Result; diff --git a/test/unit/TableGateway/Feature/SequenceFeatureTest.php b/test/unit/TableGateway/Feature/SequenceFeatureTest.php index cccdf4dc0..453f3ac0b 100644 --- a/test/unit/TableGateway/Feature/SequenceFeatureTest.php +++ b/test/unit/TableGateway/Feature/SequenceFeatureTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\TableGateway\Feature; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\ResultInterface; use Laminas\Db\Adapter\Driver\StatementInterface; use Laminas\Db\Adapter\Platform\PlatformInterface; diff --git a/test/unit/TableGateway/TableGatewayTest.php b/test/unit/TableGateway/TableGatewayTest.php index 9b7c9ab91..b3dc34114 100644 --- a/test/unit/TableGateway/TableGatewayTest.php +++ b/test/unit/TableGateway/TableGatewayTest.php @@ -2,7 +2,7 @@ namespace LaminasTest\Db\TableGateway; -use Laminas\Db\Adapter\Adapter; +use Laminas\Db\Adapter\AbstractAdapter as Adapter; use Laminas\Db\Adapter\Driver\ConnectionInterface; use Laminas\Db\Adapter\Driver\DriverInterface; use Laminas\Db\Adapter\Driver\ResultInterface; From 39538ec138101a3a34bc43fd4f027305f8edf326 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 26 May 2025 20:30:59 -0500 Subject: [PATCH 31/32] Refactor AdapterServiceFactory to align with AdapterManager implementation Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/Adapter/AdapterServiceFactory.php | 23 +++++++++++------------ src/Container/ConfigProvider.php | 5 ++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Adapter/AdapterServiceFactory.php b/src/Adapter/AdapterServiceFactory.php index 7708c5acc..fc88d68c4 100644 --- a/src/Adapter/AdapterServiceFactory.php +++ b/src/Adapter/AdapterServiceFactory.php @@ -1,22 +1,21 @@ get('config'); - return new Adapter($config['db']); + public function __invoke(ContainerInterface $container): AdapterInterface { + $adapterManager = $container->get(AdapterManager::class); + return $adapterManager->get(AdapterInterface::class); } } diff --git a/src/Container/ConfigProvider.php b/src/Container/ConfigProvider.php index 6852d37ba..32e000e27 100644 --- a/src/Container/ConfigProvider.php +++ b/src/Container/ConfigProvider.php @@ -4,6 +4,8 @@ namespace Laminas\Db\Container; +use Laminas\Db\Adapter; + final class ConfigProvider { public function __invoke(): array @@ -17,7 +19,8 @@ public function getDependencies(): array { return [ 'factories' => [ - AdapterManager::class => AdapterManagerFactory::class, + Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, + AdapterManager::class => AdapterManagerFactory::class, ], ]; } From d58b03028d1d53d401dc3ebdeb3a063d772925b6 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 26 May 2025 21:59:36 -0500 Subject: [PATCH 32/32] Signed-off-by: Joey Smith --- src/Container/AdapterManager.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Container/AdapterManager.php b/src/Container/AdapterManager.php index 21c25c60d..e470e4378 100644 --- a/src/Container/AdapterManager.php +++ b/src/Container/AdapterManager.php @@ -14,23 +14,11 @@ use Override; use Psr\Container\ContainerInterface; -use function array_replace_recursive; use function get_debug_type; use function sprintf; final class AdapterManager extends AbstractPluginManager { - - // private const CONFIG = [ - // 'factories' => [ - // Driver\DriverInterface::class => Driver\DriverServiceDelegator::class, - // Driver\ConnectionInterface::class => Driver\ConnectionServiceDelegator::class, - // Platform\PlatformInterface::class => Platform\PlatformServiceDelegator::class, - // Profiler\ProfilerInterface::class => Profiler\ProfilerServiceDelegator::class, - // Metadata\MetadataInterface::class => Metadata\MetadataServiceDelegator::class, - // ], - // ]; - public function __construct( ContainerInterface $container, array $config = [], @@ -53,6 +41,7 @@ public function validate(mixed $instance): void $instance instanceof AdapterInterface, $instance instanceof Driver\DriverInterface, $instance instanceof Driver\ConnectionInterface, + $instance instanceof Driver\ResultInterface, $instance instanceof Platform\PlatformInterface, $instance instanceof Profiler\ProfilerInterface, $instance instanceof Metadata\MetadataInterface => true,