Skip to content

Harden database schema execution and SQLite rebuilds - #8

Closed
binaryfire wants to merge 12 commits into
0.4from
fix/database-schema-execution-safety
Closed

Harden database schema execution and SQLite rebuilds#8
binaryfire wants to merge 12 commits into
0.4from
fix/database-schema-execution-safety

Conversation

@binaryfire

@binaryfire binaryfire commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR fixes several correctness problems in schema execution and SQLite table rebuilds:

  • A schema statement returning false could be treated as successful.
  • Direct multi-statement PostgreSQL and SQLite Blueprint operations could leave partial changes behind.
  • SQLite rebuilds could silently change or lose index, constraint, collation, sort-order, and table-option behavior.
  • Nested foreign-key suppression did not preserve the physical connection's incoming state.
  • A failed session restoration could return an unsafe connection to the pool.
  • SQLite table cleanup truncated live database files, which is unsafe under WAL and invisible to other open connections.

The public Schema and Blueprint APIs remain Laravel-compatible. The changes are concentrated in schema execution, migrations, database cleanup, and pool release.

Schema execution

Blueprint execution now goes through the schema builder owned by the Blueprint's connection. Statements are compiled once, executed in order, and a false statement result throws with the failed SQL instead of reporting success.

Builder::executeBlueprint() is the shared execution boundary. Custom builders remain authoritative, and extension-defined compiler methods retain their existing ordered, unwrapped behavior.

PostgreSQL

Supported multi-statement Blueprint operations run in a transaction when the caller is not already in one. Existing transactions keep ownership of commit and rollback.

Online index operations remain unwrapped because PostgreSQL does not allow CREATE INDEX CONCURRENTLY inside a transaction. Mixed online and ordinary commands are neither split nor reordered.

SQLite

Framework-owned multi-statement Blueprints run in one guarded transaction. Rebuilds preserve the incoming foreign-key state and restore it even after failure.

SQLite ignores foreign-key toggles inside an active transaction. An empty-table rebuild can use a savepoint safely, while a populated-table rebuild with foreign keys enabled now fails before mutation rather than risking cascading data loss.

Pretend mode continues to compile and log SQL without changing physical session state.

Exact SQLite schema reconstruction

SQLite table alteration rebuilds now use authoritative schema metadata instead of inferring index behavior from names or comma-separated strings.

The rebuilt schema preserves:

  • physical index names and uniqueness;
  • expression and partial index definitions;
  • indexed-column collations and descending order;
  • explicit COLLATE BINARY overrides on non-binary columns;
  • unique and primary-key constraint behavior;
  • comma-bearing identifiers;
  • exact column projections during rename;
  • attached-schema index definitions;
  • WITHOUT ROWID and STRICT table options.

Simple indexes are regenerated through the normal grammar so their SQL stays canonical. Rich indexes retain their stored definition. Rebuilds fail before mutation when SQLite does not expose enough information to preserve behavior exactly, including unsafe same-Blueprint rename and legacy drop cases.

The stored table definition is also checked before rebuilding. Behavior-changing clauses that the grammar cannot reproduce are rejected rather than silently removed.

Two public introspection corrections are intentional:

  • mixed expression indexes no longer report a misleading subset of simple columns;
  • comma-bearing column names no longer appear as multiple indexed columns.

Foreign-key suppression and pooled sessions

Foreign-key suppression depth now belongs to the database connection, so nested scopes work across separate schema-builder instances.

SQLite, MySQL, and MariaDB read and restore the actual incoming constraint state. PostgreSQL keeps its transaction-only deferred-constraint behavior. Internal restoration uses the physical PDO directly so query callbacks cannot veto cleanup or add internal maintenance to query logs.

If restoration fails or a suppression scope leaks, the physical session is marked unknown. Normal pools replace that session before reuse. Shared in-memory SQLite fails clearly because replacing its only PDO would discard the database.

Test connection cleanup now discards unsafe pooled wrappers and clears all cached references before reporting cleanup failures.

SQLite cleanup and file refresh

dropAllTables() and dropAllViews() now use SQLite's catalog cleanup path for both in-memory and file-backed databases. This keeps the database inode and journal mode intact, updates every live connection, and avoids truncating a database with an active WAL.

Table cleanup preserves views, matching the behavior of the other supported drivers. A preserved view becomes usable again after its table is recreated.

Writable-schema mode is restored exactly. Modern SQLite reloads its schema cache with writable_schema=RESET; older versions use guarded cleanup and invalidation behavior.

refreshDatabaseFile() remains an explicit filesystem operation. The no-argument form now rejects active transactions, in-memory databases, and WAL mode, and resolves the canonical main database path for URI and relative-path connections.

