From b681b17182b51a525bb2cf9191d17995c9a25322 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 16 Dec 2025 02:08:15 -0600 Subject: [PATCH 1/2] Reorganizes the files in a more logical way. Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 6 +- composer.lock | 179 +++++++++--------- .../Postgresql.php => AdapterPlatform.php} | 7 +- src/ConfigProvider.php | 9 +- src/{Driver/Pgsql => }/Connection.php | 72 ++++--- src/Container/AdapterInterfaceFactory.php | 80 ++++++-- src/DatabasePlatformNameTrait.php | 33 ++++ src/{Driver/Pgsql/Pgsql.php => Driver.php} | 18 +- src/Driver/DatabasePlatformNameTrait.php | 20 -- src/Driver/Pgsql/PgsqlConfig.php | 69 ------- src/Driver/Pgsql/Result.php | 174 ----------------- .../PostgresqlMetadata.php => Source.php} | 4 +- src/{Driver => }/Pdo/Connection.php | 0 src/{Driver/Pdo/Pdo.php => Pdo/Driver.php} | 2 +- src/Result.php | 116 ++++++++++++ src/{Driver/Pgsql => }/Statement.php | 136 +++++-------- .../Driver/Pdo/Postgresql/AdapterTest.php | 14 -- .../Driver/Pdo/Postgresql/AdapterTrait.php | 38 ---- .../Driver/Pdo/AbstractAdapterTestCase.php | 84 ++++++++ test/integration/Driver/Pdo/AdapterTest.php | 10 + test/integration/Driver/Pdo/SetupTrait.php | 66 +++++++ .../Pdo}/TableGatewayTest.php | 8 +- .../IntegrationTestStartedListener.php | 44 +++++ .../IntegrationTestStoppedListener.php | 33 ++++ .../Extension/ListenerExtension.php | 24 +++ .../FixtureLoader/PgsqlFixtureLoader.php | 16 +- .../{Adapter => }/Platform/PostgresqlTest.php | 0 test/unit/Adapter/AdapterTest.php | 2 +- 28 files changed, 692 insertions(+), 572 deletions(-) rename src/{Platform/Postgresql.php => AdapterPlatform.php} (93%) rename src/{Driver/Pgsql => }/Connection.php (77%) create mode 100644 src/DatabasePlatformNameTrait.php rename src/{Driver/Pgsql/Pgsql.php => Driver.php} (89%) delete mode 100644 src/Driver/DatabasePlatformNameTrait.php delete mode 100644 src/Driver/Pgsql/PgsqlConfig.php delete mode 100644 src/Driver/Pgsql/Result.php rename src/Metadata/{Source/PostgresqlMetadata.php => Source.php} (99%) rename src/{Driver => }/Pdo/Connection.php (100%) rename src/{Driver/Pdo/Pdo.php => Pdo/Driver.php} (95%) create mode 100644 src/Result.php rename src/{Driver/Pgsql => }/Statement.php (54%) delete mode 100644 test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTest.php delete mode 100644 test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php create mode 100644 test/integration/Driver/Pdo/AbstractAdapterTestCase.php create mode 100644 test/integration/Driver/Pdo/AdapterTest.php create mode 100644 test/integration/Driver/Pdo/SetupTrait.php rename test/integration/{Adapter/Driver/Pdo/Postgresql => Driver/Pdo}/TableGatewayTest.php (81%) create mode 100644 test/integration/Extension/IntegrationTestStartedListener.php create mode 100644 test/integration/Extension/IntegrationTestStoppedListener.php create mode 100644 test/integration/Extension/ListenerExtension.php rename test/integration/{Adapter => }/Platform/PostgresqlTest.php (100%) diff --git a/composer.json b/composer.json index e5f63c3..d53621e 100644 --- a/composer.json +++ b/composer.json @@ -30,14 +30,14 @@ } }, "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "php-db/phpdb": "^0.2.1" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "php-db/phpdb": "^0.4.0" }, "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", "phpstan/phpstan": "^2.1", "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^11.5.15" + "phpunit/phpunit": "^11.5.42" }, "suggest": { "ext-pdo": "*", diff --git a/composer.lock b/composer.lock index 0413512..136a4da 100644 --- a/composer.lock +++ b/composer.lock @@ -4,30 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "93b90a40dd4fe8c39502da74c4585c56", + "content-hash": "a3f0f794e48b895f9ed9031ee29dcf78", "packages": [ { "name": "brick/varexporter", - "version": "0.5.0", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/brick/varexporter.git", - "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b" + "reference": "af98bfc2b702a312abbcaff37656dbe419cec5bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/varexporter/zipball/84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", - "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", + "url": "https://api.github.com/repos/brick/varexporter/zipball/af98bfc2b702a312abbcaff37656dbe419cec5bc", + "reference": "af98bfc2b702a312abbcaff37656dbe419cec5bc", "shasum": "" }, "require": { "nikic/php-parser": "^5.0", - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.3", - "psalm/phar": "5.21.1" + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "6.8.4" }, "type": "library", "autoload": { @@ -45,7 +45,7 @@ ], "support": { "issues": "https://github.com/brick/varexporter/issues", - "source": "https://github.com/brick/varexporter/tree/0.5.0" + "source": "https://github.com/brick/varexporter/tree/0.6.0" }, "funding": [ { @@ -53,26 +53,26 @@ "type": "github" } ], - "time": "2024-05-10T17:15:19+00:00" + "time": "2025-02-20T17:42:39+00:00" }, { "name": "laminas/laminas-servicemanager", - "version": "4.4.0", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "74da44d07e493b834347123242d0047976fb9932" + "reference": "a6996829c8ce55025cca1b57b1e8a8b165e3926c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/74da44d07e493b834347123242d0047976fb9932", - "reference": "74da44d07e493b834347123242d0047976fb9932", + "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/a6996829c8ce55025cca1b57b1e8a8b165e3926c", + "reference": "a6996829c8ce55025cca1b57b1e8a8b165e3926c", "shasum": "" }, "require": { - "brick/varexporter": "^0.3.8 || ^0.4.0 || ^0.5.0", + "brick/varexporter": "^0.3.8 || ^0.4.0 || ^0.5.0 || ^0.6.0", "laminas/laminas-stdlib": "^3.19", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "psr/container": "^1.1 || ^2.0" }, "conflict": { @@ -86,14 +86,14 @@ "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", + "laminas/laminas-coding-standard": "~3.1.0", + "laminas/laminas-container-config-test": "^1.1", "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" + "phpbench/phpbench": "^1.4.1", + "phpunit/phpunit": "^10.5.58", + "psalm/plugin-phpunit": "^0.19.5", + "symfony/console": "^6.4.17 || ^7.3.4", + "vimeo/psalm": "^6.13.1" }, "suggest": { "friendsofphp/proxy-manager-lts": "To handle lazy initialization of services", @@ -130,7 +130,7 @@ "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" + "source": "https://github.com/laminas/laminas-servicemanager/tree/4.5.0" }, "funding": [ { @@ -138,34 +138,34 @@ "type": "community_bridge" } ], - "time": "2025-02-04T06:13:50+00:00" + "time": "2025-10-14T09:41:04+00:00" }, { "name": "laminas/laminas-stdlib", - "version": "3.20.0", + "version": "3.21.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4" + "reference": "b1c81514cfe158aadf724c42b34d3d0a8164c096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/8974a1213be42c3e2f70b2c27b17f910291ab2f4", - "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/b1c81514cfe158aadf724c42b34d3d0a8164c096", + "reference": "b1c81514cfe158aadf724c42b34d3d0a8164c096", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "conflict": { "zendframework/zend-stdlib": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "^3.0", - "phpbench/phpbench": "^1.3.1", - "phpunit/phpunit": "^10.5.38", - "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.26.1" + "laminas/laminas-coding-standard": "^3.1.0", + "phpbench/phpbench": "^1.4.1", + "phpunit/phpunit": "^11.5.42", + "psalm/plugin-phpunit": "^0.19.5", + "vimeo/psalm": "^6.13.1" }, "type": "library", "autoload": { @@ -197,20 +197,20 @@ "type": "community_bridge" } ], - "time": "2024-10-29T13:46:07+00:00" + "time": "2025-10-11T18:13:12+00:00" }, { "name": "nikic/php-parser", - "version": "v5.6.1", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { @@ -253,28 +253,28 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2025-08-13T20:13:15+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "php-db/phpdb", - "version": "0.2.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/php-db/phpdb.git", - "reference": "d221b024cb3aea77992f41a962913918301dc92e" + "reference": "3cb7531b36bf37c42843bbe9dd05583d8d8f130e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-db/phpdb/zipball/d221b024cb3aea77992f41a962913918301dc92e", - "reference": "d221b024cb3aea77992f41a962913918301dc92e", + "url": "https://api.github.com/repos/php-db/phpdb/zipball/3cb7531b36bf37c42843bbe9dd05583d8d8f130e", + "reference": "3cb7531b36bf37c42843bbe9dd05583d8d8f130e", "shasum": "" }, "require": { - "laminas/laminas-servicemanager": "^4.0.0", + "laminas/laminas-servicemanager": "^3.0.0 || ^4.0.0", "laminas/laminas-stdlib": "^3.20.0", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "conflict": { "laminas/laminas-db": "*", @@ -283,6 +283,8 @@ "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", "laminas/laminas-eventmanager": "^3.14.0", + "laminas/laminas-hydrator": "^4.6.0", + "phpbench/phpbench": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^11.5.15", @@ -321,7 +323,7 @@ "issues": "https://github.com/php-db/phpdb/issues", "source": "https://github.com/php-db/phpdb" }, - "time": "2025-10-07T08:36:48+00:00" + "time": "2025-12-05T01:52:04+00:00" }, { "name": "psr/container", @@ -380,29 +382,29 @@ "packages-dev": [ { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.1.2", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" + "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", - "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1", + "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1", "shasum": "" }, "require": { "composer-plugin-api": "^2.2", "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + "squizlabs/php_codesniffer": "^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "^2.2", "ext-json": "*", "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/php-compatibility": "^9.0 || ^10.0.0@dev", "yoast/phpunit-polyfills": "^1.0" }, "type": "composer-plugin", @@ -472,7 +474,7 @@ "type": "thanks_dev" } ], - "time": "2025-07-17T20:45:56+00:00" + "time": "2025-11-11T04:32:07+00:00" }, { "name": "laminas/laminas-coding-standard", @@ -754,11 +756,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.30", + "version": "2.1.33", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a4a7f159927983dd4f7c8020ed227d80b7f39d7d", - "reference": "a4a7f159927983dd4f7c8020ed227d80b7f39d7d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f", + "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f", "shasum": "" }, "require": { @@ -803,25 +805,25 @@ "type": "github" } ], - "time": "2025-10-02T16:07:52+00:00" + "time": "2025-12-05T10:24:31+00:00" }, { "name": "phpstan/phpstan-phpunit", - "version": "2.0.7", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc" + "reference": "8d61a5854e7497d95bc85188e13537e99bd7aae7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9a9b161baee88a5f5c58d816943cff354ff233dc", - "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/8d61a5854e7497d95bc85188e13537e99bd7aae7", + "reference": "8d61a5854e7497d95bc85188e13537e99bd7aae7", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.18" + "phpstan/phpstan": "^2.1.32" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -854,9 +856,9 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.7" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.10" }, - "time": "2025-07-13T11:31:46+00:00" + "time": "2025-12-06T11:15:39+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1195,16 +1197,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.42", + "version": "11.5.46", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c" + "reference": "75dfe79a2aa30085b7132bb84377c24062193f33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", - "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/75dfe79a2aa30085b7132bb84377c24062193f33", + "reference": "75dfe79a2aa30085b7132bb84377c24062193f33", "shasum": "" }, "require": { @@ -1276,7 +1278,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.42" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.46" }, "funding": [ { @@ -1300,7 +1302,7 @@ "type": "tidelift" } ], - "time": "2025-09-28T12:09:13+00:00" + "time": "2025-12-06T08:01:15+00:00" }, { "name": "sebastian/cli-parser", @@ -2355,16 +2357,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.13.4", + "version": "3.13.5", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119" + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ad545ea9c1b7d270ce0fc9cbfb884161cd706119", - "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4", + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4", "shasum": "" }, "require": { @@ -2381,11 +2383,6 @@ "bin/phpcs" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -2435,7 +2432,7 @@ "type": "thanks_dev" } ], - "time": "2025-09-05T05:47:09+00:00" + "time": "2025-11-04T16:30:35+00:00" }, { "name": "staabm/side-effects-detector", @@ -2491,16 +2488,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.3", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { @@ -2529,7 +2526,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, "funding": [ { @@ -2537,7 +2534,7 @@ "type": "github" } ], - "time": "2024-03-03T12:36:25+00:00" + "time": "2025-11-17T20:03:58+00:00" }, { "name": "webimpress/coding-standard", @@ -2601,11 +2598,11 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "platform-dev": {}, "platform-overrides": { "php": "8.2.99" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/src/Platform/Postgresql.php b/src/AdapterPlatform.php similarity index 93% rename from src/Platform/Postgresql.php rename to src/AdapterPlatform.php index 55fac46..79c5a2d 100644 --- a/src/Platform/Postgresql.php +++ b/src/AdapterPlatform.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Platform; +namespace PhpDb\Adapter\Pgsql; use Override; use PDO; @@ -12,7 +12,7 @@ use PhpDb\Adapter\Driver\PdoDriverInterface; use PhpDb\Adapter\Driver\Pgsql\Pgsql; use PhpDb\Adapter\Exception; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Pdo as PdoDriver; +use PhpDb\Adapter\Pgsql\Driver\Pdo\Driver as PdoDriver; use PhpDb\Adapter\Platform\AbstractPlatform; use PhpDb\Sql\Platform\Platform as SqlPlatformDecorator; use PhpDb\Sql\Platform\PlatformDecoratorInterface; @@ -24,7 +24,7 @@ use function pg_escape_string; use function str_replace; -class Postgresql extends AbstractPlatform +class AdapterPlatform extends AbstractPlatform { public final const PLATFORM_NAME = 'PostgreSQL'; /** @@ -41,7 +41,6 @@ class Postgresql extends AbstractPlatform ]; public function __construct( - //private readonly PDO|Pgsql|PdoDriver $driver private readonly DriverInterface|PdoDriverInterface|PDO $driver, ) { } diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 19aa7af..819b840 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -4,7 +4,6 @@ namespace PhpDb\Adapter\Pgsql; -use Laminas\ServiceManager\Factory\InvokableFactory; use PhpDb\Adapter\AdapterInterface; use PhpDb\Adapter\Driver\DriverInterface; use PhpDb\Adapter\Platform\PlatformInterface; @@ -22,12 +21,12 @@ public function getDependencies(): array { return [ 'aliases' => [ - PlatformInterface::class => Platform\Postgresql::class, + PlatformInterface::class => AdapterPlatform::class, ], 'factories' => [ - AdapterInterface::class => Container\AdapterServiceFactory::class, - DriverInterface::class => Container\PdoDriverInterfaceFactory::class, - Platform\Postgresql::class => InvokableFactory::class, + AdapterInterface::class => Container\AdapterInterfaceFactory::class, + DriverInterface::class => Container\PdoDriverInterfaceFactory::class, + AdapterPlatform::class => Container\PlatformInterfaceFactory::class, ], ]; } diff --git a/src/Driver/Pgsql/Connection.php b/src/Connection.php similarity index 77% rename from src/Driver/Pgsql/Connection.php rename to src/Connection.php index 03aba23..c482e98 100644 --- a/src/Driver/Pgsql/Connection.php +++ b/src/Connection.php @@ -2,8 +2,9 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Driver\Pgsql; +namespace PhpDb\Adapter\Pgsql; +use Override; use PgSql\Connection as PgSqlConnection; use PhpDb\Adapter\Driver\AbstractConnection; use PhpDb\Adapter\Driver\ConnectionInterface; @@ -16,7 +17,7 @@ use function array_filter; use function http_build_query; use function is_array; -use function is_resource; +use function pg_close; use function pg_connect; use function pg_fetch_result; use function pg_last_error; @@ -32,42 +33,45 @@ class Connection extends AbstractConnection implements DriverAwareInterface { - /** @var Pgsql */ - protected $driver; + protected Driver $driver; + + protected PgSqlConnection $resource; /** @var null|int PostgreSQL connection type */ protected ?int $type = null; - public function __construct(PgSqlConnection|array|null $connectionInfo = null) + public function __construct(PgSqlConnection|array $connectionInfo) { if (is_array($connectionInfo)) { $this->setConnectionParameters($connectionInfo); - } elseif ($connectionInfo instanceof PgSqlConnection || is_resource($connectionInfo)) { + } else { $this->setResource($connectionInfo); } } - public function setResource(PgSqlConnection $resource): ConnectionInterface - { + public function setResource( + PgSqlConnection $resource + ): ConnectionInterface&DriverAwareInterface { $this->resource = $resource; return $this; } - /** - * old param type hint Pgsql $driver - */ - public function setDriver(DriverInterface $driver): DriverAwareInterface + #[Override] + public function getResource(): ?PgSqlConnection { + return $this->resource; + } + + public function setDriver( + DriverInterface $driver + ): ConnectionInterface&DriverAwareInterface { $this->driver = $driver; return $this; } - /** - * @return $this Provides a fluent interface - */ - public function setType(?int $type): static + public function setType(?int $type): ConnectionInterface&DriverAwareInterface { $invalidConectionType = $type !== PGSQL_CONNECT_FORCE_NEW; if ($invalidConectionType) { @@ -80,12 +84,7 @@ public function setType(?int $type): static return $this; } - /** - * {@inheritDoc} - * - * @return null|string - */ - public function getCurrentSchema(): bool|string + public function getCurrentSchema(): string|false { if (! $this->isConnected()) { $this->connect(); @@ -157,7 +156,6 @@ public function isConnected(): bool */ public function disconnect(): static { - // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFallbackGlobalName pg_close($this->resource); return $this; @@ -269,8 +267,32 @@ public function getLastGeneratedValue($name = null): bool|int|string|null */ private function getConnectionString(): string { - $connectionParameters = array_filter((new PgsqlConfig())($this->connectionParameters)); + $parameters = $this->connectionParameters; + $conn = []; + foreach ($parameters as $name => $value) { + $name = match (strtolower($name)) { + 'host', 'hostname' => 'host', + 'user', 'username' => 'user', + 'password', 'passwd', 'pw' => 'password', + 'database', 'dbname', 'db', 'schema' => 'dbname', + 'port' => 'port', + 'socket' => 'socket', + default => throw new Exception\InvalidArgumentException( + 'Connection parameter "' . $name . '"' . ' is not valid for Pgsql adapter' + ), + }; + if ($name === 'port' && $value !== null) { + $value = (int) $value; + } + $conn[$name] = $value; + } - return urldecode(http_build_query($connectionParameters, '', ' ')); + return urldecode( + http_build_query( + array_filter($conn), + '', + ' ' + ) + ); } } diff --git a/src/Container/AdapterInterfaceFactory.php b/src/Container/AdapterInterfaceFactory.php index 602df73..47cd3c0 100644 --- a/src/Container/AdapterInterfaceFactory.php +++ b/src/Container/AdapterInterfaceFactory.php @@ -12,7 +12,6 @@ use PhpDb\Adapter\Exception\RuntimeException; use PhpDb\Adapter\Platform\PlatformInterface; use PhpDb\Adapter\Profiler\ProfilerInterface; -use PhpDb\Container\AdapterManager; use PhpDb\ResultSet\ResultSetInterface; use Psr\Container\ContainerInterface; @@ -20,25 +19,74 @@ class AdapterInterfaceFactory { - /** - * Create db adapter service - * - * @param array|null $options - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function __invoke(ContainerInterface $container): AdapterInterface { - $resultSetPrototype = $container->has(ResultSetInterface::class) - ? $container->get(ResultSetInterface::class) + public function __invoke(ContainerInterface $container): AdapterInterface + { + if (! $container->has('config')) { + throw new ServiceNotFoundException( + sprintf( + 'Could not find service "config" in container %s', + $container::class + ) + ); + } + + /** @var array $config */ + $config = $container->get('config'); + + /** @var array $dbConfig */ + $dbConfig = $config['db'] ?? []; + + if (! isset($dbConfig['driver'])) { + throw new RuntimeException( + 'Database configuration must contain a "driver" key' + ); + } + + /** @var string $driver */ + $driver = $dbConfig['driver']; + if (! $container->has($driver)) { + throw new ServiceNotFoundException( + sprintf( + 'Could not find database driver service "%s" in container %s', + $driver, + $container::class + ) + ); + } + /** @var DriverInterface|PdoDriverInterface $driverInstance */ + $driverInstance = $container->get($driver); + + if (! $container->has(PlatformInterface::class)) { + throw new ServiceNotFoundException( + sprintf( + 'Could not find service "%s" in container %s', + PlatformInterface::class, + $container::class + ) + ); + } + + /** @var PlatformInterface $adapterPlatform */ + $adapterPlatform = $container->get(PlatformInterface::class); + + /** @var ProfilerInterface|null $profilerInstanceOrNull */ + $profilerInstanceOrNull = $container->has(ProfilerInterface::class) + ? $container->get(ProfilerInterface::class) : null; - $profiler = $container->get(ProfilerInterface::class); + if (! $container->has(ResultSetInterface::class)) { + return new Adapter( + driver: $driverInstance, + platform: $adapterPlatform, + profiler: $profilerInstanceOrNull + ); + } return new Adapter( - $container->get(DriverInterface::class), - $container->get(Platform\Postgresql::class), - $resultSetPrototype, - $profiler + driver: $driverInstance, + platform: $adapterPlatform, + queryResultSetPrototype: $container->get(ResultSetInterface::class), + profiler: $profilerInstanceOrNull ); } } diff --git a/src/DatabasePlatformNameTrait.php b/src/DatabasePlatformNameTrait.php new file mode 100644 index 0000000..519ade3 --- /dev/null +++ b/src/DatabasePlatformNameTrait.php @@ -0,0 +1,33 @@ +profiler = $profiler; if ($this->connection instanceof ProfilerAwareInterface) { $this->connection->setProfiler($profiler); @@ -77,7 +77,7 @@ 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' + 'The PostgreSQL (pgsql) extension is required for this Driver but the extension is not loaded' ); } return true; @@ -115,7 +115,7 @@ public function createStatement($sqlOrResource = null): StatementInterface&State /** * Create result * - * @param resource|PgSqlResult|PgSqlConnection $resource + * @param PgSqlResult $resource */ #[Override] public function createResult($resource): ResultInterface&Result diff --git a/src/Driver/DatabasePlatformNameTrait.php b/src/Driver/DatabasePlatformNameTrait.php deleted file mode 100644 index a940404..0000000 --- a/src/Driver/DatabasePlatformNameTrait.php +++ /dev/null @@ -1,20 +0,0 @@ - $value) { - $name = match (strtolower($name)) { - 'host', 'hostname' => 'host', - 'user', 'username' => 'user', - 'password', 'passwd', 'pw' => 'password', - 'database', 'dbname', 'db', 'schema' => 'dbname', - 'port' => 'port', - 'socket' => 'socket', - default => throw new InvalidArgumentException( - 'Unknown connection parameter "' . $name . '"' - ), - }; - $connectionParameters[$name] = $value; - } - - $connectionFilters = [ - 'host' => [ - 'filter' => FILTER_SANITIZE_URL, - 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, - ], - 'user' => [ - 'filter' => FILTER_SANITIZE_ENCODED, - 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, - ], - 'password' => [ - 'filter' => FILTER_SANITIZE_ENCODED, - 'flags' => FILTER_FLAG_EMPTY_STRING_NULL, - ], - 'database' => [ - 'filter' => FILTER_SANITIZE_ENCODED, - 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, - ], - 'socket' => [ - 'filter' => FILTER_SANITIZE_ENCODED, - 'flags' => FILTER_FLAG_EMPTY_STRING_NULL, - ], - 'port' => [ - 'filter' => FILTER_VALIDATE_INT, - 'flags' => FILTER_NULL_ON_FAILURE, - ], - ]; - - return filter_var_array($connectionParameters, $connectionFilters); - } -} diff --git a/src/Driver/Pgsql/Result.php b/src/Driver/Pgsql/Result.php deleted file mode 100644 index 92831c6..0000000 --- a/src/Driver/Pgsql/Result.php +++ /dev/null @@ -1,174 +0,0 @@ -resource = $resource; - $this->count = pg_num_rows($this->resource); - $this->generatedValue = $generatedValue; - } - - /** - * Current - * - * @return array|bool|mixed - */ - #[ReturnTypeWillChange] - public function current() - { - if ($this->count === 0) { - return false; - } - return pg_fetch_assoc($this->resource, $this->position); - } - - /** - * Next - * - * @return void - */ - #[ReturnTypeWillChange] - public function next() - { - $this->position++; - } - - /** - * Key - * - * @return int|mixed - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->position; - } - - /** - * Valid - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - return $this->position < $this->count; - } - - /** - * Rewind - * - * @return void - */ - #[ReturnTypeWillChange] - public function rewind() - { - $this->position = 0; - } - - /** todo: track this */ - public function buffer(): void - { - } - - /** - * Is buffered - */ - public function isBuffered(): ?bool - { - return false; - } - - public function isQueryResult(): bool - { - return pg_num_fields($this->resource) > 0; - } - - /** - * Get affected rows - */ - public function getAffectedRows(): int - { - return pg_affected_rows($this->resource); - } - - /** - * Get generated value - * - * @return mixed|null - */ - public function getGeneratedValue() - { - return $this->generatedValue; - } - - /** - * Get resource - */ - public function getResource() - { - // TODO: Implement getResource() method. - } - - /** - * Count - * - * @return int The custom count as an integer. - */ - #[ReturnTypeWillChange] - public function count() - { - return $this->count; - } - - /** - * Get field count - */ - public function getFieldCount(): int - { - return pg_num_fields($this->resource); - } -} diff --git a/src/Metadata/Source/PostgresqlMetadata.php b/src/Metadata/Source.php similarity index 99% rename from src/Metadata/Source/PostgresqlMetadata.php rename to src/Metadata/Source.php index 45c4e3d..0843b61 100644 --- a/src/Metadata/Source/PostgresqlMetadata.php +++ b/src/Metadata/Source.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Metadata\Source; +namespace PhpDb\Adapter\Pgsql\Metadata; use DateTime; use Override; @@ -18,7 +18,7 @@ use const CASE_LOWER; -class PostgresqlMetadata extends AbstractSource +class Source extends AbstractSource { #[Override] protected function loadSchemaData() diff --git a/src/Driver/Pdo/Connection.php b/src/Pdo/Connection.php similarity index 100% rename from src/Driver/Pdo/Connection.php rename to src/Pdo/Connection.php diff --git a/src/Driver/Pdo/Pdo.php b/src/Pdo/Driver.php similarity index 95% rename from src/Driver/Pdo/Pdo.php rename to src/Pdo/Driver.php index 1aee71d..a235b30 100644 --- a/src/Driver/Pdo/Pdo.php +++ b/src/Pdo/Driver.php @@ -11,7 +11,7 @@ use PhpDb\Adapter\Driver\ResultInterface; use PhpDb\Adapter\Pgsql\Driver\DatabasePlatformNameTrait; -class Pdo extends AbstractPdo +class Driver extends AbstractPdo { use DatabasePlatformNameTrait; diff --git a/src/Result.php b/src/Result.php new file mode 100644 index 0000000..81a6f93 --- /dev/null +++ b/src/Result.php @@ -0,0 +1,116 @@ +resource = $resource; + $this->count = pg_num_rows($this->resource); + $this->generatedValue = $generatedValue; + } + + #[Override] + public function current(): array|false + { + if ($this->count === 0) { + return false; + } + return pg_fetch_assoc($this->resource, $this->position); + } + + #[Override] + public function next(): void + { + $this->position++; + } + + #[Override] + public function key(): int + { + return $this->position; + } + + #[Override] + public function valid(): bool + { + return $this->position < $this->count; + } + + #[Override] + public function rewind(): void + { + $this->position = 0; + } + + #[Override] + public function buffer(): void + { + } + + #[Override] + public function isBuffered(): ?bool + { + return false; + } + + #[Override] + public function isQueryResult(): bool + { + return pg_num_fields($this->resource) > 0; + } + + #[Override] + public function getAffectedRows(): int + { + return pg_affected_rows($this->resource); + } + + #[Override] + public function getGeneratedValue(): mixed + { + return $this->generatedValue; + } + + /** + * Get resource + */ + public function getResource(): PgSqlResult + { + return $this->resource; + } + + #[Override] + public function count(): int + { + return $this->count; + } + + #[Override] + public function getFieldCount(): int + { + return pg_num_fields($this->resource); + } +} diff --git a/src/Driver/Pgsql/Statement.php b/src/Statement.php similarity index 54% rename from src/Driver/Pgsql/Statement.php rename to src/Statement.php index fcb26f1..e4c97de 100644 --- a/src/Driver/Pgsql/Statement.php +++ b/src/Statement.php @@ -2,151 +2,112 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Driver\Pgsql; +namespace PhpDb\Adapter\Pgsql; +use Override; +use PgSql\Connection as PgSqlConnection; +use PgSql\Result as PgSqlResult; +use PhpDb\Adapter\Driver\DriverAwareInterface; +use PhpDb\Adapter\Driver\DriverInterface; use PhpDb\Adapter\Driver\ResultInterface; use PhpDb\Adapter\Driver\StatementInterface; use PhpDb\Adapter\Exception; use PhpDb\Adapter\ParameterContainer; -use PhpDb\Adapter\Pgsql\Connection as PgSqlConnection; -use PhpDb\Adapter\Profiler; +use PhpDb\Adapter\Profiler\ProfilerAwareInterface; +use PhpDb\Adapter\Profiler\ProfilerInterface; -use function get_resource_type; use function is_array; -use function is_resource; use function pg_execute; use function pg_last_error; use function pg_prepare; use function preg_replace_callback; -use function sprintf; -class Statement implements StatementInterface, Profiler\ProfilerAwareInterface +class Statement implements + StatementInterface, + DriverAwareInterface, + ProfilerAwareInterface { protected static int $statementIndex = 0; - protected string $statementName = ''; + protected string $statementName = 'statement'; - protected Pgsql $driver; + protected Driver $driver; - protected Profiler\ProfilerInterface $profiler; + protected ProfilerInterface $profiler; - /** @var resource */ - protected $pgsql; + protected PgSqlConnection $pgsql; - /** @var resource */ - protected $resource; + protected PgSqlResult|false $resource; protected string $sql; protected ParameterContainer $parameterContainer; - /** - * @return $this Provides a fluent interface - */ - public function setDriver(Pgsql $driver): static - { + #[Override] + public function setDriver( + DriverInterface $driver + ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { $this->driver = $driver; return $this; } - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler): static - { + #[Override] + public function setProfiler( + ProfilerInterface $profiler + ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { $this->profiler = $profiler; return $this; } - public function getProfiler(): ?Profiler\ProfilerInterface + public function getProfiler(): (StatementInterface&ProfilerInterface)|null { return $this->profiler; } - /** - * Initialize - * - * @param resource $pgsql - * @throws Exception\RuntimeException For invalid or missing postgresql connection. - */ - public function initialize($pgsql): void + public function initialize(PgSqlConnection $pgsql): void { - if ( - ! $pgsql instanceof PgSqlConnection - && ( - ! is_resource($pgsql) - || 'pgsql link' !== get_resource_type($pgsql) - ) - ) { - throw new Exception\RuntimeException(sprintf( - '%s: Invalid or missing postgresql connection; received "%s"', - __METHOD__, - get_resource_type($pgsql) - )); - } - $this->pgsql = $pgsql; } - /** - * Get resource - * - * @todo Implement this method - * phpcs:ignore Squiz.Commenting.FunctionComment.InvalidNoReturn - * @return resource - */ - public function getResource() + #[Override] + public function getResource(): PgSqlResult|false { return $this->resource; } - /** - * Set sql - * - * @param string $sql - * @return $this Provides a fluent interface - */ - public function setSql($sql): static - { + #[Override] + public function setSql( + $sql + ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { $this->sql = $sql; return $this; } - /** - * Get sql - */ + #[Override] public function getSql(): ?string { return $this->sql; } - /** - * Set parameter container - * - * @return $this Provides a fluent interface - */ - public function setParameterContainer(ParameterContainer $parameterContainer): static - { + #[Override] + public function setParameterContainer( + ParameterContainer $parameterContainer + ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { $this->parameterContainer = $parameterContainer; return $this; } - /** - * Get parameter container - */ + #[Override] public function getParameterContainer(): ParameterContainer { return $this->parameterContainer; } - /** - * Prepare - * - * @param string $sql - */ - public function prepare($sql = null): StatementInterface - { - $sql = $sql ?: $this->sql; + #[Override] + public function prepare( + ?string $sql = null + ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { + $sql = $sql ?? $this->sql; $pCount = 1; $sql = preg_replace_callback( @@ -158,13 +119,12 @@ function () use (&$pCount) { ); $this->sql = $sql; - $this->statementName = 'statement' . ++static::$statementIndex; + $this->statementName .= ++static::$statementIndex; $this->resource = pg_prepare($this->pgsql, $this->statementName, $sql); + return $this; } - /** - * Is prepared - */ + #[Override] public function isPrepared(): bool { return isset($this->resource); @@ -174,8 +134,8 @@ public function isPrepared(): bool * Execute * * @throws Exception\InvalidQueryException - * @return Result */ + #[Override] public function execute(ParameterContainer|array|null $parameters = null): ?ResultInterface { if (! $this->isPrepared()) { diff --git a/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTest.php b/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTest.php deleted file mode 100644 index 7604764..0000000 --- a/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTest.php +++ /dev/null @@ -1,14 +0,0 @@ -markTestSkipped('pdo_pgsql integration tests are not enabled!'); - } - - $this->adapter = new Adapter([ - 'driver' => 'pdo_pgsql', - 'database' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), - 'hostname' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'), - 'username' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), - 'password' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD'), - ]); - - $this->hostname = (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); - } -} diff --git a/test/integration/Driver/Pdo/AbstractAdapterTestCase.php b/test/integration/Driver/Pdo/AbstractAdapterTestCase.php new file mode 100644 index 0000000..c14fdd4 --- /dev/null +++ b/test/integration/Driver/Pdo/AbstractAdapterTestCase.php @@ -0,0 +1,84 @@ +getAdapter()->getDriver()->getConnection(); + $this->assertInstanceOf(ConnectionInterface::class, $connection); + } + + public function testGetCurrentSchema(): void + { + /** @var AdapterInterface&SchemaAwareInterface&Adapter $adapter */ + $adapter = $this->getAdapter(); + $schema = $adapter->getCurrentSchema(); + self::assertIsString($schema); + self::assertNotEmpty($schema); + } + + public function testDriverDisconnectAfterQuoteWithPlatform(): void + { + $isTcpConnection = $this->isTcpConnection(); + + /** @var AdapterInterface&Adapter $adapter */ + $adapter = $this->getAdapter([ + 'db' => [ + 'driver' => Pdo::class, + ], + ]); + $adapter->getDriver()->getConnection()->connect(); + self::assertTrue($adapter->getDriver()->getConnection()->isConnected()); + if ($isTcpConnection) { + self::assertTrue($adapter->getDriver()->getConnection()->isConnected()); + } + + $adapter->getDriver()->getConnection()->disconnect(); + self::assertFalse($adapter->getDriver()->getConnection()->isConnected()); + if ($isTcpConnection) { + self::assertFalse($adapter->getDriver()->getConnection()->isConnected()); + } + + $adapter->getDriver()->getConnection()->connect(); + self::assertTrue($adapter->getDriver()->getConnection()->isConnected()); + if ($isTcpConnection) { + self::assertTrue($adapter->getDriver()->getConnection()->isConnected()); + } + + $adapter->getPlatform()->quoteValue('test'); + + $adapter->getDriver()->getConnection()->disconnect(); + + self::assertFalse($adapter->getDriver()->getConnection()->isConnected()); + if ($isTcpConnection) { + self::assertFalse($adapter->getDriver()->getConnection()->isConnected()); + } + } + + protected function isTcpConnection(): bool + { + $hostName = $this->getHostname(); + return $hostName !== 'localhost' && $hostName !== '127.0.0.1'; + } +} diff --git a/test/integration/Driver/Pdo/AdapterTest.php b/test/integration/Driver/Pdo/AdapterTest.php new file mode 100644 index 0000000..301b8eb --- /dev/null +++ b/test/integration/Driver/Pdo/AdapterTest.php @@ -0,0 +1,10 @@ +markTestSkipped('pdo_pgsql integration tests are not enabled!'); + } + + $connectionParams = [ + 'driver' => 'pdo_pgsql', + 'database' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), + 'hostname' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'), + 'username' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), + ]; + + $pdoDriver = new Pdo( + new Connection($connectionParams), + new Statement(), + new Result() + ); + + $this->adapter = new Adapter( + $pdoDriver, + new Postgresql($pdoDriver) + ); + + $this->hostname = (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'); + } + + public function getAdapter(): AdapterInterface + { + return $this->adapter; + } + + public function getHostname(): string + { + return $this->hostname; + } +} diff --git a/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php b/test/integration/Driver/Pdo/TableGatewayTest.php similarity index 81% rename from test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php rename to test/integration/Driver/Pdo/TableGatewayTest.php index 6d278a6..160ca49 100644 --- a/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php +++ b/test/integration/Driver/Pdo/TableGatewayTest.php @@ -1,8 +1,9 @@ testSuite()->name() !== 'integration test') { + return; + } + + if (getenv('TESTS_PHPDB_ADAPTER_MYSQL')) { + $this->fixtureLoaders[] = new PgsqlFixtureLoader(); + } + + if (empty($this->fixtureLoaders)) { + return; + } + + printf("\nIntegration test started.\n"); + + foreach ($this->fixtureLoaders as $fixtureLoader) { + $fixtureLoader->createDatabase(); + } + } +} diff --git a/test/integration/Extension/IntegrationTestStoppedListener.php b/test/integration/Extension/IntegrationTestStoppedListener.php new file mode 100644 index 0000000..dcf1b9f --- /dev/null +++ b/test/integration/Extension/IntegrationTestStoppedListener.php @@ -0,0 +1,33 @@ +testSuite()->name() !== 'integration test' + || empty($this->fixtureLoaders) + ) { + return; + } + + printf("\nIntegration test ended.\n"); + + foreach ($this->fixtureLoaders as $fixtureLoader) { + $fixtureLoader->dropDatabase(); + } + } +} diff --git a/test/integration/Extension/ListenerExtension.php b/test/integration/Extension/ListenerExtension.php new file mode 100644 index 0000000..9f0f171 --- /dev/null +++ b/test/integration/Extension/ListenerExtension.php @@ -0,0 +1,24 @@ +registerSubscribers( + new IntegrationTestStartedListener(), + new IntegrationTestStoppedListener(), + ); + } +} diff --git a/test/integration/FixtureLoader/PgsqlFixtureLoader.php b/test/integration/FixtureLoader/PgsqlFixtureLoader.php index f2cd5d6..c54a7c5 100644 --- a/test/integration/FixtureLoader/PgsqlFixtureLoader.php +++ b/test/integration/FixtureLoader/PgsqlFixtureLoader.php @@ -34,12 +34,12 @@ public function createDatabase(): void if ( false === $this->pdo->exec(sprintf( "CREATE DATABASE %s", - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE') + getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE') )) ) { throw new Exception(sprintf( "I cannot create the PostgreSQL %s test database: %s", - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'), + getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), print_r($this->pdo->errorInfo(), true) )); } @@ -52,7 +52,7 @@ public function createDatabase(): void if (false === $this->pdo->exec(file_get_contents($this->fixtureFile))) { throw new Exception(sprintf( "I cannot create the table for %s database. Check the %s file. %s ", - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'), + getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), $this->fixtureFile, print_r($this->pdo->errorInfo(), true) )); @@ -75,7 +75,7 @@ public function dropDatabase(): void $this->pdo->exec(sprintf( "DROP DATABASE IF EXISTS %s", - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE') + getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE') )); $this->disconnect(); @@ -86,16 +86,16 @@ public function dropDatabase(): void */ protected function connect(bool $useDb = false): void { - $dsn = 'pgsql:host=' . getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); + $dsn = 'pgsql:host=' . getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'); if ($useDb) { - $dsn .= ';dbname=' . getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'); + $dsn .= ';dbname=' . getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'); } $this->pdo = new PDO( $dsn, - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_USERNAME'), - getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_PASSWORD') + getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD') ); } diff --git a/test/integration/Adapter/Platform/PostgresqlTest.php b/test/integration/Platform/PostgresqlTest.php similarity index 100% rename from test/integration/Adapter/Platform/PostgresqlTest.php rename to test/integration/Platform/PostgresqlTest.php diff --git a/test/unit/Adapter/AdapterTest.php b/test/unit/Adapter/AdapterTest.php index 0ee756b..ff1d96b 100644 --- a/test/unit/Adapter/AdapterTest.php +++ b/test/unit/Adapter/AdapterTest.php @@ -12,7 +12,7 @@ use PhpDb\Adapter\Driver\ResultInterface; use PhpDb\Adapter\Driver\StatementInterface; use PhpDb\Adapter\ParameterContainer; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Pdo; +use PhpDb\Adapter\Pgsql\Driver\Pdo\Driver; use PhpDb\Adapter\Pgsql\Platform\Postgresql as PgsqlPlatform; use PhpDb\Adapter\Profiler; use PhpDb\ResultSet\ResultSet; From 7c9f5a6550651848f18dee35ddd36937f518f488 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 22 Dec 2025 23:15:14 -0600 Subject: [PATCH 2/2] Completely rebuilds AdapterAbstractServiceFactory usage. Refactors all factories (Pdo has not been completed) to work primarily through the abstract factory. Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 11 +- composer.lock | 9 +- phpunit.xml.dist | 10 +- src/AdapterPlatform.php | 14 +- src/ConfigProvider.php | 73 ++++++++- src/Connection.php | 16 +- .../AdapterAbstractServiceFactory.php | 141 ++++++++++++++++ src/Container/AdapterInterfaceFactory.php | 12 +- src/Container/ConnectionInterfaceFactory.php | 31 ++++ .../ConnectionInterfaceFactoryFactory.php | 10 -- src/Container/DriverInterfaceFactory.php | 30 ++++ .../DriverInterfaceFactoryFactory.php | 10 -- ...gator.php => MetadataInterfaceFactory.php} | 2 +- .../PdoConnectionInterfaceFactory.php | 1 - src/Container/PdoResultFactory.php | 10 -- src/Container/PdoStatementFactory.php | 10 -- src/Container/PlatformInterfaceFactory.php | 24 ++- .../PlatformInterfaceFactoryFactory.php | 10 -- src/Container/StatementInterfaceFactory.php | 23 +++ src/Driver.php | 1 - src/Exception/ContainerException.php | 25 +++ src/Metadata/Source.php | 2 +- src/Pdo/Connection.php | 4 +- src/Pdo/Driver.php | 4 +- src/Result.php | 2 +- src/Statement.php | 19 ++- test/asset/SetupTrait.php | 152 ++++++++++++++++++ ...gresqlTest.php => AdapterPlatformTest.php} | 30 ++-- test/integration/Driver/Pdo/AdapterTest.php | 10 -- .../AdapterTest.php} | 8 +- .../{Driver => }/Pdo/SetupTrait.php | 18 +-- .../{Driver => }/Pdo/TableGatewayTest.php | 0 .../Adapter/AdapterInterfaceFactoryTest.php | 116 ------------- test/unit/Adapter/AdapterTest.php | 68 ++++---- test/unit/Adapter/ConfigProviderTest.php | 54 +++++-- test/unit/Adapter/SetupTest.php | 20 +++ 36 files changed, 670 insertions(+), 310 deletions(-) create mode 100644 src/Container/AdapterAbstractServiceFactory.php create mode 100644 src/Container/ConnectionInterfaceFactory.php delete mode 100644 src/Container/ConnectionInterfaceFactoryFactory.php create mode 100644 src/Container/DriverInterfaceFactory.php delete mode 100644 src/Container/DriverInterfaceFactoryFactory.php rename src/Container/{AdapterManagerDelegator.php => MetadataInterfaceFactory.php} (68%) delete mode 100644 src/Container/PdoResultFactory.php delete mode 100644 src/Container/PdoStatementFactory.php delete mode 100644 src/Container/PlatformInterfaceFactoryFactory.php create mode 100644 src/Container/StatementInterfaceFactory.php create mode 100644 src/Exception/ContainerException.php create mode 100644 test/asset/SetupTrait.php rename test/integration/{Platform/PostgresqlTest.php => AdapterPlatformTest.php} (74%) delete mode 100644 test/integration/Driver/Pdo/AdapterTest.php rename test/integration/{Driver/Pdo/AbstractAdapterTestCase.php => Pdo/AdapterTest.php} (93%) rename test/integration/{Driver => }/Pdo/SetupTrait.php (80%) rename test/integration/{Driver => }/Pdo/TableGatewayTest.php (100%) delete mode 100644 test/unit/Adapter/AdapterInterfaceFactoryTest.php create mode 100644 test/unit/Adapter/SetupTest.php diff --git a/composer.json b/composer.json index d53621e..a753655 100644 --- a/composer.json +++ b/composer.json @@ -31,16 +31,17 @@ }, "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", - "php-db/phpdb": "^0.4.0" + "php-db/phpdb": "^0.4.1" }, "require-dev": { + "ext-pdo_pgsql": "*", + "ext-pgsql": "*", "laminas/laminas-coding-standard": "^3.0.1", "phpstan/phpstan": "^2.1", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^11.5.42" }, "suggest": { - "ext-pdo": "*", "ext-pdo_pgsql": "*", "ext-pgsql": "*", "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" @@ -53,13 +54,14 @@ "autoload-dev": { "psr-4": { "PhpDbTest\\Adapter\\Pgsql\\": "test/unit/", + "PhpDbTestAsset\\Pgsql\\": "test/asset/", "PhpDbIntegrationTest\\Adapter\\Pgsql\\": "test/integration/" } }, "scripts": { "check": [ "@cs-check", - "@static-analysis", + "@sa", "@test", "@test-integration" ], @@ -68,8 +70,9 @@ "test": "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": "vendor/bin/phpstan analyse --memory-limit=256M", + "sa": "vendor/bin/phpstan analyse --memory-limit=256M", "sa-generate-baseline": "vendor/bin/phpstan analyse --memory-limit=256M --generate-baseline", + "sa-verbose": "vendor/bin/phpstan analyse --memory-limit=256M -vv", "upload-coverage": "coveralls -v" } } diff --git a/composer.lock b/composer.lock index 136a4da..4461851 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a3f0f794e48b895f9ed9031ee29dcf78", + "content-hash": "5063e7391ca1bbb366715a6569a7af12", "packages": [ { "name": "brick/varexporter", @@ -259,7 +259,7 @@ }, { "name": "php-db/phpdb", - "version": "0.4.0", + "version": "0.4.x-dev", "source": { "type": "git", "url": "https://github.com/php-db/phpdb.git", @@ -2600,7 +2600,10 @@ "platform": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, - "platform-dev": {}, + "platform-dev": { + "ext-pdo_pgsql": "*", + "ext-pgsql": "*" + }, "platform-overrides": { "php": "8.2.99" }, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 97ae618..295633b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -29,10 +29,10 @@ - - - - - + + + + + \ No newline at end of file diff --git a/src/AdapterPlatform.php b/src/AdapterPlatform.php index 79c5a2d..9ba5f64 100644 --- a/src/AdapterPlatform.php +++ b/src/AdapterPlatform.php @@ -7,19 +7,13 @@ use Override; use PDO; use PgSql\Connection as PgSqlConnection; -use PhpDb\Adapter\AdapterInterface; use PhpDb\Adapter\Driver\DriverInterface; use PhpDb\Adapter\Driver\PdoDriverInterface; -use PhpDb\Adapter\Driver\Pgsql\Pgsql; -use PhpDb\Adapter\Exception; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Driver as PdoDriver; use PhpDb\Adapter\Platform\AbstractPlatform; use PhpDb\Sql\Platform\Platform as SqlPlatformDecorator; use PhpDb\Sql\Platform\PlatformDecoratorInterface; -use function get_resource_type; use function implode; -use function in_array; use function is_resource; use function pg_escape_string; use function str_replace; @@ -27,15 +21,14 @@ class AdapterPlatform extends AbstractPlatform { public final const PLATFORM_NAME = 'PostgreSQL'; + /** * Overrides value from AbstractPlatform to use proper escaping for Postgres - * - * @var string */ - protected $quoteIdentifierTo = '""'; + protected string $quoteIdentifierTo = '""'; /** @var string[] */ - private $knownPgsqlResources = [ + private array $knownPgsqlResources = [ 'pgsql link', 'pgsql link persistent', ]; @@ -78,7 +71,6 @@ public function quoteValue($value): string * {@inheritDoc} * * @param scalar $value - * @return string */ #[Override] public function quoteTrustedValue($value): string diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 819b840..be98388 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -4,29 +4,90 @@ namespace PhpDb\Adapter\Pgsql; +use Laminas\ServiceManager\Factory\InvokableFactory; use PhpDb\Adapter\AdapterInterface; +use PhpDb\Adapter\Driver\ConnectionInterface; use PhpDb\Adapter\Driver\DriverInterface; +use PhpDb\Adapter\Driver\PdoConnectionInterface; +use PhpDb\Adapter\Driver\PdoDriverInterface; use PhpDb\Adapter\Platform\PlatformInterface; +use PhpDb\Adapter\Pgsql\Pdo\Connection as PdoConnection; +use PhpDb\Adapter\Pgsql\Pdo\Driver as PdoDriver; +use PhpDb\Adapter\Profiler\Profiler; +use PhpDb\Adapter\Profiler\ProfilerInterface; +use PhpDb\Container\AdapterAbstractServiceFactory; +use PhpDb\Metadata\MetadataInterface; +use PhpDb\ResultSet\ResultSetInterface; -readonly class ConfigProvider +final readonly class ConfigProvider { public function __invoke(): array { return [ - 'dependencies' => $this->getDependencies(), + 'dependencies' => $this->getDependencies(), + AdapterInterface::class => $this->getAdapters(), + ]; + } + + public function getAdapters(): array + { + return [ + 'adapters' => [ + AdapterInterface::class => [ + 'driver' => Driver::class, + 'connection' => [ + 'host' => 'localhost', + 'port' => 5432, + 'username' => 'your_username', + 'password' => 'your_password', + 'database' => 'your_database', + ], + ], + ], ]; } public function getDependencies(): array { return [ + 'abstract_factories' => [ + Container\AdapterAbstractServiceFactory::class, + ], 'aliases' => [ - PlatformInterface::class => AdapterPlatform::class, + DriverInterface::class => Driver::class, + 'pgsql' => Driver::class, + 'PgSQL' => Driver::class, + 'Postgresql' => Driver::class, + 'PostgreSQL' => Driver::class, + PdoDriverInterface::class => PdoDriver::class, + 'pdo_pgsql' => PdoDriver::class, + 'PDO_pgsql' => PdoDriver::class, + 'PDO_PgSQL' => PdoDriver::class, + 'Pdo_PgSQL' => PdoDriver::class, + 'PDO_postgresql' => PdoDriver::class, + 'pdo_postgresql' => PdoDriver::class, + 'PDO_Postgresql' => PdoDriver::class, + 'Pdo_Postgresql' => PdoDriver::class, + 'PDO_PostgreSQL' => PdoDriver::class, + 'pdo_PostgreSQL' => PdoDriver::class, + ConnectionInterface::class => Connection::class, + MetadataInterface::class => Metadata\Source::class, + PdoConnectionInterface::class => PdoConnection::class, + PlatformInterface::class => AdapterPlatform::class, ], 'factories' => [ - AdapterInterface::class => Container\AdapterInterfaceFactory::class, - DriverInterface::class => Container\PdoDriverInterfaceFactory::class, - AdapterPlatform::class => Container\PlatformInterfaceFactory::class, + //AdapterInterface::class => Container\AdapterInterfaceFactory::class, + AdapterPlatform::class => Container\PlatformInterfaceFactory::class, + Connection::class => Container\ConnectionInterfaceFactory::class, + Metadata\Source::class => Container\MetadataInterfaceFactory::class, + Statement::class => Container\StatementInterfaceFactory::class, + Driver::class => Container\DriverInterfaceFactory::class, + PdoConnection::class => Container\PdoConnectionInterfaceFactory::class, + PdoDriver::class => Container\PdoDriverInterfaceFactory::class, + // Provide the following if you wish to override the Profiler implementation + //ProfilerInterface::class => YourCustomProfilerFactory::class, + // Provide the following if you wish to override the ResultSet implementation + //ResultSetInterface::class => YourCustomResultSetFactory::class, ], ]; } diff --git a/src/Connection.php b/src/Connection.php index c482e98..b058bc4 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -27,6 +27,7 @@ use function set_error_handler; use function sprintf; use function str_replace; +use function strtolower; use function urldecode; use const PGSQL_CONNECT_FORCE_NEW; @@ -35,7 +36,8 @@ class Connection extends AbstractConnection implements DriverAwareInterface { protected Driver $driver; - protected PgSqlConnection $resource; + /** @var PgSqlConnection|null */ + protected $resource; /** @var null|int PostgreSQL connection type */ protected ?int $type = null; @@ -268,7 +270,7 @@ public function getLastGeneratedValue($name = null): bool|int|string|null private function getConnectionString(): string { $parameters = $this->connectionParameters; - $conn = []; + $conn = []; foreach ($parameters as $name => $value) { $name = match (strtolower($name)) { 'host', 'hostname' => 'host', @@ -278,7 +280,7 @@ private function getConnectionString(): string 'port' => 'port', 'socket' => 'socket', default => throw new Exception\InvalidArgumentException( - 'Connection parameter "' . $name . '"' . ' is not valid for Pgsql adapter' + 'Connection parameter "' . $name . '" is not valid for Pgsql adapter' ), }; if ($name === 'port' && $value !== null) { @@ -290,9 +292,9 @@ private function getConnectionString(): string return urldecode( http_build_query( array_filter($conn), - '', - ' ' - ) - ); + '', + ' ' + ) + ); } } diff --git a/src/Container/AdapterAbstractServiceFactory.php b/src/Container/AdapterAbstractServiceFactory.php new file mode 100644 index 0000000..f8f68b2 --- /dev/null +++ b/src/Container/AdapterAbstractServiceFactory.php @@ -0,0 +1,141 @@ +getConfig($container); + if ($config === []) { + return false; + } + + return isset($config[$requestedName]) + && is_array($config[$requestedName]) + && ! empty($config[$requestedName]); + } + + /** + * Create a DB adapter + * + * @param string $requestedName + */ + public function __invoke( + ContainerInterface|ServiceManager $container, + $requestedName, + ?array $options = null + ): AdapterInterface&Adapter { + /** @var string|null $driverClass */ + $driverClass = $this->config[$requestedName]['driver'] ?? null; + if ($driverClass === null) { + throw new ServiceNotCreatedException( + sprintf('Cannot create adapter "%s"; no driver configured', $requestedName) + ); + } + + /** @var DriverInterface|PdoDriverInterface $driver */ + $driver = $container->build($driverClass, $this->config[$requestedName]); + /** @var PlatformInterface&Pgsql\AdapterPlatform $platform */ + $platform = $container->build(PlatformInterface::class, ['driver' => $driver]); + /** @var ResultSetInterface|null $resultSet */ + $resultSet = $container->has(ResultSetInterface::class) + ? $container->build(ResultSetInterface::class) + : null; + /** @var ProfilerInterface|null $profiler */ + $profiler = $container->has(ProfilerInterface::class) + ? $container->build(ProfilerInterface::class) + : null; + + return match(true) { + $resultSet !== null && $profiler !== null => new Adapter( + driver:$driver, + platform: $platform, + queryResultSetPrototype: $resultSet, + profiler: $profiler, + ), + $resultSet !== null => new Adapter( + driver:$driver, + platform: $platform, + queryResultSetPrototype: $resultSet, + ), + $profiler !== null => new Adapter( + driver:$driver, + platform: $platform, + profiler: $profiler, + ), + default => new Adapter( + driver:$driver, + platform: $platform, + ), + }; + } + + /** + * Get db configuration, if any + * todo: refactor to use PhpDb\ConfigProvider::ADAPTERS_CONFIG_KEY instead of hardcoding 'adapters' + */ + protected function getConfig(ContainerInterface $container): array + { + if ($this->config !== null) { + return $this->config; + } + + if (! $container->has('config')) { + $this->config = []; + return $this->config; + } + + $config = $container->get('config'); + if ( + ! isset($config[AdapterInterface::class]) + || ! is_array($config[AdapterInterface::class]) + ) { + $this->config = []; + return $this->config; + } + + $config = $config[AdapterInterface::class]; + if ( + ! isset($config['adapters']) + || ! is_array($config['adapters']) + ) { + $this->config = []; + return $this->config; + } + + $this->config = $config['adapters']; + return $this->config; + } +} diff --git a/src/Container/AdapterInterfaceFactory.php b/src/Container/AdapterInterfaceFactory.php index 47cd3c0..1b3df2e 100644 --- a/src/Container/AdapterInterfaceFactory.php +++ b/src/Container/AdapterInterfaceFactory.php @@ -19,8 +19,10 @@ class AdapterInterfaceFactory { - public function __invoke(ContainerInterface $container): AdapterInterface - { + public function __invoke( + ContainerInterface $container, + string $requestedName, + ): AdapterInterface { if (! $container->has('config')) { throw new ServiceNotFoundException( sprintf( @@ -34,7 +36,7 @@ public function __invoke(ContainerInterface $container): AdapterInterface $config = $container->get('config'); /** @var array $dbConfig */ - $dbConfig = $config['db'] ?? []; + $dbConfig = $config[AdapterInterface::class][$requestedName] ?? $config[AdapterInterface::class] ?? []; if (! isset($dbConfig['driver'])) { throw new RuntimeException( @@ -75,14 +77,14 @@ public function __invoke(ContainerInterface $container): AdapterInterface : null; if (! $container->has(ResultSetInterface::class)) { - return new Adapter( + return new $requestedName( driver: $driverInstance, platform: $adapterPlatform, profiler: $profilerInstanceOrNull ); } - return new Adapter( + return new $requestedName( driver: $driverInstance, platform: $adapterPlatform, queryResultSetPrototype: $container->get(ResultSetInterface::class), diff --git a/src/Container/ConnectionInterfaceFactory.php b/src/Container/ConnectionInterfaceFactory.php new file mode 100644 index 0000000..6b6e478 --- /dev/null +++ b/src/Container/ConnectionInterfaceFactory.php @@ -0,0 +1,31 @@ +get('config')[AdapterInterface::class]['adapters'][$requestedName]['connection'] + ?? null; + if ($connectionInfo === null || ! is_array($connectionInfo) || $connectionInfo === []) { + throw new InvalidConnectionParametersException( + 'Connection configuration must be an array of parameters', + $connectionInfo + ); + } + return new Connection($connectionInfo); + } +} diff --git a/src/Container/ConnectionInterfaceFactoryFactory.php b/src/Container/ConnectionInterfaceFactoryFactory.php deleted file mode 100644 index 16b120f..0000000 --- a/src/Container/ConnectionInterfaceFactoryFactory.php +++ /dev/null @@ -1,10 +0,0 @@ -get('config')[AdapterInterface::class]['adapters'][$requestedName]['connection'] + ?? []; + $connection = $container->build(Pgsql\Connection::class, ['connection' => $connectionParameters]); + return new Pgsql\Driver( + connection:$connection, + statementPrototype: $container->build(Pgsql\Statement::class, ['options' => $options['options'] ?? []]), + resultPrototype: new Pgsql\Result(), + ); + } +} diff --git a/src/Container/DriverInterfaceFactoryFactory.php b/src/Container/DriverInterfaceFactoryFactory.php deleted file mode 100644 index 72da1fa..0000000 --- a/src/Container/DriverInterfaceFactoryFactory.php +++ /dev/null @@ -1,10 +0,0 @@ -data['schemas'])) { return; diff --git a/src/Pdo/Connection.php b/src/Pdo/Connection.php index 3f5de24..e8597e0 100644 --- a/src/Pdo/Connection.php +++ b/src/Pdo/Connection.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Driver\Pdo; +namespace PhpDb\Adapter\Pgsql\Pdo; use Override; use PDO; @@ -26,7 +26,7 @@ class Connection extends AbstractPdoConnection * {@inheritDoc} */ #[Override] - public function getCurrentSchema(): string|bool + public function getCurrentSchema(): string|false { if (! $this->isConnected()) { $this->connect(); diff --git a/src/Pdo/Driver.php b/src/Pdo/Driver.php index a235b30..48f21a2 100644 --- a/src/Pdo/Driver.php +++ b/src/Pdo/Driver.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql\Driver\Pdo; +namespace PhpDb\Adapter\Pgsql\Pdo; use Override; use PDOStatement; use PhpDb\Adapter\Driver\Pdo\AbstractPdo; use PhpDb\Adapter\Driver\Pdo\Result; use PhpDb\Adapter\Driver\ResultInterface; -use PhpDb\Adapter\Pgsql\Driver\DatabasePlatformNameTrait; +use PhpDb\Adapter\Pgsql\DatabasePlatformNameTrait; class Driver extends AbstractPdo { diff --git a/src/Result.php b/src/Result.php index 81a6f93..9f71e89 100644 --- a/src/Result.php +++ b/src/Result.php @@ -71,7 +71,7 @@ public function buffer(): void } #[Override] - public function isBuffered(): ?bool + public function isBuffered(): false { return false; } diff --git a/src/Statement.php b/src/Statement.php index e4c97de..8ea3752 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -27,6 +27,8 @@ class Statement implements DriverAwareInterface, ProfilerAwareInterface { + protected bool $bufferResults = false; + protected static int $statementIndex = 0; protected string $statementName = 'statement'; @@ -41,7 +43,16 @@ class Statement implements protected string $sql; - protected ParameterContainer $parameterContainer; + public function __construct( + protected ParameterContainer $parameterContainer = new ParameterContainer(), + array|bool $options = false + ) { + if (is_array($options)) { + $this->bufferResults = $options['buffer_results'] ?? false; + } else { + $this->bufferResults = $options; + } + } #[Override] public function setDriver( @@ -77,7 +88,7 @@ public function getResource(): PgSqlResult|false #[Override] public function setSql( - $sql + ?string $sql ): StatementInterface&DriverAwareInterface&ProfilerAwareInterface { $this->sql = $sql; return $this; @@ -118,9 +129,9 @@ function () use (&$pCount) { $sql ); - $this->sql = $sql; + $this->sql = $sql; $this->statementName .= ++static::$statementIndex; - $this->resource = pg_prepare($this->pgsql, $this->statementName, $sql); + $this->resource = pg_prepare($this->pgsql, $this->statementName, $sql); return $this; } diff --git a/test/asset/SetupTrait.php b/test/asset/SetupTrait.php new file mode 100644 index 0000000..e6ba423 --- /dev/null +++ b/test/asset/SetupTrait.php @@ -0,0 +1,152 @@ +getAdapter(); + parent::setUp(); + } + + public function getAdapter(string $adapter = self::NATIVE_ADAPTER): AdapterInterface + { + $serviceManagerConfig = ArrayUtils::merge( + (new Pgsql\ConfigProvider())()['dependencies'], + [ + 'services' => [ + 'config' => $this->getTestConfig(), + ], + ] + ); + $this->serviceManager = new ServiceManager($serviceManagerConfig); + return $this->serviceManager->get($adapter); + } + + public function getTestConfig(): array + { + return [ + AdapterInterface::class => [ + 'adapters' => [ + self::NATIVE_ADAPTER => [ + 'driver' => Pgsql\Driver::class, + 'connection' => [ + 'host' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'), + 'port' => 5432, + 'username' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), + 'database' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), + ], + ], + self::PDO_ADAPTER => [ + 'driver' => Pgsql\Pdo\Driver::class, + 'connection' => [ + 'host' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'), + 'port' => 5432, + 'username' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), + 'database' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), + ], + ], + ], + ], + ]; + } + + public function getMockedAdapter(string $adapter = self::NATIVE_ADAPTER): AdapterInterface + { + $driverMock = $this->getMockBuilder(DriverInterface::class)->getMock(); + $pdoDriverMock = $this->getMockBuilder(PdoDriverInterface::class)->getMock(); + $testConfig = [ + AdapterInterface::class => [ + 'adapters' => [ + self::NATIVE_ADAPTER => [ + 'driver' => Pgsql\Driver::class, + 'connection' => [ + 'host' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'), + 'port' => 5432, + 'username' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), + 'database' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), + ], + ], + self::PDO_ADAPTER => [ + 'driver' => Pgsql\Pdo\Driver::class, + 'connection' => [ + 'host' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'), + 'port' => 5432, + 'username' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), + 'database' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_DATABASE'), + ], + ], + ], + ], + 'dependencies' => [ + 'abstract_factories' => [ + Pgsql\Container\AdapterAbstractServiceFactory::class, + ], + 'aliases' => [ + DriverInterface::class => Pgsql\Driver::class, + 'pgsql' => Pgsql\Driver::class, + 'PgSQL' => Pgsql\Driver::class, + 'Postgresql' => Pgsql\Driver::class, + 'PostgreSQL' => Pgsql\Driver::class, + PdoDriverInterface::class => Pgsql\Pdo\Driver::class, + 'pdo_pgsql' => Pgsql\Pdo\Driver::class, + 'PDO_pgsql' => Pgsql\Pdo\Driver::class, + 'PDO_PgSQL' => Pgsql\Pdo\Driver::class, + 'Pdo_PgSQL' => Pgsql\Pdo\Driver::class, + 'PDO_postgresql' => Pgsql\Pdo\Driver::class, + 'pdo_postgresql' => Pgsql\Pdo\Driver::class, + 'PDO_Postgresql' => Pgsql\Pdo\Driver::class, + 'Pdo_Postgresql' => Pgsql\Pdo\Driver::class, + 'PDO_PostgreSQL' => Pgsql\Pdo\Driver::class, + 'pdo_PostgreSQL' => Pgsql\Pdo\Driver::class, + ConnectionInterface::class => Pgsql\Connection::class, + PdoConnectionInterface::class => Pgsql\Pdo\Connection::class, + PlatformInterface::class => Pgsql\AdapterPlatform::class, + ], + 'factories' => [ + Pgsql\Driver::class => function (ContainerInterface $container) use ($driverMock) { + return $driverMock; + }, + Pgsql\Pdo\Driver::class => function (ContainerInterface $container) use ($pdoDriverMock) { + return $pdoDriverMock; + }, + ], + ], + ]; + + $libConfig = (new Pgsql\ConfigProvider())(); + $config = ArrayUtils::merge($libConfig, $testConfig); + $serviceManagerConfig = ArrayUtils::merge( + $config['dependencies'], + [ + 'services' => [ + 'config' => $config, + ], + ] + ); + + $this->serviceManager = new ServiceManager($serviceManagerConfig); + return $this->serviceManager->get($adapter); + } +} diff --git a/test/integration/Platform/PostgresqlTest.php b/test/integration/AdapterPlatformTest.php similarity index 74% rename from test/integration/Platform/PostgresqlTest.php rename to test/integration/AdapterPlatformTest.php index 7bec9ab..759d5f6 100644 --- a/test/integration/Platform/PostgresqlTest.php +++ b/test/integration/AdapterPlatformTest.php @@ -1,12 +1,12 @@ */ public array|\PDO $adapters = []; @@ -25,23 +25,23 @@ final class PostgresqlTest extends TestCase #[Override] protected function setUp(): void { - if (! getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL')) { + if (! getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL')) { $this->markTestSkipped(self::class . ' integration tests are not enabled!'); } if (extension_loaded('pgsql')) { $this->adapters['pgsql'] = pg_connect( - 'host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME') - . ' dbname=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') - . ' user=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME') - . ' password=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + 'host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_HOSTNAME') + . ' dbname=' . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_DATABASE') + . ' user=' . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_USERNAME') + . ' password=' . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_PASSWORD') ); } if (extension_loaded('pdo')) { $this->adapters['pdo_pgsql'] = new \PDO( - 'pgsql:host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME') . ';dbname=' - . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + 'pgsql:host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_HOSTNAME') . ';dbname=' + . getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_DATABASE'), + getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_USERNAME'), + getenv('TESTS_LAMINAS_DB_ADAPTER_PGSQL_PASSWORD') ); } } @@ -60,11 +60,11 @@ public function testQuoteValueWithPgsql() ) { $this->markTestSkipped('Postgres (pgsql) not configured in unit test configuration file'); } - $pgsql = new Postgresql($this->adapters['pgsql']); + $pgsql = new AdapterPlatform($this->adapters['pgsql']); $value = $pgsql->quoteValue('value'); self::assertEquals('\'value\'', $value); - $pgsql = new Postgresql(new Pgsql\Pgsql(new Pgsql\Connection($this->adapters['pgsql']))); + $pgsql = new AdapterPlatform(new Driver(new PgSqlConnection($this->adapters['pgsql']))); $value = $pgsql->quoteValue('value'); self::assertEquals('\'value\'', $value); } diff --git a/test/integration/Driver/Pdo/AdapterTest.php b/test/integration/Driver/Pdo/AdapterTest.php deleted file mode 100644 index 301b8eb..0000000 --- a/test/integration/Driver/Pdo/AdapterTest.php +++ /dev/null @@ -1,10 +0,0 @@ -getAdapter([ 'db' => [ - 'driver' => Pdo::class, + 'driver' => Driver::class, ], ]); $adapter->getDriver()->getConnection()->connect(); diff --git a/test/integration/Driver/Pdo/SetupTrait.php b/test/integration/Pdo/SetupTrait.php similarity index 80% rename from test/integration/Driver/Pdo/SetupTrait.php rename to test/integration/Pdo/SetupTrait.php index 60f53e2..2918279 100644 --- a/test/integration/Driver/Pdo/SetupTrait.php +++ b/test/integration/Pdo/SetupTrait.php @@ -2,16 +2,16 @@ declare(strict_types=1); -namespace PhpDbIntegrationTest\Adapter\Pgsql\Driver\Pdo; +namespace PhpDbIntegrationTest\Adapter\Pgsql\Pdo; use Override; use PhpDb\Adapter\Adapter; use PhpDb\Adapter\AdapterInterface; use PhpDb\Adapter\Driver\Pdo\Result; use PhpDb\Adapter\Driver\Pdo\Statement; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Driver; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Connection; -use PhpDb\Adapter\Pgsql\Platform\Postgresql; +use PhpDb\Adapter\Pgsql\AdapterPlatform; +use PhpDb\Adapter\Pgsql\Pdo\Connection; +use PhpDb\Adapter\Pgsql\Pdo\Driver; use function getenv; use function is_string; @@ -40,15 +40,15 @@ protected function setUp(): void 'password' => (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_PASSWORD'), ]; - $pdoDriver = new Pdo( - new Connection($connectionParams), - new Statement(), - new Result() + $pdoDriver = new Driver( + new Connection($connectionParams), + new Statement(), + new Result() ); $this->adapter = new Adapter( $pdoDriver, - new Postgresql($pdoDriver) + new AdapterPlatform($pdoDriver) ); $this->hostname = (string) getenv('TESTS_PHPDB_ADAPTER_PGSQL_HOSTNAME'); diff --git a/test/integration/Driver/Pdo/TableGatewayTest.php b/test/integration/Pdo/TableGatewayTest.php similarity index 100% rename from test/integration/Driver/Pdo/TableGatewayTest.php rename to test/integration/Pdo/TableGatewayTest.php diff --git a/test/unit/Adapter/AdapterInterfaceFactoryTest.php b/test/unit/Adapter/AdapterInterfaceFactoryTest.php deleted file mode 100644 index 309cd68..0000000 --- a/test/unit/Adapter/AdapterInterfaceFactoryTest.php +++ /dev/null @@ -1,116 +0,0 @@ -getDependencies(); - $config['services']['config'] = $dbConfig; - - return new ServiceManager($config); - } - - #[Override] - protected function setUp(): void - { - if (! extension_loaded('pdo_sqlite')) { - $this->markTestSkipped('Adapter factory tests require pdo_sqlite'); - } - - $this->factory = new AdapterInterfaceFactory(); - } - - /** - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function testV3FactoryReturnsDefaultAdapter(): void - { - $this->expectNotToPerformAssertions(); - - $services = $this->createServiceManager([ - 'db' => [ - 'driver' => 'Pdo_Pgsql', - 'database' => ':memory:', - ], - ]); - - $this->factory->__invoke($services, Adapter::class); - } - - /** - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function testV3FactoryReturnsDefaultAdapterWithDefaultProfiler(): void - { - $services = $this->createServiceManager([ - 'db' => [ - 'driver' => 'Pdo_Pgsql', - 'database' => ':memory:', - 'profiler' => true, - ], - ]); - - $adapter = $this->factory->__invoke($services, Adapter::class); - self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); - } - - /** - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function testV3FactoryReturnsDefaultAdapterWithProfilerClassname(): void - { - $services = $this->createServiceManager([ - 'db' => [ - 'driver' => 'Pdo_Pgsql', - 'database' => ':memory:', - 'profiler' => Profiler::class, - ], - ]); - - $adapter = $this->factory->__invoke($services, Adapter::class); - self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); - } - - /** - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function testV3FactoryReturnsDefaultAdapterWithProfilerInstance(): void - { - $services = $this->createServiceManager([ - 'db' => [ - 'driver' => 'Pdo_Pgsql', - 'database' => ':memory:', - 'profiler' => $this->getMockBuilder(ProfilerInterface::class)->getMock(), - ], - ]); - - $adapter = $this->factory->__invoke($services, Adapter::class); - self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); - } -} diff --git a/test/unit/Adapter/AdapterTest.php b/test/unit/Adapter/AdapterTest.php index ff1d96b..cdfb8f0 100644 --- a/test/unit/Adapter/AdapterTest.php +++ b/test/unit/Adapter/AdapterTest.php @@ -12,12 +12,11 @@ use PhpDb\Adapter\Driver\ResultInterface; use PhpDb\Adapter\Driver\StatementInterface; use PhpDb\Adapter\ParameterContainer; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Driver; -use PhpDb\Adapter\Pgsql\Platform\Postgresql as PgsqlPlatform; +use PhpDb\Adapter\Pgsql\AdapterPlatform; +use PhpDb\Adapter\Pgsql\Pdo\Driver; use PhpDb\Adapter\Profiler; use PhpDb\ResultSet\ResultSet; use PhpDb\ResultSet\ResultSetInterface; -use PhpDbTest\TestAsset\TemporaryResultSet; use PHPUnit\Framework\Attributes\CoversMethod; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\TestDox; @@ -40,7 +39,7 @@ final class AdapterTest extends TestCase { protected DriverInterface&MockObject $mockDriver; - protected PgsqlPlatform $mockPlatform; + protected AdapterPlatform $mockPlatform; protected ConnectionInterface&MockObject $mockConnection; @@ -194,9 +193,6 @@ public function testQueryWhenExecutedProducesAResultSetObjectWhenResultIsQuery() $r = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); self::assertInstanceOf(ResultSet::class, $r); - - $r = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE, new TemporaryResultSet()); - self::assertInstanceOf(TemporaryResultSet::class, $r); } #[TestDox('unit test: Test createStatement() produces a statement object')] @@ -220,33 +216,33 @@ public function testMagicGet(): void $this->adapter->foo; } - /** - * @throws Exception - */ - #[Override] - protected function setUp(): void - { - $this->mockConnection = $this->createMock(ConnectionInterface::class); - $this->mockPlatform = new PgsqlPlatform(); - $this->mockStatement = $this->getMockBuilder(Statement::class)->getMock(); - $this->mockDriver = $this->getMockBuilder(Pdo::class) - ->setConstructorArgs([ - $this->mockConnection, - $this->mockStatement, - ]) - ->getMock(); - - $this->mockResultSet = $this->getMockBuilder(ResultSetInterface::class)->getMock(); - - $this->mockDriver->method('getDatabasePlatformName')->willReturn('Pgsql'); - $this->mockDriver->method('checkEnvironment')->willReturn(true); - $this->mockDriver->method('getConnection')->willReturn($this->mockConnection); - //$this->mockDriver->method('createStatement')->willReturn($this->mockStatement); - - $this->adapter = new Adapter( - $this->mockDriver, - $this->mockPlatform, - $this->mockResultSet - ); - } + // #[Override] + // protected function setUp(): void + // { + // $this->mockConnection = $this->createMock(ConnectionInterface::class); + + // $this->mockStatement = $this->getMockBuilder(Statement::class)->getMock(); + + // $this->mockDriver = $this->getMockBuilder(Driver::class) + // ->setConstructorArgs([ + // $this->mockConnection, + // $this->mockStatement, + // ]) + // ->getMock(); + + // $this->mockDriver->method('getDatabasePlatformName')->willReturn('Pgsql'); + // $this->mockDriver->method('checkEnvironment')->willReturn(true); + // $this->mockDriver->method('getConnection')->willReturn($this->mockConnection); + // $this->mockDriver->method('createStatement')->willReturn($this->mockStatement); + + // $this->mockPlatform = new AdapterPlatform($this->mockDriver); + + // $this->mockResultSet = $this->getMockBuilder(ResultSetInterface::class)->getMock(); + + // $this->adapter = new Adapter( + // $this->mockDriver, + // $this->mockPlatform, + // $this->mockResultSet + // ); + // } } diff --git a/test/unit/Adapter/ConfigProviderTest.php b/test/unit/Adapter/ConfigProviderTest.php index 4132144..8d1c86b 100644 --- a/test/unit/Adapter/ConfigProviderTest.php +++ b/test/unit/Adapter/ConfigProviderTest.php @@ -6,46 +6,70 @@ use Laminas\ServiceManager\Factory\InvokableFactory; use PhpDb\Adapter\AdapterInterface; +use PhpDb\Adapter\Driver\ConnectionInterface; use PhpDb\Adapter\Driver\DriverInterface; -use PhpDb\Adapter\Pgsql\ConfigProvider; -use PhpDb\Adapter\Pgsql\Container\AdapterServiceFactory; -use PhpDb\Adapter\Pgsql\Driver; -use PhpDb\Adapter\Pgsql\Platform; +use PhpDb\Adapter\Driver\PdoConnectionInterface; +use PhpDb\Adapter\Driver\PdoDriverInterface; +use PhpDb\Adapter\Pgsql; use PhpDb\Adapter\Platform\PlatformInterface; use PhpDb\Adapter\Profiler\Profiler; use PhpDb\Adapter\Profiler\ProfilerInterface; +use PhpDb\Container\AdapterAbstractServiceFactory; +use PhpDb\Metadata\MetadataInterface; use PHPUnit\Framework\Attributes\CoversMethod; use PHPUnit\Framework\Attributes\Depends; use PHPUnit\Framework\TestCase; -#[CoversMethod(ConfigProvider::class, '__invoke')] -#[CoversMethod(ConfigProvider::class, 'getDependencies')] +#[CoversMethod(Pgsql\ConfigProvider::class, '__invoke')] +#[CoversMethod(Pgsql\ConfigProvider::class, 'getDependencies')] final class ConfigProviderTest extends TestCase { /** @var array> */ private array $config = [ 'aliases' => [ - PlatformInterface::class => Platform\Postgresql::class, - ProfilerInterface::class => Profiler::class, + DriverInterface::class => Pgsql\Driver::class, + 'pgsql' => Pgsql\Driver::class, + 'PgSQL' => Pgsql\Driver::class, + 'Postgresql' => Pgsql\Driver::class, + 'PostgreSQL' => Pgsql\Driver::class, + PdoDriverInterface::class => Pgsql\Pdo\Driver::class, + 'pdo_pgsql' => Pgsql\Pdo\Driver::class, + 'PDO_pgsql' => Pgsql\Pdo\Driver::class, + 'PDO_PgSQL' => Pgsql\Pdo\Driver::class, + 'Pdo_PgSQL' => Pgsql\Pdo\Driver::class, + 'PDO_postgresql' => Pgsql\Pdo\Driver::class, + 'pdo_postgresql' => Pgsql\Pdo\Driver::class, + 'PDO_Postgresql' => Pgsql\Pdo\Driver::class, + 'Pdo_Postgresql' => Pgsql\Pdo\Driver::class, + 'PDO_PostgreSQL' => Pgsql\Pdo\Driver::class, + 'pdo_PostgreSQL' => Pgsql\Pdo\Driver::class, + ConnectionInterface::class => Pgsql\Connection::class, + MetadataInterface::class => Pgsql\Metadata\Source::class, + PdoConnectionInterface::class => Pgsql\Pdo\Connection::class, + PlatformInterface::class => Pgsql\AdapterPlatform::class, + ProfilerInterface::class => Profiler::class, ], 'factories' => [ - AdapterInterface::class => AdapterServiceFactory::class, - DriverInterface::class => Driver\Pdo\DriverFactory::class, - Platform\Postgresql::class => InvokableFactory::class, - Profiler::class => InvokableFactory::class, + AdapterInterface::class => Pgsql\Container\AdapterInterfaceFactory::class, + Pgsql\Driver::class => Pgsql\Container\DriverInterfaceFactory::class, + Pgsql\Pdo\Driver::class => Pgsql\Container\PdoDriverInterfaceFactory::class, + Pgsql\Connection::class => Pgsql\Container\ConnectionInterfaceFactory::class, + Pgsql\Pdo\Connection::class => Pgsql\Container\PdoConnectionInterfaceFactory::class, + Pgsql\AdapterPlatform::class => Pgsql\Container\PlatformInterfaceFactory::class, + Profiler::class => InvokableFactory::class, ], ]; - public function testProvidesExpectedConfiguration(): ConfigProvider + public function testProvidesExpectedConfiguration(): Pgsql\ConfigProvider { - $provider = new ConfigProvider(); + $provider = new Pgsql\ConfigProvider(); self::assertEquals($this->config, $provider->getDependencies()); return $provider; } #[Depends('testProvidesExpectedConfiguration')] - public function testInvocationProvidesDependencyConfiguration(ConfigProvider $provider): void + public function testInvocationProvidesDependencyConfiguration(Pgsql\ConfigProvider $provider): void { self::assertEquals(['dependencies' => $provider->getDependencies()], $provider()); } diff --git a/test/unit/Adapter/SetupTest.php b/test/unit/Adapter/SetupTest.php new file mode 100644 index 0000000..8ed8abf --- /dev/null +++ b/test/unit/Adapter/SetupTest.php @@ -0,0 +1,20 @@ +getAdapter(); + self::assertInstanceOf(AdapterInterface::class, $adapter); + } +}