feat: make Doctrine DBAL optional via a Connection port (DBAL + PDO adapters) - #2
Merged
Conversation
The core engine now talks to PostgreSQL through a small Core\Database\Connection port instead of Doctrine DBAL directly, so the library runs on Doctrine DBAL or a bare PDO connection. Doctrine is optional and natively supported. - Core\Database: Connection (port), ParameterType (enum) and DatabaseException, which carries the SQLSTATE so missing-dependency handling stays backend-agnostic. - Dbal\DbalConnection: adapter over Doctrine DBAL — keeps primary/replica routing, middlewares and profiling. - Pdo\PdoConnection: adapter over a bare PDO handle (pdo_pgsql), with no extra Composer dependency. - MaterializedViewManager gains forDriver(Connection) and forPdo(\PDO); forConnection(DBAL\Connection) is unchanged and now wraps the connection in DbalConnection internally. - IdentifierQuoter is PostgreSQL-native (no DBAL platform) with byte-identical output. - doctrine/dbal moves from require to require-dev + suggest; the core requires only php and psr/log. Fully backward compatible: existing Doctrine code and the Symfony bundle need no changes — forConnection, MaterializedViewMigrationSql, RefreshTargetResolver and AsyncRefreshRequest are unchanged.
Th3Mouk
force-pushed
the
feat/optional-dbal-pdo
branch
from
June 13, 2026 12:05
2cc334a to
9e0338a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The core engine only needs to run statements, fetch rows and open a transaction — a tiny surface. Expressing that as a port frees
Corefrom any database library, so a project without Doctrine can drive PostgreSQL materialized views over a bare PDO connection, while Doctrine stays the recommended, natively-supported backend.What
Core\Databaseport —Connection(5 methods),ParameterType(enum),DatabaseException(carries the SQLSTATE, so42P01/3F000missing-dependency handling stays backend-agnostic). The whole synchronous engine runs on this;Coreno longer depends on Doctrine.Dbal\DbalConnection— wraps a Doctrine DBAL connection; keeps primary/replica routing, middlewares and profiling; mapsDBAL\Exception→DatabaseException.Pdo\PdoConnection— wraps a barePDOhandle (pdo_pgsql); no extra Composer dependency.forDriver(Connection)andforPdo(\PDO);forConnection(DBAL\Connection)is unchanged and now wraps the connection inDbalConnectioninternally.IdentifierQuoteris PostgreSQL-native (no DBAL platform), byte-identical output.composer.json—doctrine/dbalmovesrequire→require-dev+suggest; the core requires onlyphpandpsr/log.ext-pdo_pgsqlis suggested for the PDO path.Backward compatibility
Fully BC.
forConnection(),MaterializedViewMigrationSql,RefreshTargetResolver(still returns a DBALConnection) andAsyncRefreshRequestare unchanged, so existing Doctrine code and the Symfony bundle need no changes. The DBAL type names that remain inCore(theforConnectionconvenience and the async-refresh resolver contract) are never loaded on the PDO path.Validation
All CI gates green, plus the new PDO adapter exercised against a real PostgreSQL:
cs:checkstantest:unittest:pgPdoConnectionTestagainst a live PostgreSQL)New tests:
tests/Unit/Dbal/DbalConnectionTest(delegation,ParameterTypemapping, exception→SQLSTATE, primary/replica routing) andtests/Integration/Pdo/PdoConnectionTest(queries, typed params, transactional commit/rollback, SQLSTATE).Docs
README, getting-started, architecture, design-rationale (decision #1 reframed), a refresh/locking note, a new
docs/guide/connection-backends.md, and CHANGELOG[1.2.0].