Compatibility

  • Existing Schema and Blueprint entry points are unchanged.
  • New Blueprint index commands keep their existing generated SQL.
  • MySQL and MariaDB retain their native non-transactional DDL behavior.
  • PostgreSQL online index behavior remains explicitly non-transactional.
  • Low-level extension compilers are not forced into transaction rules they did not opt into.
  • Migration documentation now describes Hypervel's SQLite foreign-key default and the transaction limits for SQLite and PostgreSQL constraint toggles.

Testing

The full formatter, static analysis, framework, Testbench, and dogfood checks pass.

Coverage includes unit and real-database tests for SQLite, PostgreSQL, MySQL, and MariaDB, including rollback behavior, command ordering, index and constraint reconstruction, nested foreign-key suppression, pooled-session invalidation, writable-schema restoration, WAL handling, and database truncation.

Summary by CodeRabbit

  • New Features
    • Added safer schema blueprint execution with improved transaction handling across PostgreSQL and SQLite.
    • Added schema execution support through the public Schema API.
    • SQLite migrations now preserve indexes, constraints, collations, sort order, and table options more accurately.
  • Bug Fixes
    • Improved foreign-key restoration, nested operations, and pooled connection recovery.
    • Added safeguards for failed schema operations and unsafe SQLite refresh and cleanup.
  • Documentation
    • Updated SQLite foreign-key constraint guidance and configuration details.

Route Blueprint execution through the connection-owned schema builder, compile statements once, and fail loudly when a schema statement reports failure.

Make foreign-key suppression connection-owned and nest-safe, preserve the incoming MySQL and MariaDB state, bypass application callbacks for physical-session restoration, and invalidate leaked or failed session state before pooled reuse.

Reject pooled reconnects that remain unsafe, including shared in-memory SQLite sessions that cannot be replaced without losing their database, and cover execution order, failure handling, nesting, restoration, pool reset, and real database behavior.
Wrap supported multi-statement Blueprint operations in a database transaction while preserving caller-owned transactions, runtime grammar opt-outs, and framework command ordering.

Keep online index operations unwrapped because PostgreSQL forbids concurrent index creation inside a transaction, and leave extension-defined compilers on the existing ordered execution path.

Cover rollback, nested transaction ownership, every online index form, grammar extensions and overrides, raw compilation, and real PostgreSQL constraint-suppression nesting.
Execute framework-owned multi-statement Blueprints inside guarded SQLite transactions while preserving foreign-key state, caller transactions, pretend mode, command order, and extension compiler behavior.

Round-trip index identity and semantics through authoritative SQLite metadata, including expression and partial indexes, collations, descending order, constraint-backed indexes, comma-bearing identifiers, column renames, table options, and supported constraint clauses. Fail before mutation when SQLite metadata cannot reconstruct the original behavior safely.

Replace live database-file truncation with guarded catalog cleanup, preserve views during table wipes, reload schema state safely across SQLite versions, and make explicit database-file refresh reject active transactions, in-memory databases, and WAL mode.

Add focused unit and real-engine regressions for rollback, rebuild ordering, exact index and constraint behavior, stored definitions, foreign-key safety, writable-schema restoration, WAL and file handling, and every discovered data-integrity failure.
Teach the test database resolver to discard pooled wrappers whose physical session state became unknown, clear both cached connection entries, and complete all resets before rethrowing the first cleanup failure.

Add resolver regressions for discard and failure ordering, plus integration coverage proving DatabaseTruncation preserves an initially disabled SQLite foreign-key state.
Correct the stale claim about Hypervel SQLite defaults and document the transaction boundaries that govern SQLite constraint toggles and PostgreSQL constraint deferral.
Record the verified failure modes and final architecture for Blueprint execution, driver-specific transaction boundaries, exact SQLite index reconstruction, connection-owned foreign-key suppression, pooled-session invalidation, and safe SQLite catalog cleanup.

Capture the required integration coverage, compatibility guarantees, performance boundaries, public behavior disclosures, and completed review status so the implementation and future maintenance share one concise source of truth.
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR centralizes schema blueprint execution and adds driver-specific safety rules. It preserves SQLite schema metadata during rebuilds, tracks nested foreign-key suppression, invalidates unsafe pooled sessions, and adds broad unit and integration coverage.

Changes

Blueprint execution and suppression

