Skip to content
CAI
Software that uses CAICheck a score

prooph/pdo-event-store

65.6

Adequate · 22 September 2026

7.6k

lines of production code

PHP

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

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.