From 8db32240d7933e1378e78498eb53f6493fca6536 Mon Sep 17 00:00:00 2001 From: dimarik82 Date: Mon, 18 May 2026 09:01:18 +0000 Subject: [PATCH 1/2] refactor: move transaction-factory selection into Driver composition root Type was an @api enum that imported internal classes and exposed makeFactoryTransaction() returning class-string, leaking an internal type through the public API surface. - Type is now a pure public dialect enum (cases + value()), with no reference to internal classes. - Connection no longer depends on the public Type for behavior; its constructor takes class-string directly. - Driver (the composition root that already resolves the dialect via prepareDSN) decides which transaction factory to use via a private makeFactoryTransaction(), so the choice is not part of any public surface. - StatementMysqlTest constructs Connection with the factory class-string. - composer.json: drop the dbschemix/core vcs repository entry. phpcs/psalm/phpstan green; 29/29 Testo tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- composer.json | 6 ------ src/Driver.php | 23 +++++++++++++++++++++-- src/Type.php | 16 ---------------- src/internal/Connection.php | 9 +++++---- tests/workflow/StatementMysqlTest.php | 4 ++-- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/composer.json b/composer.json index 22595f5..c4b5d94 100644 --- a/composer.json +++ b/composer.json @@ -49,12 +49,6 @@ }, "sort-packages": true }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/dbschemix/core" - } - ], "scripts": { "fix": [ "@phpcbf", diff --git a/src/Driver.php b/src/Driver.php index d058c57..9598ca5 100644 --- a/src/Driver.php +++ b/src/Driver.php @@ -10,12 +10,16 @@ use PDOException; use OutOfBoundsException; use dbschemix\core\command\Command; +use dbschemix\core\command\CommandInterface; use dbschemix\core\connection\ConnectionInterface; use dbschemix\core\connection\DriverInterface; use dbschemix\core\exception\ConfigurationException; use dbschemix\core\exception\ConnectionException; use dbschemix\core\Config; use dbschemix\pdo\internal\Connection; +use dbschemix\pdo\internal\FactoryTransaction; +use dbschemix\pdo\internal\Transaction; +use dbschemix\pdo\internal\TransactionMysql; use function dbschemix\core\internal\get_package_path; @@ -84,7 +88,7 @@ public function getSetupPath(): string } #[Override] - public function makeCommand(Config $config): Command + public function makeCommand(Config $config): CommandInterface { return new Command($this->makeConnection(), $config); } @@ -106,7 +110,7 @@ private function makeConnection(): ConnectionInterface try { return $this->connectionInstance = new Connection( ($this->connectionFactory)(), - $this->type, + $this->makeFactoryTransaction(), ); } catch (PDOException $exception) { throw new ConnectionException($this, $exception); @@ -115,9 +119,24 @@ private function makeConnection(): ConnectionInterface return $this->connectionInstance; } + + /** + * Composition root: picks the transaction factory for the resolved dialect. + * + * @return class-string + */ + private function makeFactoryTransaction(): string + { + if ($this->type === Type::PDO_MYSQL) { + return TransactionMysql::class; + } + + return Transaction::class; + } } /** + * @internal * @return array{0: Type, 1: non-empty-lowercase-string} * @throws ConfigurationException */ diff --git a/src/Type.php b/src/Type.php index da5e879..598afbc 100644 --- a/src/Type.php +++ b/src/Type.php @@ -4,10 +4,6 @@ namespace dbschemix\pdo; -use dbschemix\pdo\internal\FactoryTransaction; -use dbschemix\pdo\internal\Transaction; -use dbschemix\pdo\internal\TransactionMysql; - /** * @api */ @@ -31,16 +27,4 @@ public function value(): string */ return strtolower($db); } - - /** - * @return class-string - */ - public function makeFactoryTransaction(): string - { - if ($this === self::PDO_MYSQL) { - return TransactionMysql::class; - } - - return Transaction::class; - } } diff --git a/src/internal/Connection.php b/src/internal/Connection.php index 008f34e..c1817f2 100644 --- a/src/internal/Connection.php +++ b/src/internal/Connection.php @@ -8,7 +8,6 @@ use PDO; use dbschemix\core\connection\ConnectionInterface; use dbschemix\core\connection\TransactionInterface; -use dbschemix\pdo\Type; /** * @psalm-internal dbschemix\pdo @@ -17,17 +16,19 @@ { use ThrowPrepareException; + /** + * @param class-string $factoryTransaction + */ public function __construct( private PDO $connection, - private Type $driverType, + private string $factoryTransaction, ) { } #[Override] public function beginTransaction(): TransactionInterface { - $class = $this->driverType->makeFactoryTransaction(); - return $class::begin($this->connection); + return ($this->factoryTransaction)::begin($this->connection); } #[Override] diff --git a/tests/workflow/StatementMysqlTest.php b/tests/workflow/StatementMysqlTest.php index 105fb3e..b607624 100644 --- a/tests/workflow/StatementMysqlTest.php +++ b/tests/workflow/StatementMysqlTest.php @@ -12,7 +12,7 @@ use Testo\Test; use dbschemix\core\connection\TransactionInterface; use dbschemix\pdo\internal\Connection; -use dbschemix\pdo\Type; +use dbschemix\pdo\internal\TransactionMysql; #[Test] final class StatementMysqlTest @@ -27,7 +27,7 @@ public function init(): void 'CREATE TABLE migration (name TEXT PRIMARY KEY, version INTEGER DEFAULT 0, atime TEXT)' ); - $this->transaction = (new Connection($pdo, Type::PDO_MYSQL))->beginTransaction(); + $this->transaction = (new Connection($pdo, TransactionMysql::class))->beginTransaction(); } /** From ab4200695f8fabc384c5c00f4559603412e71842 Mon Sep 17 00:00:00 2001 From: dimarik82 Date: Mon, 18 May 2026 12:48:52 +0300 Subject: [PATCH 2/2] infection ignore FactoryTransaction --- src/Driver.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Driver.php b/src/Driver.php index 9598ca5..55a54fe 100644 --- a/src/Driver.php +++ b/src/Driver.php @@ -123,6 +123,7 @@ private function makeConnection(): ConnectionInterface /** * Composition root: picks the transaction factory for the resolved dialect. * + * @infection-ignore-all * @return class-string */ private function makeFactoryTransaction(): string