Skip to content

Fluent Schema builder API#7

Merged
abnegate merged 10 commits intomainfrom
feat-fluent-schema-builder
Apr 30, 2026
Merged

Fluent Schema builder API#7
abnegate merged 10 commits intomainfrom
feat-fluent-schema-builder

Conversation

@abnegate
Copy link
Copy Markdown
Member

Summary

  • Refactor Schema from callback-style (\$schema->create(\$name, fn (Table) => ...)) to a fluent table builder (\$schema->table(\$name)->...->create()); column factories return a Column whose forwarders re-expose the table-level builder so chaining never breaks. Composite primary, table-level CHECK, and named enum columns are arg-dispatched off Column::primary/check/enum. ClickHouse gains explicit Table::orderBy(). No backwards compat. Removed string variants of addColumn/modifyColumn/addIndex types — must use ColumnType / IndexType enums.
  • Fix latent SQLite emit bug surfaced by e2e: INTEGER AUTOINCREMENT NOT NULL ... PRIMARY KEY (id) is invalid; SQLite needs INTEGER PRIMARY KEY AUTOINCREMENT inline. Old unit tests just compared strings and never hit the engine.
  • Add 64-test fluent builder unit file and 21-test integration file (every dialect, including the README ClickHouse round-trip with TTL and Nullable). Total: 5420 tests / 12811 assertions, lint clean, PHPStan max-level clean.
  • Regroup tests: new tests/Query/API/ folder for topic-grouped Query API tests (drop the redundant `Query` suffix); move `ConditionTest` to `Builder/` and `ExceptionTest` to `Exception/` to mirror src layout; rename misleading `AST/BuilderIntegrationTest` → `BuilderAstTest` and `Hook/Filter/FilterTest` → `TenantTest`.

Test plan

  • `./vendor/bin/phpunit tests/` — 5420 / 5420
  • `composer lint`
  • `composer check` (PHPStan max)
  • Live docker stack (MySQL 8.4, MariaDB 11, Postgres 16+pgvector, ClickHouse 24, Mongo 7) — integration suite green

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

📊 Coverage

Metric PR Baseline Δ
Lines 91.92% (6958/7570) 91.75% +0.16%
Methods 84.80% (1038/1224) 83.39% +1.41%
Classes 62.87% (105/167) 63.47% -0.60%

Full per-file breakdown in the job summary.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR replaces the callback-style schema API ($schema->create($name, fn(Table) => ...)) with a fluent builder ($schema->table($name)->...->create()), where Column and ForeignKey expose full forwarder sets so chains never break. It also fixes a latent SQLite bug where INTEGER AUTOINCREMENT NOT NULL ... PRIMARY KEY (id) was emitted instead of the required INTEGER PRIMARY KEY AUTOINCREMENT, and adds ClickHouse orderBy() support. The test suite grows to 5,420 tests with a new 64-test unit file and 21-test integration file verified against live databases.

Confidence Score: 5/5

Safe to merge; both findings are P2 edge cases that do not affect normal operation.

No P0 or P1 findings. The SQLite regex issue only triggers for column names containing backtick characters (extremely unusual), and the MongoDB ifExists omission preserves pre-existing behaviour. All previously flagged gaps (truncate/rename forwarders) are addressed.

src/Query/Schema/SQLite.php (regex edge case) and src/Query/Schema/MongoDB.php (ifExists semantics).

Important Files Changed

Filename Overview
src/Query/Schema/Column.php New fluent forwarder layer; all terminal methods (create, alter, drop, dropIfExists, truncate, rename) are present; arg-dispatch for primary/check/enum is clean.
src/Query/Schema/Table.php Fluent Table builder; all terminal calls delegate through requireSchema(); addForeignKey/foreignKey aliasing and its duplicate-registration caveat is documented.
src/Query/Schema/ForeignKey.php New file adding FK fluent builder with full forwarder coverage including ttl/truncate/rename terminal forwarders.
src/Query/Schema/SQLite.php SQLite AUTOINCREMENT fix is correct for the common case; preg_replace approach has a minor edge case with backtick-containing column names (regex uses [^`]+ which cannot match doubled backticks).
src/Query/Schema/MongoDB.php Refactored to compile* interface; compileDrop silently ignores $ifExists (pre-existing limitation, but the explicit parameter now misleads callers).
src/Query/Schema/ClickHouse.php Adds explicit orderBy support; ORDER BY falls back to primary keys then tuple() correctly; engine/TTL compilation unchanged.
src/Query/Schema.php Callback-style API replaced by fluent compile* methods; all dialects updated consistently.
src/Query/Schema/PostgreSQL.php compileAlter override updated to new Table-object API; index and FK handling unchanged.
tests/Query/Schema/FluentBuilderTest.php New 64-test unit file covering all dialects and the fluent builder API.
tests/Integration/Schema/FluentBuilderIntegrationTest.php New 21-test integration file verified against live docker stack per PR description.

Reviews (4): Last reviewed commit: "(refactor): rename $blueprint to $table ..." | Re-trigger Greptile

Comment thread src/Query/Schema/Column.php
Comment thread src/Query/Schema/Table.php
Comment thread src/Query/Schema/Column.php
@abnegate abnegate merged commit ec79613 into main Apr 30, 2026
7 checks passed
@abnegate abnegate deleted the feat-fluent-schema-builder branch April 30, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant