Skip to content

Add structured fluent operations and explicit SQL preview - #175

Merged
jogibear9988 merged 7 commits into
masterfrom
codex/migrator-fluent-operations
Sep 22, 2026
Merged

jogibear9988 merged 7 commits into
masterfrom
codex/migrator-fluent-operations

Conversation

@jogibear9988

Copy link
Copy Markdown
Member

Builds on #174. Adds fluent authoring, operation records, automatic reversal, schema inspection, and offline SQL generation with planned-schema tracking. The legacy builder now creates complete tables. Unsupported preview operations fail explicitly and callbacks are never executed in structured preview. Includes execution-versus-preview SQLite tests and input snapshot tests. Further runner integration and documentation follow in the next PRs. Review and merge manually in stack order.

Copilot AI lite review requested due to automatic review settings September 22, 2026 12:42

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved correctness issues remain in fluent execution, provider dispatch, reversal, and SQL preview.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 6 Medium severity

Open (8)
What changed in this PR

Adds fluent migration operations, automatic reversal, schema inspection, and offline SQL preview with planned-schema tracking.

Changes:

  • Introduces structured fluent migration builders and operation records.
  • Completes legacy table construction and foreign-key handling.
  • Adds preview, reversal, execution, and schema-inspection tests.
File Summary
src/​Migrator/​Framework/​SchemaBuilder/​SchemaBuilder.cs Tracks columns for complete table creation.
src/​Migrator/​Framework/​SchemaBuilder/​AddTableExpression.cs Builds tables with collected columns and foreign keys.
src/​Migrator/​Framework/​Fluent/​SqlGenerationContext.cs Tracks planned schema and generates SQL literals.
src/​Migrator/​Framework/​Fluent/​Operations.cs Defines structured operations, reversal, execution, and preview.
src/​Migrator/​Framework/​Fluent/​MigrationBuilder.cs Provides fluent migration authoring APIs.
src/​Migrator/​Framework/​Fluent/​FluentMigration.cs Adds migration lifecycle and schema-inspection helpers.
src/​Migrator.Tests/​FluentOperationsTests.cs Tests execution, preview, reversal, snapshots, and legacy behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Migrator/Framework/Fluent/MigrationBuilder.cs Outdated
Comment thread src/Migrator/Framework/Fluent/Operations.cs Outdated
Comment thread src/Migrator/Framework/Fluent/Operations.cs Outdated
Comment thread src/Migrator/Framework/Fluent/Operations.cs Outdated
Comment thread src/Migrator/Framework/Fluent/SqlGenerationContext.cs Outdated
Comment thread src/Migrator/Framework/Fluent/SqlGenerationContext.cs Outdated
Comment thread src/Migrator/Framework/Fluent/SqlGenerationContext.cs
Comment thread src/Migrator/Framework/SchemaBuilder/AddTableExpression.cs Outdated
Copilot AI review requested due to automatic review settings September 22, 2026 12:54

Copilot AI 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.

Comment thread src/Migrator/Framework/Fluent/MigrationBuilder.cs Outdated
Comment thread src/Migrator/Framework/SchemaBuilder/AddTableExpression.cs
Comment thread src/Migrator/Framework/Fluent/Operations.cs

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved correctness and execution-versus-preview parity issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity

Open (3)
Resolved since last review (10)
Previously missed (5)

In code that hasn't changed since last review

Medium severity Resolve Execute.Script paths relative to the migration assembly

src/​Migrator/​Framework/​Fluent/​MigrationBuilder.cs:143

This reads a relative script path from the process working directory while the existing provider API resolves relative paths against CurrentMigration's assembly (TransformationProvider.ExecuteScript). Fluent migrations that call Execute.Script("...sql") will fail when launched from a different directory even though the equivalent provider operation works. Resolve relative paths with the same migration-aware rule or defer execution to the provider while defining the preview behavior.

Medium severity Include indexed columns in AddTable previews

src/​Migrator/​Framework/​Fluent/​Operations.cs:34

AddTable execution emits indexes requested through ColumnProperty.Indexed—inline via JoinColumnsAndIndexes or as standalone indexes in providers such as DB2/Firebird/Informix/Sybase—but this preview renders only ColumnSql. A previewed create table can therefore lack an index that execution creates. Emit the corresponding provider-specific index statements or reject indexed columns explicitly instead of silently omitting them.

Medium severity Create standalone indexes for indexed added columns

src/​Migrator/​Framework/​Fluent/​Operations.cs:39

The new column fluent API lets callers set ColumnProperty.Indexed, but this add-column path relies on provider mapping alone. DB2/Firebird/Informix/Sybase set SupportsIndex = false; their AddColumn implementations only emit the mapped column and do not create the required standalone index, so Create.Column(...).WithProperty(ColumnProperty.Indexed) silently loses the index. Add the standalone index after the column or reject this combination explicitly.

Medium severity Preserve generated names for reversible indexes

src/​Migrator/​Framework/​Fluent/​Operations.cs:113