Layer / File(s) Summary
Blueprint execution and suppression
src/database/src/Schema/Blueprint.php, src/database/src/Schema/Builder.php, src/database/src/Connection.php, src/support/src/Facades/Schema.php, tests/Database/DatabaseSchemaBuilderTest.php
Blueprints delegate execution to schema builders. Statements execute in order with failure checks. Foreign-key suppression supports nesting, pretend mode, restoration, and session invalidation.

PostgreSQL and MySQL boundaries

Layer / File(s) Summary
PostgreSQL and MySQL boundaries
src/database/src/Schema/PostgresBuilder.php, src/database/src/Schema/MySqlBuilder.php, tests/Database/DatabasePostgresBuilderTest.php, tests/Integration/Database/Postgres/*, tests/Integration/Database/MySql/*
PostgreSQL wraps eligible multi-statement blueprints in transactions and excludes online commands. MySQL table cleanup uses shared foreign-key suppression.

SQLite schema state and rebuilds

Layer / File(s) Summary
SQLite schema state and rebuilds
src/database/src/Query/Processors/SQLiteProcessor.php, src/database/src/Schema/BlueprintState.php, src/database/src/Schema/Grammars/SQLiteGrammar.php, src/database/src/Schema/SQLiteBuilder.php, tests/Integration/Database/Sqlite/*
SQLite preserves physical index names, SQL, collations, sort order, constraints, and table options. Rebuilds validate unsupported definitions and safely handle renames, removals, cleanup, and file refreshes.

Session state and pool recovery

Layer / File(s) Summary
Session state and pool recovery
src/database/src/Connection.php, src/database/src/Pool/PooledConnection.php, src/foundation/src/Testing/DatabaseConnectionResolver.php, tests/Database/DatabaseConnectionTest.php, tests/Integration/Database/PooledConnectionTest.php
Leaked suppression scopes and failed session operations mark connections unknown. Pool reset discards unsafe connections and fails closed for shared in-memory SQLite databases.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Blueprint
  participant SQLiteBuilder
  participant SQLiteProcessor
  participant SQLiteDatabase
  Blueprint->>SQLiteBuilder: executeBlueprint(Blueprint)
  SQLiteBuilder->>SQLiteDatabase: read table and index schema state
  SQLiteDatabase-->>SQLiteProcessor: columns and index metadata
  SQLiteProcessor-->>SQLiteBuilder: decoded schema-state metadata
  SQLiteBuilder->>SQLiteDatabase: execute guarded rebuild statements
  SQLiteDatabase-->>SQLiteBuilder: success or failure
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.96% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the PR's main changes to schema execution safety and SQLite rebuilds.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/database-schema-execution-safety

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR centralizes guarded Blueprint execution and strengthens SQLite schema reconstruction, cleanup, and pooled-session recovery.

  • Executes supported PostgreSQL and SQLite multi-statement Blueprints through engine-aware transaction boundaries.
  • Preserves SQLite index, constraint, collation, ordering, and table-option metadata during rebuilds.
  • Tracks nested foreign-key suppression on the owning connection and invalidates untrustworthy pooled sessions.
  • Replaces SQLite file truncation during schema cleanup with guarded catalog mutation while retaining an explicit file-refresh API.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains in the available follow-up review context.

No blocking failure remains.

Important Files Changed

Filename Overview
src/database/src/Schema/SQLiteBuilder.php Adds guarded transactional Blueprint execution, exact foreign-key restoration, catalog-based cleanup, and validated database-file refresh behavior.
src/database/src/Schema/Grammars/SQLiteGrammar.php Reconstructs SQLite tables and indexes from richer authoritative metadata while rejecting unsupported lossy rebuilds.
src/database/src/Schema/BlueprintState.php Tracks exact column, index, constraint, and stored table-definition state across ordered schema mutations.
src/database/src/Query/Processors/SQLiteProcessor.php Decodes lossless SQLite index metadata, including comma-bearing identifiers, collations, ordering, and reconstructibility.
src/database/src/Schema/Builder.php Introduces the shared guarded Blueprint execution boundary and connection-owned nested foreign-key suppression lifecycle.
src/database/src/Connection.php Tracks suppression depth and physical-session trust so failed restoration or leaked scopes can invalidate pooled sessions.
src/database/src/Pool/PooledConnection.php Prevents unknown physical sessions from being returned to the pool or reported as successfully reconnected.
src/database/src/Schema/PostgresBuilder.php Wraps eligible multi-statement Blueprint operations in transactions while preserving online-index restrictions and caller-owned transactions.
src/foundation/src/Testing/DatabaseConnectionResolver.php Discards unsafe cached pooled wrappers and completes cache cleanup before surfacing reset failures.

Reviews (2): Last reviewed commit: "docs(plans): record schema write-connect..." | Re-trigger Greptile

@binaryfire

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/boost/docs/migrations.md`:
- Around line 1663-1664: Update the warning in the migration documentation to
state that PostgreSQL defers only DEFERRABLE constraints within a transaction;
non-deferrable foreign keys remain enforced. Clarify that
withoutForeignKeyConstraints() is not a general PostgreSQL foreign-key disabling
operation while preserving the existing SQLite and transaction guidance.

In `@src/database/src/Schema/MySqlBuilder.php`:
- Around line 50-58: Update MySqlBuilder::foreignKeyConstraintsAreEnabled() to
call Connection::scalar() with $useReadPdo set to false, ensuring it reads
@@foreign_key_checks from the write session used by setForeignKeyConstraints().
Adjust the corresponding scalar expectations in DatabaseMySqlBuilderTest to
assert the false argument.

In `@tests/Database/DatabaseMySqlBuilderTest.php`:
- Around line 62-66: Update MySqlBuilder::dropAllTables() to propagate a false
result from the DROP TABLE statement by routing it through executeStatements()
or throwing on failure, while still restoring FOREIGN_KEY_CHECKS. Add a
regression test in DatabaseMySqlBuilderTest that makes statement() return false
and verifies the operation fails.

In `@tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php`:
- Around line 559-605: Add the #[RequiresDatabase('sqlite', '>=3.37.0')]
attribute to both testRebuildPreservesWithoutRowid() and
testRebuildPreservesStrictTables() so these SQLite 3.37+-specific tests are
skipped on older database versions.
- Around line 992-1022: Update
testSQLiteDoubleQuotedStringFallbackChangesUniqueIndexSemantics to detect the
SQLite SQLITE_DQS compile option via pragma_compile_options before creating the
indices, and skip or assert the expected unsupported behavior when DQS is
disabled. Preserve the existing fallback assertions only for builds that permit
double-quoted string literals, without changing unrelated tests.

In `@tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php`:
- Around line 302-330: Remove process-global chdir usage from both tests: in
tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php:302-330,
use the absolute database path for the PDO DSN while continuing to pass the
relative name to SQLiteConnection; in
tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php:360-393,
verify the temporary directory does not contain a :memory: file without changing
directories.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 01b2559d-d204-44ec-ab6c-efa3af07ae5c

📥 Commits

Reviewing files that changed from the base of the PR and between 5c41e9d and 5244798.

📒 Files selected for processing (30)
  • docs/plans/2026-08-09-0555-database-schema-execution-safety.md
  • src/boost/docs/migrations.md
  • src/database/src/Connection.php
  • src/database/src/Pool/PooledConnection.php
  • src/database/src/Query/Processors/SQLiteProcessor.php
  • src/database/src/Schema/Blueprint.php
  • src/database/src/Schema/BlueprintState.php
  • src/database/src/Schema/Builder.php
  • src/database/src/Schema/Grammars/SQLiteGrammar.php
  • src/database/src/Schema/MySqlBuilder.php
  • src/database/src/Schema/PostgresBuilder.php
  • src/database/src/Schema/SQLiteBuilder.php
  • src/foundation/src/Testing/DatabaseConnectionResolver.php
  • src/support/src/Facades/Schema.php
  • tests/Database/DatabaseConnectionTest.php
  • tests/Database/DatabaseMySqlBuilderTest.php
  • tests/Database/DatabasePostgresBuilderTest.php
  • tests/Database/DatabaseSQLiteBuilderTest.php
  • tests/Database/DatabaseSQLiteProcessorTest.php
  • tests/Database/DatabaseSQLiteSchemaGrammarTest.php
  • tests/Database/DatabaseSchemaBlueprintTest.php
  • tests/Database/DatabaseSchemaBuilderTest.php
  • tests/Foundation/Testing/DatabaseConnectionResolverTest.php
  • tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php
  • tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php
  • tests/Integration/Database/PooledConnectionTest.php
  • tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php
  • tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php
  • tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php
  • tests/Integration/Foundation/Testing/DatabaseTruncationTest.php

Comment thread src/boost/docs/migrations.md Outdated
Comment thread src/database/src/Schema/MySqlBuilder.php
Comment thread tests/Database/DatabaseMySqlBuilderTest.php
Comment thread tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php
Comment thread tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php
Read foreign-key constraint state from the write PDO so nested suppression restores the physical session that schema mutations use. MariaDB inherits the same correction through its MySQL builder base.\n\nRoute drop-all table and view statements through the guarded schema executor. Exact false statement results now surface as failures, while native exceptions, SQL ordering, and foreign-key restoration behavior remain unchanged.\n\nAdd regression coverage for write-session reads, failed cleanup statements, and restoration before error propagation.
Route Schema::hasTable(), SQLite pragma and rebuild probes, stored table definitions, and populated-table guards through the write PDO. This keeps mutation decisions consistent with the physical session and schema they govern when read/write connections differ.\n\nKeep SQLite compile-option discovery on the reader because it is process-wide library metadata, and document that deliberate exception.\n\nGuard PostgreSQL drop-all table, view, type, and domain statements against exact false results without changing their SQL or execution order. Add real split-PDO SQLite regressions and strict call-shape coverage across every supported builder.
Verify WITHOUT ROWID preservation through sqlite_master so the assertion works on the same SQLite versions as the schema introspection path. Keep the reachable STRICT version guard and remove the redundant older-version guard.\n\nReplace compile-option assumptions about double-quoted string fallback with a behavioral DDL probe that covers both indexed-column and partial-predicate positions. Unsupported builds skip only on SQLite's missing-column diagnostic, while all other failures remain visible.
Separate the SQLite and PostgreSQL transaction rules so the guidance cannot be read as applying the same way to both drivers.\n\nDocument that PostgreSQL defers only foreign keys created with deferrable(), only inside a transaction, while other constraints remain enforced.
Record that mutation-governing schema and session state belongs to the write connection, including Schema::hasTable() and SQLite rebuild state.\n\nAdd failed drop-all results and reader/writer divergence to the PR behavior and upstream-defect lists. Refresh the remaining-work wording without turning the plan into durable commit or push authority.
@binaryfire

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/plans/2026-08-09-0555-database-schema-execution-safety.md (1)

37-43: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Limit the SQLite atomicity claim to failures before commit.

Foreign-key restoration runs in finally after the DDL transaction completes. A restoration failure can therefore throw after the schema change commits. The connection can be marked unknown, but the committed DDL cannot be rolled back.

Line 43 currently overstates the guarantee. Limit it to statement and transaction failures before commit. Document that post-commit restoration failures can leave committed schema changes and require connection invalidation. Add a test for this case to prevent unsafe retries.

This follows the plan’s finally restoration flow and unknown-session handling.

Suggested wording
- All SQLite multi-statement Blueprint failures roll back completely.
+ SQLite statement and transaction failures roll back completely. A foreign-key restoration failure may occur after commit; it throws and invalidates the physical session but cannot undo committed DDL.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plans/2026-08-09-0555-database-schema-execution-safety.md` around lines
37 - 43, Revise the SQLite atomicity statement to guarantee rollback only for
statement or transaction failures occurring before commit. Document that
foreign-key restoration in the post-commit finally path may fail after schema
changes are committed, requiring connection invalidation and preventing safe
retries; add a test covering this restoration-failure case.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/plans/2026-08-09-0555-database-schema-execution-safety.md`:
- Around line 37-43: Revise the SQLite atomicity statement to guarantee rollback
only for statement or transaction failures occurring before commit. Document
that foreign-key restoration in the post-commit finally path may fail after
schema changes are committed, requiring connection invalidation and preventing
safe retries; add a test covering this restoration-failure case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b16ebb5-776b-4818-8039-6f70d8fd45cd

📥 Commits

Reviewing files that changed from the base of the PR and between 5244798 and 0afd65c.

📒 Files selected for processing (15)
  • docs/plans/2026-08-09-0555-database-schema-execution-safety.md
  • src/boost/docs/migrations.md
  • src/database/src/Schema/Builder.php
  • src/database/src/Schema/Grammars/SQLiteGrammar.php
  • src/database/src/Schema/MySqlBuilder.php
  • src/database/src/Schema/PostgresBuilder.php
  • src/database/src/Schema/SQLiteBuilder.php
  • tests/Database/DatabaseMariaDbSchemaBuilderTest.php
  • tests/Database/DatabaseMySQLSchemaBuilderTest.php
  • tests/Database/DatabaseMySqlBuilderTest.php
  • tests/Database/DatabasePostgresBuilderTest.php
  • tests/Database/DatabasePostgresSchemaBuilderTest.php
  • tests/Database/DatabaseSQLiteBuilderTest.php
  • tests/Database/DatabaseSQLiteSchemaGrammarTest.php
  • tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/boost/docs/migrations.md
  • tests/Database/DatabaseSQLiteSchemaGrammarTest.php
  • src/database/src/Schema/Grammars/SQLiteGrammar.php
  • src/database/src/Schema/SQLiteBuilder.php
  • tests/Database/DatabaseSQLiteBuilderTest.php

@binaryfire binaryfire closed this Aug 9, 2026
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