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: diff --git a/composer.json b/composer.json index fabca6d93..bdd8f83c8 100644 --- a/composer.json +++ b/composer.json @@ -24,21 +24,19 @@ "dealerdirect/phpcodesniffer-composer-installer": true } }, - "extra": { + "extra": { "laminas": { - "component": "Laminas\\Db", - "config-provider": "Laminas\\Db\\ConfigProvider" + "config-provider": "Laminas\\Db\\Container\\ConfigProvider" } }, "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", "phpunit/phpunit": "^11.5.12", "psalm/plugin-phpunit": "^0.19.2", "rector/rector": "^2.0", @@ -46,8 +44,7 @@ }, "suggest": { "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^3.2 || ^4.3) 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": { @@ -66,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/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/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/AbstractAdapter.php b/src/Adapter/AbstractAdapter.php new file mode 100644 index 000000000..2138588e7 --- /dev/null +++ b/src/Adapter/AbstractAdapter.php @@ -0,0 +1,327 @@ +driver)) { + $parameters = $this->driver; + if ($this->profiler === null && isset($parameters['profiler'])) { + $profiler = $this->createProfiler($parameters); + } + $this->driver = $this->createDriver($parameters); + } + + $this->driver->checkEnvironment(); + + $this->platform = $this->platform ?? $this->createPlatform($parameters); + $this->queryResultSetPrototype = $this->queryResultSetPrototype ?? new ResultSet\ResultSet(); + + if ($profiler) { + $this->setProfiler($profiler); + } + } + + /** + * @return $this Provides a fluent interface + */ + public function setProfiler(Profiler\ProfilerInterface $profiler): self + { + $this->profiler = $profiler; + if ($this->driver instanceof Profiler\ProfilerAwareInterface) { + $this->driver->setProfiler($profiler); + } + return $this; + } + + public function getProfiler(): ?Profiler\ProfilerInterface + { + return $this->profiler; + } + + /** + * @throws Exception\RuntimeException + */ + public function getDriver(): Driver\DriverInterface|array + { + if ($this->driver === null) { + throw new Exception\RuntimeException('Driver has not been set or configured for this adapter.'); + } + return $this->driver; + } + + public function getPlatform(): ?Platform\PlatformInterface + { + return $this->platform; + } + + public function getQueryResultSetPrototype(): ResultSet\ResultSetInterface + { + return $this->queryResultSetPrototype; + } + + public function getCurrentSchema(): string + { + return $this->driver->getConnection()->getCurrentSchema(); + } + + /** + * query() is a convenience function + * + * @throws Exception\InvalidArgumentException + * @throws PhpException + */ + public function query( + string $sql, + ParameterContainer|array|string $parametersOrQueryMode = self::QUERY_MODE_PREPARE, + ?ResultSet\ResultSetInterface $resultPrototype = null + ): Driver\StatementInterface|ResultSet\ResultSet|Driver\ResultInterface { + if ( + is_string($parametersOrQueryMode) + && in_array($parametersOrQueryMode, [self::QUERY_MODE_PREPARE, self::QUERY_MODE_EXECUTE]) + ) { + $mode = $parametersOrQueryMode; + $parameters = null; + } elseif (is_array($parametersOrQueryMode) || $parametersOrQueryMode instanceof ParameterContainer) { + $mode = self::QUERY_MODE_PREPARE; + $parameters = $parametersOrQueryMode; + } else { + throw new Exception\InvalidArgumentException( + 'Parameter 2 to this method must be a flag, an array, or ParameterContainer' + ); + } + + if ($mode === self::QUERY_MODE_PREPARE) { + $lastPreparedStatement = $this->driver->createStatement($sql); + $lastPreparedStatement->prepare(); + if (is_array($parameters) || $parameters instanceof ParameterContainer) { + if (is_array($parameters)) { + $lastPreparedStatement->setParameterContainer(new ParameterContainer($parameters)); + } else { + $lastPreparedStatement->setParameterContainer($parameters); + } + $result = $lastPreparedStatement->execute(); + } else { + return $lastPreparedStatement; + } + } else { + $result = $this->driver->getConnection()->execute($sql); + } + + if ($result instanceof Driver\ResultInterface && $result->isQueryResult()) { + $resultSet = $resultPrototype ?? $this->queryResultSetPrototype; + $resultSetCopy = clone $resultSet; + + $resultSetCopy->initialize($result); + + return $resultSetCopy; + } + + return $result; + } + + /** + * Create statement + */ + public function createStatement( + ?string $initialSql = null, + ParameterContainer|array|null $initialParameters = null + ): Driver\StatementInterface { + $statement = $this->driver->createStatement($initialSql); + if ( + $initialParameters === null + || ! $initialParameters instanceof ParameterContainer + && is_array($initialParameters) + ) { + $initialParameters = new ParameterContainer(is_array($initialParameters) ? $initialParameters : []); + } + $statement->setParameterContainer($initialParameters); + return $statement; + } + + public function getHelpers() + { + $functions = []; + $platform = $this->platform; + foreach (func_get_args() as $arg) { + switch ($arg) { + case self::FUNCTION_QUOTE_IDENTIFIER: + $functions[] = function ($value) use ($platform) { + return $platform->quoteIdentifier($value); + }; + break; + case self::FUNCTION_QUOTE_VALUE: + $functions[] = function ($value) use ($platform) { + return $platform->quoteValue($value); + }; + break; + } + } + } + + /** + * @throws Exception\InvalidArgumentException + * @return Driver\DriverInterface|Platform\PlatformInterface + */ + public function __get(string $name) + { + return match (strtolower($name)) { + 'driver' => $this->driver, + 'platform' => $this->platform, + default => throw new Exception\InvalidArgumentException('Invalid magic property on adapter'), + }; + } + + // 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 + { + if ($parameters['profiler'] instanceof Profiler\ProfilerInterface) { + return $parameters['profiler']; + } + + if (is_bool($parameters['profiler'])) { + return $parameters['profiler'] === true ? new Profiler\Profiler() : null; + } + + throw new Exception\InvalidArgumentException( + '"profiler" parameter must be an instance of ProfilerInterface or a boolean' + ); + } +} diff --git a/src/Adapter/Adapter.php b/src/Adapter/Adapter.php deleted file mode 100644 index ad3c7c0e1..000000000 --- a/src/Adapter/Adapter.php +++ /dev/null @@ -1,364 +0,0 @@ -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 - ); - } - - $driver->checkEnvironment(); - $this->driver = $driver; - - if ($platform === null) { - $platform = $this->createPlatform($parameters); - } - - $this->platform = $platform; - $this->queryResultSetPrototype = $queryResultPrototype ?: new ResultSet\ResultSet(); - - if ($profiler) { - $this->setProfiler($profiler); - } - } - - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler): self - { - $this->profiler = $profiler; - if ($this->driver instanceof Profiler\ProfilerAwareInterface) { - $this->driver->setProfiler($profiler); - } - return $this; - } - - public function getProfiler(): ?Profiler\ProfilerInterface - { - return $this->profiler; - } - - /** - * @throws Exception\RuntimeException - */ - public function getDriver(): Driver\DriverInterface|array - { - if ($this->driver === null) { - throw new Exception\RuntimeException('Driver has not been set or configured for this adapter.'); - } - return $this->driver; - } - - public function getPlatform(): ?Platform\PlatformInterface - { - return $this->platform; - } - - public function getQueryResultSetPrototype(): ResultSet\ResultSetInterface - { - return $this->queryResultSetPrototype; - } - - public function getCurrentSchema(): string - { - return $this->driver->getConnection()->getCurrentSchema(); - } - - /** - * query() is a convenience function - * - * @throws Exception\InvalidArgumentException - * @throws PhpException - */ - public function query( - string $sql, - ParameterContainer|array|string $parametersOrQueryMode = self::QUERY_MODE_PREPARE, - ?ResultSet\ResultSetInterface $resultPrototype = null - ): Driver\StatementInterface|ResultSet\ResultSet|Driver\ResultInterface { - if ( - is_string($parametersOrQueryMode) - && in_array($parametersOrQueryMode, [self::QUERY_MODE_PREPARE, self::QUERY_MODE_EXECUTE]) - ) { - $mode = $parametersOrQueryMode; - $parameters = null; - } elseif (is_array($parametersOrQueryMode) || $parametersOrQueryMode instanceof ParameterContainer) { - $mode = self::QUERY_MODE_PREPARE; - $parameters = $parametersOrQueryMode; - } else { - throw new Exception\InvalidArgumentException( - 'Parameter 2 to this method must be a flag, an array, or ParameterContainer' - ); - } - - if ($mode === self::QUERY_MODE_PREPARE) { - $lastPreparedStatement = $this->driver->createStatement($sql); - $lastPreparedStatement->prepare(); - if (is_array($parameters) || $parameters instanceof ParameterContainer) { - if (is_array($parameters)) { - $lastPreparedStatement->setParameterContainer(new ParameterContainer($parameters)); - } else { - $lastPreparedStatement->setParameterContainer($parameters); - } - $result = $lastPreparedStatement->execute(); - } else { - return $lastPreparedStatement; - } - } else { - $result = $this->driver->getConnection()->execute($sql); - } - - if ($result instanceof Driver\ResultInterface && $result->isQueryResult()) { - $resultSet = $resultPrototype ?? $this->queryResultSetPrototype; - $resultSetCopy = clone $resultSet; - - $resultSetCopy->initialize($result); - - return $resultSetCopy; - } - - return $result; - } - - /** - * Create statement - */ - public function createStatement( - ?string $initialSql = null, - ParameterContainer|array|null $initialParameters = null - ): Driver\StatementInterface { - $statement = $this->driver->createStatement($initialSql); - if ( - $initialParameters === null - || ! $initialParameters instanceof ParameterContainer - && is_array($initialParameters) - ) { - $initialParameters = new ParameterContainer(is_array($initialParameters) ? $initialParameters : []); - } - $statement->setParameterContainer($initialParameters); - return $statement; - } - - public function getHelpers() - { - $functions = []; - $platform = $this->platform; - foreach (func_get_args() as $arg) { - switch ($arg) { - case self::FUNCTION_QUOTE_IDENTIFIER: - $functions[] = function ($value) use ($platform) { - return $platform->quoteIdentifier($value); - }; - break; - case self::FUNCTION_QUOTE_VALUE: - $functions[] = function ($value) use ($platform) { - return $platform->quoteValue($value); - }; - break; - } - } - } - - /** - * @throws Exception\InvalidArgumentException - * @return Driver\DriverInterface|Platform\PlatformInterface - */ - public function __get(string $name) - { - return match (strtolower($name)) { - 'driver' => $this->driver, - 'platform' => $this->platform, - default => throw new Exception\InvalidArgumentException('Invalid magic property on adapter'), - }; - } - - 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 - { - if ($parameters['profiler'] instanceof Profiler\ProfilerInterface) { - return $parameters['profiler']; - } - - if (is_bool($parameters['profiler'])) { - return $parameters['profiler'] === true ? new Profiler\Profiler() : null; - } - - throw new Exception\InvalidArgumentException( - '"profiler" parameter must be an instance of ProfilerInterface or a boolean' - ); - } -} diff --git a/src/Adapter/AdapterAbstractServiceFactory.php b/src/Adapter/AdapterAbstractServiceFactory.php index 6b238f162..e45cee3d3 100644 --- a/src/Adapter/AdapterAbstractServiceFactory.php +++ b/src/Adapter/AdapterAbstractServiceFactory.php @@ -2,9 +2,8 @@ namespace Laminas\Db\Adapter; -use Interop\Container\ContainerInterface; -use Laminas\ServiceManager\AbstractFactoryInterface; -use Laminas\ServiceManager\ServiceLocatorInterface; +use Laminas\ServiceManager\Factory\AbstractFactoryInterface; +use Psr\Container\ContainerInterface; use function is_array; @@ -36,18 +35,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 +47,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/AdapterAwareInterface.php b/src/Adapter/AdapterAwareInterface.php index e5342a5d3..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(Adapter $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; diff --git a/src/Adapter/AdapterInterface.php b/src/Adapter/AdapterInterface.php index 50980d656..312c754c9 100644 --- a/src/Adapter/AdapterInterface.php +++ b/src/Adapter/AdapterInterface.php @@ -1,5 +1,7 @@ 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); - if (! $databaseAdapter instanceof Adapter) { + if (! $databaseAdapter instanceof AdapterInterface) { return $instance; } diff --git a/src/Adapter/AdapterServiceFactory.php b/src/Adapter/AdapterServiceFactory.php index 470c23725..fc88d68c4 100644 --- a/src/Adapter/AdapterServiceFactory.php +++ b/src/Adapter/AdapterServiceFactory.php @@ -1,32 +1,21 @@ get('config'); - return new Adapter($config['db']); - } - - /** - * Create db adapter service (v2) - * - * @return Adapter + * Create db AdapterInterface instance + * This is now managed by the AdapterManager + * Satellite packages now delegate the creation context of the AdapterManager */ - public function createService(ServiceLocatorInterface $container) - { - return $this($container, Adapter::class); + public function __invoke(ContainerInterface $container): AdapterInterface { + $adapterManager = $container->get(AdapterManager::class); + return $adapterManager->get(AdapterInterface::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 @@ +isConnected()) { $this->resource = null; @@ -41,39 +34,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|null { return $this->driverName; } - /** - * @return null|ProfilerInterface - */ - public function getProfiler() + public function getProfiler(): ProfilerInterface|null { return $this->profiler; } - /** - * {@inheritDoc} - * - * @return resource - */ + #[Override] public function getResource() { if (! $this->isConnected()) { @@ -83,32 +61,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): ProfilerAwareInterface { $this->profiler = $profiler; diff --git a/src/Adapter/Driver/ConnectionInterface.php b/src/Adapter/Driver/ConnectionInterface.php index 39ba2b3fe..4d7958f2f 100644 --- a/src/Adapter/Driver/ConnectionInterface.php +++ b/src/Adapter/Driver/ConnectionInterface.php @@ -1,78 +1,48 @@ 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/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/Driver/Pdo/AbstractPdo.php b/src/Adapter/Driver/Pdo/AbstractPdo.php new file mode 100644 index 000000000..25aa2c427 --- /dev/null +++ b/src/Adapter/Driver/Pdo/AbstractPdo.php @@ -0,0 +1,305 @@ +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; + if ($this->connection instanceof ProfilerAwareInterface) { + $this->connection->setProfiler($profiler); + } + if ($this->statementPrototype instanceof ProfilerAwareInterface) { + $this->statementPrototype->setProfiler($profiler); + } + return $this; + } + + public function getProfiler(): ProfilerInterface|null + { + return $this->profiler; + } + + /** + * Register statement prototype + */ + public function registerStatementPrototype(StatementInterface&PdoDriverAwareInterface $statementPrototype) + { + $this->statementPrototype = $statementPrototype; + $this->statementPrototype->setDriver($this); + } + + /** + * Register result prototype + */ + public function registerResultPrototype(ResultInterface $resultPrototype) + { + $this->resultPrototype = $resultPrototype; + } + + /** + * Add feature + * + * todo: needs improvement + * + * @return $this Provides a fluent interface + */ + public function addFeature(string $name, AbstractFeature $feature): self + { + if ($feature instanceof AbstractFeature) { + $name = $feature->getName(); // overwrite the name, just in case + $feature->setDriver($this); + } + $this->features[$name] = $feature; + return $this; + } + + /** + * Setup the default features for Pdo + * + * @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; + // } + + /** + * Get feature + */ + public function getFeature(string $name): AbstractFeature|false + { + if (isset($this->features[$name])) { + return $this->features[$name]; + } + return false; + } + + /** + * Get database platform 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); + // } + // } + // } + + /** + * Check environment + */ + 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; + } + + public function getConnection(): ConnectionInterface + { + return $this->connection; + } + + /** + * todo: this needs improved + * @param string|PDOStatement $sqlOrResource + */ + public function createStatement($sqlOrResource = null): StatementInterface + { + /** @var Statement */ + $statement = clone $this->statementPrototype; + if ($sqlOrResource instanceof PDOStatement) { + $statement->setResource($sqlOrResource); + } else { + if (is_string($sqlOrResource)) { + $statement->setSql($sqlOrResource); + } + if (! $this->connection->isConnected()) { + $this->connection->connect(); + } + /** @var \PDO */ + $resource = $this->connection->getResource(); + $statement->initialize($resource); + } + return $statement; + } + + /** + * @param resource $resource + * @param mixed $context + * @return Result + */ + // 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); + // } + + // $result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount); + // return $result; + // } + + public function getResultPrototype(): ResultInterface|null + { + return $this->resultPrototype; + } + + public function getPrepareType(): string + { + return self::PARAMETERIZATION_NAMED; + } + + 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 + if (is_int($name) && $type === self::PARAMETERIZATION_NAMED) { + $name = (string) $name; + } + // end proposed fix + $name = ltrim($name, ':'); + // @see https://bugs.php.net/bug.php?id=43130 + 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.', + $name + )); + } + return ':' . $name; + } + + return '?'; + } + + 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 new file mode 100644 index 000000000..276269b0b --- /dev/null +++ b/src/Adapter/Driver/Pdo/AbstractPdoConnection.php @@ -0,0 +1,406 @@ +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' + ); + } + } + + public function setDriver(PdoDriverInterface $driver): PdoDriverAwareInterface + { + $this->driver = $driver; + + return $this; + } + + #[Override] + public function setConnectionParameters(array $connectionParameters): static + { + $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 + )); + } + + return $this; + } + + /** + * Get the dsn string for this connection + * + * @throws RuntimeException + */ + public function getDsn(): string + { + 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 */ + public function setResource(PDO $resource): static + { + $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(): bool + { + return $this->resource instanceof PDO; + } + + /** @inheritDoc */ + public function beginTransaction(): ConnectionInterface + { + if (! $this->isConnected()) { + $this->connect(); + } + + if (0 === $this->nestedTransactionsCount) { + $this->resource->beginTransaction(); + $this->inTransaction = true; + } + + $this->nestedTransactionsCount++; + + return $this; + } + + /** @inheritDoc */ + public function commit(): ConnectionInterface + { + 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(): ConnectionInterface + { + 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): ?ResultInterface + { + 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 a statement */ + public function prepare(?string $sql = null): StatementInterface + { + 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/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/Driver/Pdo/Pdo.php b/src/Adapter/Driver/Pdo/Pdo.php deleted file mode 100644 index 72af7561d..000000000 --- a/src/Adapter/Driver/Pdo/Pdo.php +++ /dev/null @@ -1,340 +0,0 @@ -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) - { - $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); - return $this; - } - - /** - * Register statement prototype - */ - public function registerStatementPrototype(Statement $statementPrototype) - { - $this->statementPrototype = $statementPrototype; - $this->statementPrototype->setDriver($this); - } - - /** - * Register result prototype - */ - public function registerResultPrototype(Result $resultPrototype) - { - $this->resultPrototype = $resultPrototype; - } - - /** - * Add feature - * - * @param string $name - * @param AbstractFeature $feature - * @return $this Provides a fluent interface - */ - public function addFeature($name, $feature) - { - if ($feature instanceof AbstractFeature) { - $name = $feature->getName(); // overwrite the name, just in case - $feature->setDriver($this); - } - $this->features[$name] = $feature; - return $this; - } - - /** - * Setup the default features for Pdo - * - * @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; - } - - /** - * Get feature - * - * @param string $name - * @return AbstractFeature|false - */ - public function getFeature($name) - { - if (isset($this->features[$name])) { - return $this->features[$name]; - } - return false; - } - - /** - * Get database platform 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); - } - } - } - - /** - * Check environment - */ - public function checkEnvironment() - { - if (! extension_loaded('PDO')) { - throw new Exception\RuntimeException( - 'The PDO extension is required for this adapter but the extension is not loaded' - ); - } - } - - /** - * @return Connection - */ - public function getConnection() - { - return $this->connection; - } - - /** - * @param string|PDOStatement $sqlOrResource - * @return Statement - */ - public function createStatement($sqlOrResource = null) - { - $statement = clone $this->statementPrototype; - if ($sqlOrResource instanceof PDOStatement) { - $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; - } - - /** - * @param resource $resource - * @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); - } - - // 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; - } - - /** - * @return Result - */ - public function getResultPrototype() - { - return $this->resultPrototype; - } - - /** - * @return string - */ - public function getPrepareType() - { - return self::PARAMETERIZATION_NAMED; - } - - /** - * @param string $name - * @param string|null $type - * @return string - */ - public function formatParameterName($name, $type = null) - { - if ($type === null && ! is_numeric($name) || $type === self::PARAMETERIZATION_NAMED) { - $name = ltrim($name, ':'); - // @see https://bugs.php.net/bug.php?id=43130 - 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.', - $name - )); - } - return ':' . $name; - } - - return '?'; - } - - /** - * @param string|null $name - * @return string|null|false - */ - public function getLastGeneratedValue($name = null) - { - return $this->connection->getLastGeneratedValue($name); - } -} diff --git a/src/Adapter/Driver/Pdo/Statement.php b/src/Adapter/Driver/Pdo/Statement.php index 4606de40b..ddc4f339c 100644 --- a/src/Adapter/Driver/Pdo/Statement.php +++ b/src/Adapter/Driver/Pdo/Statement.php @@ -1,11 +1,19 @@ driver = $driver; return $this; } - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler) + public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; return $this; } - /** - * @return null|Profiler\ProfilerInterface - */ - public function getProfiler() + public function getProfiler(): ?ProfilerInterface { return $this->profiler; } - /** - * Initialize - * - * @return $this Provides a fluent interface - */ - public function initialize(\PDO $connectionResource) + public function initialize(PDO $connectionResource): static { $this->pdo = $connectionResource; return $this; } - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(PDOStatement $pdoStatement) + public function setResource(PDOStatement $pdoStatement): static { $this->resource = $pdoStatement; return $this; } - /** - * Get resource - * - * @return mixed - */ - public function getResource() + public function getResource(): PDOStatement|null { return $this->resource; } - /** - * Set sql - * - * @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; } - /** - * Get sql - * - * @return string - */ - public function getSql() + public function getSql(): string|null { return $this->sql; } @@ -128,25 +90,21 @@ public function getSql() /** * @return $this Provides a fluent interface */ - public function setParameterContainer(ParameterContainer $parameterContainer) + public function setParameterContainer(ParameterContainer $parameterContainer): self { $this->parameterContainer = $parameterContainer; return $this; } - /** - * @return ParameterContainer - */ - public function getParameterContainer() + public function getParameterContainer(): ParameterContainer|null { return $this->parameterContainer; } /** - * @param string $sql * @throws Exception\RuntimeException */ - public function prepare($sql = null) + public function prepare(string|null $sql = null): static|null { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); @@ -164,22 +122,19 @@ public function prepare($sql = null) } $this->isPrepared = true; + + 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) + public function execute(ParameterContainer|array|null $parameters = null): ResultInterface|null { if (! $this->isPrepared) { $this->prepare(); @@ -204,16 +159,13 @@ public function execute($parameters = null) } /** 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)) { @@ -227,9 +179,7 @@ public function execute($parameters = null) ); } - if ($this->profiler) { - $this->profiler->profilerFinish(); - } + $this->profiler?->profilerFinish(); return $this->driver->createResult($this->resource, $this); } @@ -237,7 +187,7 @@ public function execute($parameters = null) /** * Bind parameters from container */ - protected function bindParametersFromContainer() + protected function bindParametersFromContainer(): void { if ($this->parametersBound) { return; @@ -246,22 +196,23 @@ protected function bindParametersFromContainer() $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; } } @@ -272,12 +223,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/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/PdoDriverAwareInterface.php b/src/Adapter/Driver/PdoDriverAwareInterface.php new file mode 100644 index 000000000..32eb0b55b --- /dev/null +++ b/src/Adapter/Driver/PdoDriverAwareInterface.php @@ -0,0 +1,11 @@ +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 3ccb988f6..2a84e5bd4 100644 --- a/src/Adapter/Driver/StatementInterface.php +++ b/src/Adapter/Driver/StatementInterface.php @@ -16,23 +16,16 @@ public function getResource(); /** * Prepare sql - * - * @param string $sql */ - public function prepare($sql = null); + public function prepare(string|null $sql = null): static|null; /** * Check if is prepared - * - * @return bool */ - public function isPrepared(); + public function isPrepared(): bool; /** * Execute - * - * @param null|array|ParameterContainer $parameters - * @return ResultInterface */ - public function execute($parameters = null); + 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/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/Adapter/Platform/PlatformInterface.php b/src/Adapter/Platform/PlatformInterface.php index fdc193b28..1fbbf9a83 100644 --- a/src/Adapter/Platform/PlatformInterface.php +++ b/src/Adapter/Platform/PlatformInterface.php @@ -1,55 +1,53 @@ 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 18840135f..f0b6c4485 100644 --- a/src/Adapter/StatementContainerInterface.php +++ b/src/Adapter/StatementContainerInterface.php @@ -1,35 +1,16 @@ $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/AdapterManager.php b/src/Container/AdapterManager.php new file mode 100644 index 000000000..e470e4378 --- /dev/null +++ b/src/Container/AdapterManager.php @@ -0,0 +1,55 @@ + 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 new file mode 100644 index 000000000..6a43ac0a2 --- /dev/null +++ b/src/Container/AdapterManagerFactory.php @@ -0,0 +1,30 @@ +get('config'); + $dbConfig = $config['db'] ?? []; + + return new AdapterManager( + $container, + [ + 'aliases' => [ + 'db' => ConfigInterface::class, + ], + 'services' => [ + ConfigInterface::class => $dbConfig, + ], + ] + ); + } +} diff --git a/src/Container/ConfigProvider.php b/src/Container/ConfigProvider.php new file mode 100644 index 000000000..32e000e27 --- /dev/null +++ b/src/Container/ConfigProvider.php @@ -0,0 +1,27 @@ + $this->getDependencies(), + ]; + } + + public function getDependencies(): array + { + return [ + 'factories' => [ + Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, + AdapterManager::class => AdapterManagerFactory::class, + ], + ]; + } +} diff --git a/src/Container/MetadataFactory.php b/src/Container/MetadataFactory.php new file mode 100644 index 000000000..0fc2860d1 --- /dev/null +++ b/src/Container/MetadataFactory.php @@ -0,0 +1,30 @@ +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/AbstractSource.php b/src/Metadata/Source/AbstractSource.php index 13de76eb1..6cb058669 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; @@ -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(Adapter $adapter) - { - $this->adapter = $adapter; + public function __construct( + protected AdapterInterface $adapter + ) { $this->defaultSchema = $adapter->getCurrentSchema() ?: self::DEFAULT_SCHEMA; } diff --git a/src/Metadata/Source/Factory.php b/src/Metadata/Source/Factory.php index fd2ef863b..b90a723cd 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; @@ -14,10 +14,12 @@ class Factory /** * Create source from adapter * + * @deprecated to be removed in 3.0.0 + * * @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 deleted file mode 100644 index ff2687897..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, Adapter::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, Adapter::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, Adapter::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, Adapter::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, Adapter::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, Adapter::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, Adapter::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, Adapter::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/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); } 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 f7612ebc2..fd761cc8e 100644 --- a/src/Sql/Insert.php +++ b/src/Sql/Insert.php @@ -2,8 +2,7 @@ namespace Laminas\Db\Sql; -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; @@ -34,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); } @@ -63,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; @@ -77,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; @@ -86,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) { @@ -112,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' ); } @@ -135,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); } @@ -152,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, @@ -168,8 +160,8 @@ public function getRawState($key = null) protected function processInsert( PlatformInterface $platform, - ?DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if ($this->select) { return; @@ -187,7 +179,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,8 +203,8 @@ protected function processInsert( protected function processSelect( PlatformInterface $platform, - ?DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if (! $this->select) { return; @@ -235,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; @@ -250,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( @@ -269,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); } @@ -283,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/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 @@ 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 95% rename from src/Sql/Platform/Mysql/Mysql.php rename to src/Sql/Platform/_Mysql/Mysql.php index dbba270d9..e4a7afa2e 100644 --- a/src/Sql/Platform/Mysql/Mysql.php +++ b/src/Sql/Platform/_Mysql/Mysql.php @@ -1,5 +1,7 @@ '%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/Sql.php b/src/Sql/Sql.php index 96b2cf693..7bcaba8d8 100644 --- a/src/Sql/Sql.php +++ b/src/Sql/Sql.php @@ -1,5 +1,7 @@ |array */ - protected $specifications = [ + protected array $specifications = [ self::SPECIFICATION_UPDATE => 'UPDATE %1$s', self::SPECIFICATION_JOIN => [ '%1$s' => [ @@ -47,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); @@ -81,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; @@ -98,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(); @@ -116,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; @@ -134,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); @@ -148,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, @@ -163,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, - ?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, - ?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) { @@ -199,7 +176,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,8 +199,8 @@ protected function processSet( protected function processWhere( PlatformInterface $platform, - ?DriverInterface $driver = null, - ?ParameterContainer $parameterContainer = null + Driver\DriverInterface|null $driver = null, + ParameterContainer|null $parameterContainer = null ) { if ($this->where->count() === 0) { return; @@ -237,9 +214,9 @@ protected function processWhere( /** @return null|string[] */ protected function processJoins( PlatformInterface $platform, - ?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); } @@ -248,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; @@ -259,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 0b3afe713..92dd41c95 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,29 +14,16 @@ class MetadataFeature extends AbstractFeature { - /** @var MetadataInterface */ - protected $metadata; - - /** - * Constructor - */ - public function __construct(?MetadataInterface $metadata = null) + public function __construct(protected MetadataInterface $metadata) { - if ($metadata) { - $this->metadata = $metadata; - } $this->sharedData['metadata'] = [ 'primaryKey' => null, 'columns' => [], ]; } - public function postInitialize() + public function postInitialize(): void { - 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..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\Adapter; use Laminas\Db\Adapter\AdapterAbstractServiceFactory; +use Laminas\Db\Adapter\AdapterInterface; use Laminas\ServiceManager\Config; use Laminas\ServiceManager\Exception\ServiceNotFoundException; use Laminas\ServiceManager\ServiceManager; @@ -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); } /** 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;