When Index.Name is null, several providers synthesize a name and return it from AddIndex (for example IX_<table>_<columns>), but IndexOperation.Apply discards that return value and Reverse() stores null. Automatic reversal will then call RemoveIndex(table, null) and fail instead of dropping the index. Either capture/retain the generated name or require an explicit name for reversible index operations.

Medium severity Use Oracle timestamp expressions for DateTime literals

src/​Migrator/​Framework/​Fluent/​SqlGenerationContext.cs:33

This literal renders every DateTime as a bare quoted string. Oracle's dialect deliberately emits TO_TIMESTAMP(...) for DateTime defaults (src/Migrator/Providers/Impl/Oracle/OracleDialect.cs:138-142), so a previewed Oracle insert can depend on NLS settings or fail instead of inserting the same value as the parameterized execution path. Use the Oracle-specific dialect expression here.

Comment thread src/Migrator/Framework/Fluent/MigrationBuilder.cs Outdated
Comment thread src/Migrator/Framework/Fluent/Operations.cs
Copilot AI review requested due to automatic review settings September 22, 2026 13:18

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 13:35

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 13:52

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 13:59

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:06

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:13

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:22

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:25

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:27

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:37

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:51

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jogibear9988
jogibear9988 added this pull request to stack #179 September 22, 2026 15:50
Add Create/Alter/Delete/Rename/data/Execute/administration roots backed by operation records, immutable input snapshots, schema inspection and explicit provider callbacks. Build complete table definitions before execution, including the legacy builder adapter. Add automatic reversal for supported operations and reject unsupported preview/reversal rather than running callbacks. Track created and renamed tables during offline SQL generation. Validation: fluent snapshot, preview rejection, SQLite execution/preview equivalence and legacy-builder tests pass; unit and SQLite suites pass.
Reject insert-only modifiers on updates/deletes and reject raw delete predicates instead of silently deleting all rows. Dispatch complete table definitions through the provider's normal overload when no engine is specified. Retain legacy FK actions and defer conditional reversal until provider matching is known. Align preview identifier quoting with provider rules, render PostgreSQL82 booleans correctly and use Oracle RAW GUID conversion.

Validation: rebuilt solution; Unit 79 and SQLite 149 passed. Added regressions for invalid modifiers, inactive irreversible branches, preview identifiers/literals and actual legacy cascade-delete behavior. Addresses eight PR 175 review findings.
Map every normal API method family to fluent authoring, schema inspection or explicit context APIs, enforced by reflection coverage. Replace view/data-copy/update-from/database callbacks with typed operations and snapshot mutable definitions. Add schema query helpers and controlled command/connection callbacks. Reject structured SQL preview after raw SQL invalidates known schema and block administrative operations inside provider transactions.

Validation: rebuilt solution; Unit 84 and SQLite 154 passed before the final transaction guard. New tests cover persisted conditional inserts/updates/deletes, reader queries, pair snapshots and preview dependency rejection. Final guard and expanded provider coverage are checked on the next full build.
Delete.Row and Delete.Set now fail during authoring instead of silently ignoring row data and potentially deleting an entire table. DataOperation also rejects nonempty row fields when callers bypass the builder. Keep structured Where predicates as the delete input.

Validation: build, Unit 85 passed, SQLite 154 passed. Regression asserts no provider Delete call occurs for invalid modifiers. Addresses reviews 4072049125 and 4072049185.
Represent loaded scripts separately from raw SQL so execution uses provider batch handling and preview preserves client separators. Validate SQL Server GO syntax before preview output and invalidate schema knowledge after arbitrary scripts. Add a regression for file/resource operation capture and unchanged batch boundaries.

Validation: build, Unit 90 passed and SQLite 155 passed.
…operations

Validate the complete authored operation list before executing its first operation. Reversible and conditional wrappers propagate validation only for their active operations, so a database-administration expression cannot be discovered after earlier schema changes. Apply the same path to builders, fluent Up/Down and automatic reversal.

Validation: solution build, Unit 91 passed, SQLite 158 passed. Regression checks no earlier table is created and an inactive provider-specific operation does not block execution.
Verify one complete table definition reaches the provider, including type, primary key, size and default. Assert foreign-key ordering, direction and action, and verify existing-table columns use AddColumn without creating a table. Remove seven tests whose assertions were commented out.

Validation: solution build and Unit 88 passed; fewer test cases now cover meaningful observable behavior.
@jogibear9988
jogibear9988 force-pushed the codex/migrator-fluent-operations branch from 22b6132 to 1c10816 Compare September 22, 2026 18:43
Copilot AI review requested due to automatic review settings September 22, 2026 18:43

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Base automatically changed from codex/migrator-provider-corrections to master September 22, 2026 19:10
@jogibear9988
jogibear9988 merged commit 0acca02 into master Sep 22, 2026
12 checks passed
@jogibear9988
jogibear9988 deleted the codex/migrator-fluent-operations branch September 22, 2026 19:12
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.

2 participants