prooph/pdo-event-store
65.6
Adequate · 22 September 2026
7.6k
lines of production code
PHP
primary language
7
measurements over time
What this system is
This system is a PHP-based event sourcing library that provides a unified PDO-based persistence layer for storing and projecting events across MySQL, MariaDB, and PostgreSQL databases. It implements a standardized \PdoEventStore\ interface to handle event stream operations, concurrency control, and projection management with database-specific optimizations. The codebase includes comprehensive test coverage and utility classes for JSON handling and database-specific strategies, ensuring consistent behavior across all supported SQL backends.
How it got here
2016 — PDO event store implementation
12 changes.
This period focused on refactoring the event store to support multiple SQL databases via a unified PDO interface. The work involved creating new database schemas, implementing a consistent factory pattern for MySQL, MariaDB, and PostgreSQL, and adding comprehensive test coverage for the new persistence strategies.
2017–2019 — Database-specific implementation and testing
8 changes.
This period focused on implementing database-specific features and utilities, including gap detection for projections, write lock strategies, and helper classes for JSON and PostgreSQL. The work was accompanied by comprehensive test coverage and SQL schema definitions for MariaDB, MySQL, and PostgreSQL to support these new capabilities.
Features
Add PostgreSQL schema for event streams and projections
New SQL scripts define the database schema for PostgreSQL, creating tables for event streams and projections. The event\_streams table includes a BIGSERIAL primary key, stream name, metadata, and category fields, while the projections table stores projection name, position, state, and status. These changes support the implementation of PostgreSQL-specific data storage for event sourcing and projections.
scripts/postgres · high confidence
Add database-specific write lock strategies
Introduced new write lock implementations for MariaDB, MySQL, PostgreSQL, and a no-op strategy. The MariaDB and MySQL strategies use the database's native locking functions (GET\_LOCK/RELEASE\_LOCK) with specific error handling for deadlocks. The PostgreSQL strategy uses advisory locks (pg\_advisory\_lock/unlock). The NoLockStrategy provides a non-blocking alternative. These classes implement the WriteLockStrategy interface for their respective database systems.
src/WriteLockStrategy · high confidence
Add gap detection for projections
Projections now support gap detection to handle scenarios where events are skipped due to transaction visibility issues or rollbacks. A new \GapDetector\ interface and \GapDetection\ implementation allow projectors to detect gaps in the event stream and automatically retry to fill them. This feature is available for both \PdoEventStoreProjector\ and \PdoEventStoreReadModelProjector\ via the \gap\_detection\ option.
src/Projection · high confidence
Add multi-database test configuration and CI infrastructure
The project now supports running tests against MariaDB, MySQL, and PostgreSQL. This is enabled by new \phpunit.\*.xml\ configuration files that isolate database-specific test suites, a \docker-compose-tests.yml\ file to spin up the required database containers, and a \Dockerfile\ to build the test environment. The legacy \.travis.yml\ and \.php\_cs\ files have been removed in favor of this modernized testing setup.
(repo-wide) · high confidence
Added MariaDB schema definitions for event streams and projections
New SQL migration scripts have been added to the MariaDB initialization process, defining the \event\_streams\ and \projections\ tables. These scripts establish the database schema required for storing event stream data and projection states, including specific constraints for JSON validation and unique indexing.
scripts/mariadb · high confidence
Adds JSON and PostgreSQL helper utilities
A new Json utility class has been added to provide consistent JSON encoding and decoding with specific flags (JSON\_UNESCAPED\_UNICODE, JSON\_UNESCAPED\_SLASHES, JSON\_PRESERVE\_ZERO\_FRACTION) and error handling. Additionally, a PostgresHelper trait was introduced to simplify quoting identifiers and extracting schema names from fully qualified table names, improving how the library handles PostgreSQL table references.
src/Util · high confidence
New MariaDB persistence strategies with indexed metadata support
Added MariaDB persistence strategies (Aggregate, Simple, and Single Stream) that support indexed metadata fields for efficient querying. The Single Stream strategy includes generated columns and indexes for aggregate\_id, aggregate\_type, and aggregate\_version, enabling faster lookups by aggregate. All MariaDB strategies use utf8mb4 character set and enforce JSON validity via CHECK constraints.
src/PersistenceStrategy · high confidence
Behavioural changes
Migrate event store implementations to a unified PdoEventStore interface
The MySQL and MariaDB event store implementations have been refactored to implement the new \PdoEventStore\ interface, which extends \EventStore\. This change standardizes the API across database drivers, replacing the previous \TableNameGeneratorStrategy\ and adapter-specific interfaces with a common persistence strategy pattern. Users will now interact with a consistent \PdoEventStore\ contract for both MySQL and MariaDB, simplifying the integration of different SQL-based event stores.
src · high confidence
MySQL schema updates for event streams and projections
Added MySQL database schema files for the event store, specifically creating the \event\_streams\ and \projections\ tables. The \event\_streams\ table uses a 64-bit integer (\BIGINT\) for the primary key, and the \projections\ table includes columns for name, position, state, status, and lock information.
scripts/mysql · medium confidence
New exception classes and factory for PDO event store
The \src/Exception\ directory now contains a dedicated set of exception classes for the PDO event store implementation. This includes a \ConcurrencyExceptionFactory\ for creating specific concurrency errors, as well as new exception types for \InvalidArgumentException\, \JsonException\, \ProjectionNotCreatedException\, and \RuntimeException\. Additionally, the codebase has been reorganized by renaming \Sha1TableNameGeneratorStrategy\ to \ExtensionNotLoaded\ and \IndexingStrategy\ to \PdoEventStoreException\, moving them into the exception namespace to better separate error handling logic.
src/Exception · medium confidence
Refactored container factories for event stores and projection managers
The container layer has been restructured to use a new \AbstractEventStoreFactory\ and \AbstractProjectionManagerFactory\ base classes, replacing the previous \MySQLEventStoreAdapterFactory\. This change introduces a more consistent factory pattern for creating MySQL, MariaDB, and PostgreSQL event stores and their corresponding projection managers. The \PdoConnectionFactory\ was added to handle PDO connection creation with specific DSN building logic for MySQL and PostgreSQL. Users will now configure event stores and projection managers through these new factory classes, which support plugin and metadata enricher injection, and allow for configurable write lock strategies.
src/Container · high confidence
Removed MySQL-specific event streams table script
The SQL script for the MySQL 'event\_streams' table has been removed from the repository. This change eliminates the MySQL-specific schema definition, likely as part of a broader effort to improve PostgreSQL compatibility or to consolidate database logic.
scripts · medium confidence
Test coverage
Add Pdo event store tests for MariaDB, MySQL, and Postgres; Added Postgres persistence strategy tests; Added container factory tests for Pdo event store and projection managers; Added custom persistence strategy test assets for MariaDB, MySQL, and PostgreSQL; Added test coverage for Pdo projections, queries, and read models; Added test coverage for write lock strategies; Added test fixtures for event store and projection tables.
Dependencies
Upgrade to PHP 8.1+ and modernize dependencies
The package now requires PHP 8.1 or higher and updates the Prooph Event Store dependency to version ^v7.12.3. Development dependencies have been modernized, including an upgrade to PHPUnit 10 and the introduction of prophecy-phpunit, while the namespace has been updated from Prooph\\EventStore\\Adapter\\MongoDb to Prooph\\EventStore\\Pdo to reflect the PDO-based implementation.
(dependencies) · medium confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 58 → 66 (+8.0)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 82 → 88 (+6.2)
- Architecture 86 → 90 (+4.8)
- Maturity 55 → 55 (-0.1)
- Readiness 48 → 60 (+11.9)
- Security 71 → 97 (+25.8)
Resolved (55)
- Change coupling: MariaDbProjectionManager.php ↔ MySqlProjectionManager.php (src/Projection/MariaDbProjectionManager.php)
- Change coupling: MySqlProjectionManager.php ↔ PostgresProjectionManager.php (src/Projection/MySqlProjectionManager.php)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- Duplicated block (10 lines × 3) (src/Projection/MariaDbProjectionManager.php)
- Duplicated block (11 lines × 2) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (11 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (11 lines × 3) (src/PersistenceStrategy/MariaDbAggregateStreamStrategy.php)
- Duplicated block (11 lines × 3) (src/Projection/MariaDbProjectionManager.php)
- Duplicated block (12 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (13 lines × 2) (src/MariaDbEventStore.php)
- Duplicated block (13 lines × 2) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (13 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (13 lines × 3) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (13 lines × 6) (src/Projection/MariaDbProjectionManager.php)
- Duplicated block (14 lines × 2) (src/MariaDbEventStore.php)
- Duplicated block (14 lines × 3) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (14 lines × 3) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (15 lines × 2) (src/MariaDbEventStore.php)
- Duplicated block (15 lines × 2) (src/MariaDbEventStore.php)
- …and 35 more
New (133)
- Change coupling clique: MariaDbProjectionManager.php, MySqlProjectionManager.php, PostgresProjectionManager.php (src/Projection/MariaDbProjectionManager.php)
- ClassTooLong: MariaDbEventStore (src/MariaDbEventStore.php)
- ClassTooLong: MySqlEventStore (src/MySqlEventStore.php)
- ClassTooLong: PdoEventStoreProjector (src/Projection/PdoEventStoreProjector.php)
- ClassTooLong: PdoEventStoreReadModelProjector (src/Projection/PdoEventStoreReadModelProjector.php)
- ClassTooLong: PostgresEventStore (src/PostgresEventStore.php)
- Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
- Duplicated block (10 lines × 2) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (10 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (10 lines × 6) (src/MariaDbEventStore.php)
- Duplicated block (11 lines × 5) (src/MariaDbEventStore.php)
- Duplicated block (12 lines × 2) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (12 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (12 lines × 3) (src/Projection/MariaDbProjectionManager.php)
- Duplicated block (13 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (14 lines × 2) (src/Projection/PdoEventStoreProjector.php)
- Duplicated block (14 lines × 3) (src/PersistenceStrategy/MariaDbAggregateStreamStrategy.php)
- Duplicated block (15 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (15 lines × 3) (src/MariaDbEventStore.php)
- Duplicated block (15 lines × 3) (src/Projection/MariaDbProjectionManager.php)
- …and 113 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
prooph/pdo-event-store was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit b58ab0621d623de0f8f4569ac816ac093cd65047 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.