Repository navigation
v0.1.1
Fixes two defects that made MySQL and PostgreSQL unusable. v0.1.0 worked on
SQLite only — upgrade before using either.
MySQL: the migration could not run
The schema used CREATE INDEX IF NOT EXISTS, which SQLite and PostgreSQL accept
and MySQL does not, so installation failed on the first index. Indexes are now
declared inside CREATE TABLE IF NOT EXISTS on MySQL, which is idempotent as a
whole, and as separate statements elsewhere. Identity columns are bounded at 150
characters on MySQL so the widest composite index stays well inside InnoDB's key
limit.
PostgreSQL: every read came back corrupt
Stored payloads are now base64-encoded. PHP encodes private and protected
property names with NUL bytes, and a PostgreSQL text column cannot hold those.
SQLite and MySQL only worked because they are permissive about it — the kind of
accident a single-driver test suite never reveals.
This changes the on-disk payload format. v0.1.0 could only write data on
SQLite; any such database has to be rebuilt.
Also
- PHP 8.5 static analysis:
$argvis read through$GLOBALSwith a guard, and
last-element access on a list usescount() - 1rather than
array_key_last(), which is typed as possibly returning null. - The shipped test trait migrates a shared database once and empties its tables
per test, instead of dropping and recreating seven tables each time.
Verification
Verified on PHP 8.4 and 8.5 against SQLite, MySQL 8.4 and PostgreSQL 17: 88 tests
on each driver, the deterministic simulator producing identical results
everywhere, and six concurrent writer processes producing a gapless commit log
with every replica acknowledged on both real databases — the concurrency property
the change feed documentation had listed as unproven.