← All messages

The ORM was portable until PostgreSQL was asked

The ORM now runs its full suite against real MySQL and real PostgreSQL in CI, and gained a driver seam where the two genuinely differ.

Being database-agnostic has been the design since the model took its engine by injection rather than by hard-coding: static %model.DB => %MySQL in the app, and the ORM talks to whatever it is handed. Proving it is a separate job from designing it, and a suite running on SQLite proves portability to SQLite.

PostgreSQL is a good second opinion because it disagrees in useful places. lastInsertId() maps to lastval() there, which raises when the insert touched no sequence and takes the surrounding transaction with it, so the ORM gained a driver-overridable lastId() wrapped in a savepoint. And user, a perfectly ordinary column name, is a reserved word, so identifier quoting became something the driver decides rather than a formatting convention. Both are now seams where a future driver can differ.

The same week the CI grew a second axis nobody had noticed was missing: the standard PHP setup action only supplies a non-thread-safe build, so the thread-safe SAPI that worker mode actually runs on had never been tested. There is now a job that runs the whole suite inside the FrankenPHP image.

Engine 1.0. See the ORM chapter.

We use essential cookies to make this site work. With your permission we also use analytics to improve the site.