diff --git a/README.md b/README.md
index 34678016..5aefb5dd 100644
--- a/README.md
+++ b/README.md
@@ -31,15 +31,17 @@ DotNetProjects.Migrator is a fork of [Migrator.NET](https://github.com/migratord
## Why use it?
-- **Imperative or fluent C# migrations.** Use `Migration.Up/Down` or v13’s `FluentMigration.BuildUp/BuildDown`; review both like application code.
+- **Imperative or fluent C# migrations.** Use `Migration.Up/Down` or `FluentMigration.BuildUp/BuildDown`; review both like application code.
- **No ORM dependency.** Use it alongside EF, Dapper, another data layer, or plain ADO.NET.
- **Database transformation API.** Work with tables, columns, keys, indexes and data, with raw SQL available for provider-specific operations.
- **Version tracking.** Apply pending migrations or target a specific version using database-backed history.
- **Scoped histories.** Track multiple modules in one database when each runner is given the appropriate migration set.
- **Bring your database driver.** The library does not directly reference database-driver packages; supply an ADO.NET connection or configure the driver factory.
-- **SQLite schema handling.** This fork includes schema inspection and table-recreation logic for operations SQLite cannot perform directly.
+- **SQLite schema changes without an ORM model.** Automatically rebuild existing tables to change column types, defaults and nullability or add/remove primary, foreign, unique and check constraints. Migrator reads the live schema and copies existing rows for supported changes.
-The source upgrade adds a structured fluent API, runner filtering/lifecycle options, SQL-preview subset, native locking, a CLI project and optional Microsoft DI/logging integration. These changes are merged in source and **are not a released NuGet feature claim**. See the [runner and fluent guide](docs/runner-guide.md) and [detailed framework comparison](docs/migration-framework-comparison.md). EF-style model scaffolding and migration-content checksums remain outside the implementation.
+Runner options include tags, profiles, ordered maintenance, transaction modes, planning, a SQL-preview subset and native locking. Use the CLI or optional Microsoft DI/logging integration in your own host. See the [runner and fluent guide](docs/runner-guide.md) and [detailed framework comparison](docs/migration-framework-comparison.md). EF-style model scaffolding and migration-content checksums remain outside the implementation.
+
+**SQLite is a particular strength:** FluentMigrator requires manual reconstruction for general column alterations and adding/removing foreign keys on existing tables; DbUp and Evolve leave reconstruction to your scripts. EF Core also rebuilds SQLite tables, using model metadata. Migrator supplies this automation from the live database without an ORM model. See the sourced [SQLite operation comparison and preservation limits](docs/migration-framework-comparison.md#sqlite-emulation-comparison).
## Installation and requirements
@@ -59,7 +61,7 @@ Building the `.slnx` solution requires an SDK that understands that format, such
## Quick start
-This example targets **unreleased v13 source**. Clone/check out this repository before running these commands from the repository root. For published 12.1, follow its version-specific API; see the [migration guide](docs/migration-guide-12.1-to-13.md).
+This example uses the current repository API. Clone/check out this repository before running these commands from the repository root. When updating older migrations, see the [migration guide](docs/migration-guide-12.1-to-13.md).
### 1. Create a migration host
@@ -153,7 +155,7 @@ Keep applied migration classes in source control. Change the schema with a new m
With the runner above, `migrator.MigrateTo(0)` reverses all applied migrations in its set. In this example that drops `Users`, including its data. A `Down()` implementation is a reverse schema operation, not a backup restore.
-By default, migration execution starts a transaction for each migration and attempts rollback on failure. V13 also offers `None` and `WholeSession` transaction modes; whole-session support is limited to SQLite, PostgreSQL and SQL Server. Actual atomicity depends on the database, driver and operation; some databases implicitly commit DDL. `AfterUp()` and `AfterDown()` run **after commit**, so a failure in those hooks cannot undo the committed migration.
+By default, migration execution starts a transaction for each migration and attempts rollback on failure. `None` and `WholeSession` transaction modes are also available; whole-session support is limited to SQLite, PostgreSQL and SQL Server. Actual atomicity depends on the database, driver and operation; some databases implicitly commit DDL. `AfterUp()` and `AfterDown()` run **after commit** (after the session commit in whole-session mode), so a failure in those hooks cannot undo the committed migration.
For deployment, run a dedicated migration host before the application needs the new schema. Coordinate it so competing instances do not migrate the same database concurrently. Review and test both directions against your actual database engine.
@@ -183,16 +185,18 @@ billingMigrator.MigrateToLastVersion();
Important details:
-- In the upgrade source, explicit scopes filter discovery; unscoped migrations inherit the runner scope. A scope partitions history, not database objects.
+- Explicit scopes filter discovery; unscoped migrations inherit the runner scope. A scope partitions history, not database objects.
- Leave `MigrationAttribute.Scope` unset to inherit the provider scope; set it to select a migration for one specific scope.
- Duplicate versions are checked within the effective scope. Duplicate versions in distinct explicit scopes are independent.
- Scopes do not isolate tables or data. Module migrations still need compatible table names and coordinated schema ownership.
+Consolidated baseline migrations can record included versions with `Database.MigrationApplied(version, scope)`. The runner rechecks scope history before each step, skipping versions already covered by that baseline. See [consolidated history](docs/runner-guide.md#consolidated-history).
+
See [ProviderFactory](src/Migrator/ProviderFactory.cs), [MigrationLoader](src/Migrator/MigrationLoader.cs) and [history implementation](src/Migrator/Providers/TransformationProvider.cs).
## Fluent API and deployment tooling
-For v13 source, replace the quick start’s `CreateUsers.cs` with this fluent equivalent; keep the same runner. Use one version-1 class, not both examples together.
+Replace the quick start’s `CreateUsers.cs` with this fluent equivalent; keep the same runner. Use one version-1 class, not both examples together.
```csharp
using DotNetProjects.Migrator.Framework;
@@ -224,7 +228,7 @@ Run the [compiled fluent example](examples/FluentQuickStart/Program.cs):
dotnet run --project examples/FluentQuickStart
```
-The example creates a complete table definition, previews it without changing history, runs a whole-session migration, then verifies automatic reversal. The [runner guide](docs/runner-guide.md) covers CLI commands, tags/profiles, maintenance, transactions, optional DI/logging, locks and preview limitations. Build the source packages locally to try the new tooling; no NuGet publication accompanies these PRs.
+The example creates a complete table definition, previews it without changing history, runs a whole-session migration, then verifies automatic reversal. The [runner guide](docs/runner-guide.md) covers CLI commands, tags/profiles, maintenance, transactions, optional DI/logging, locks and preview limitations, including local tool installation.
## Schema and data operations
@@ -253,6 +257,34 @@ public override void Down()
Provider implementations determine which operations are available and how they map to SQL. Use `Database.ExecuteNonQuery(...)` for custom SQL and keep dialect-specific statements explicit. The source also includes the [MigrationBuilder fluent API](src/Migrator/Framework/Fluent/MigrationBuilder.cs).
+### Explicit constraints, SQL defaults and collations
+
+Columns describe type, size, precision, nullability and identity. Define primary, unique, foreign-key and check constraints as named table objects; inspect them with `GetTableConstraints`. Changing a column preserves explicit constraints. `RawSql.Insert` marks a trusted SQL default expression, while `Collation` provides semantic presets and installed provider names.
+
+```csharp
+new Column("Id", DbType.String, 27) { DefaultValue = RawSql.Insert("ksuid_new()") };
+builder.Create.Table("Events").WithColumn("Id").AsString(27)
+ .WithDefaultValue(RawSql.Insert("ksuid_new()"));
+
+new Column("Name", DbType.String, 100) { Collation = Collation.AsciiIgnoreCase };
+builder.Create.Table("Names").WithColumn("Name").AsString(100)
+ .WithCollation(Collation.AsciiIgnoreCase);
+```
+
+SQL expressions are trusted migration code and must exist on the target database.
+Ordinary string defaults remain quoted literals. Semantic collations have explicit
+provider limits; SQLite's `AsciiIgnoreCase` never substitutes for Unicode folding.
+Use `Collation.Named("provider_name")` for a specific language or installed collation.
+See the [mapping and migration guide](docs/migration-guide-12.1-to-13.md#explicit-sql-defaults-and-semantic-collations).
+
+### SQLite reconstruction and data types
+
+Supported rebuilds retain mapped data, named/composite keys, declared column collations, supported indexes and triggers, and the AUTOINCREMENT high-water mark. Generated columns, `STRICT`, `WITHOUT ROWID` and indexes with explicit collations are rejected for reconstruction; hidden rowid values are not preserved. Foreign keys retain separate update/delete actions; unsupported `MATCH FULL`/`PARTIAL` requests fail explicitly. See the [SQLite preservation matrix](docs/migration-framework-comparison.md#what-survives-reconstructionand-what-is-not-guaranteed).
+
+CLR `Guid` defaults use the same blob representation as inserted GUID parameters. Existing text GUID defaults remain unchanged during unrelated rebuilds; converting mixed storage requires an explicit data migration. SQLite's `AsciiIgnoreCase` preset selects ASCII-only `NOCASE`; Unicode case-insensitive requests need a suitable custom collation, registered on the connection and selected by name.
+
+Use `TimeOnly` for time-of-day values and `TimeSpan` for intervals. Storage and precision depend on the provider. The [runner guide](docs/runner-guide.md#time-of-day-and-intervals) and [data-type support and boundary tests](docs/data-type-boundary-tests.md) describe unsigned ranges, large text/binary, decimal precision and engine-specific limits.
+
## Database providers
The [provider factory](src/Migrator/ProviderFactory.cs) contains these database families:
@@ -269,14 +301,14 @@ The [provider factory](src/Migrator/ProviderFactory.cs) contains these database
| IBM Informix | `IBM_Informix` |
| Firebird | `Firebird` |
| Ingres | `Ingres` |
-| SAP HANA (v13 source) | `Hana` |
+| SAP HANA | `Hana` |
| Sybase | `Sybase` |
This is an inventory of dialects present in source, **not a guarantee that every server version, driver or operation is supported**. Some entries are legacy variants. Verify the combination you deploy against the [provider implementations](src/Migrator/Providers/Impl) and [provider tests](src/Migrator.Tests/Providers).
## Comparison with other .NET frameworks
-Reviewed **22 September 2026**. Migrator's column describes this repository; the alternatives summarize their official documentation. These are workflow differences, not performance benchmarks or a ranking.
+Reviewed **23 September 2026**. Migrator's column describes this repository; the alternatives summarize their official documentation. These are workflow differences, not performance benchmarks or a ranking.
| Capability | Migrator.NET (this fork) | FluentMigrator | EF Core | DbUp | Evolve |
| ---------------------------- | --------------------------------- | -------------------------------------------- | ------------------------------------ | -------------------------- | --------------------------------- |
@@ -285,13 +317,14 @@ Reviewed **22 September 2026**. Migrator's column describes this repository; the
| Model-difference scaffolding | No built-in generator | Hand-authored | Yes, with model snapshots | Hand-authored | Hand-authored |
| Downgrade applied migrations | Authored `Down()` / `BuildDown()`; supported automatic reversal | `Down()`; supported auto-reverse expressions | Generated/editable `Down()` | Custom undo or forward fix | Forward fix; no Down command |
| Separate histories | Scope + selected assembly/types | Custom version table + filtering | Contexts + custom history table | Journals + script filters | Metadata table/schema + locations |
-| Execution | Library / source CLI (unreleased) | Library + CLI | CLI, scripts, bundles, runtime | Library / custom host | Library, .NET tool, CLI |
+| Execution | Library / CLI | Library + CLI | CLI, scripts, bundles, runtime | Library / custom host | Library, .NET tool, CLI |
| Recurring work | Ordered maintenance / named profiles | Maintenance migrations / profiles | Seeding APIs (EF 9+) | `RunAlways` scripts | Checksum-based repeatable SQL |
+| Automatic SQLite reconstruction | Live-schema rebuilds; no ORM model | Manual for general column/FK alterations | Rebuilds for model-represented artifacts | Author scripts | Author scripts |
All five can execute raw SQL. Transaction support depends on database capabilities: Migrator defaults to per-migration transactions, with none or whole-session options (SQLite, PostgreSQL and SQL Server); DbUp makes transactions opt-in; the others have configurable transaction behavior. Reversing a completed migration is different from rolling back a failed transaction. Evolve's checksum-based repeatables also differ from always-run scripts or lifecycle hooks.
-- Choose **Migrator** for imperative or fluent C# schema operations, scoped history, tags/profiles and a source CLI or your own host.
-- **FluentMigrator** also offers fluent C# authoring, tags and profiles. Compare its published runner packages and provider behavior with Migrator’s v13 source tooling; fluent syntax alone is not a reason to switch.
+- Choose **Migrator** for imperative or fluent C# schema operations, scoped history, tags/profiles and the CLI or your own host.
+- **FluentMigrator** also offers fluent C# authoring, tags and profiles. Compare provider operations, especially automatic SQLite reconstruction, and deployment requirements.
- Consider **EF Core migrations** when your EF model drives the schema and you want scaffolding and deployment artifacts.
- Consider **DbUp** for a SQL-oriented runner composed in .NET, or **Evolve** for convention-based SQL with checksum validation and repeatables.
@@ -345,30 +378,3 @@ This project continues the original [Migrator.NET](https://github.com/migratordo
## License
The package declares **Mozilla Public License 1.1 (MPL-1.1)** in its [project metadata](src/Migrator/DotNetProjects.Migrator.csproj). See the [license text](https://www.mozilla.org/en-US/MPL/1.1/) and source-file notices.
-
-### Version 13 source changes
-
-The v13 source preview separates columns from named table constraints and removes the old column flags and duplicate fluent builder. See the [12.1-to-13 migration guide](docs/migration-guide-12.1-to-13.md) before recompiling migrations. These source features are not claims about the published 12.1 NuGet package.
-
-
-### SQL expressions and collations in v13
-
-```csharp
-new Column("Id", DbType.String, 27) { DefaultValue = RawSql.Insert("ksuid_new()") };
-builder.Create.Table("Events").WithColumn("Id").AsString(27)
- .WithDefaultValue(RawSql.Insert("ksuid_new()"));
-
-new Column("Name", DbType.String, 100) { Collation = Collation.CaseInsensitive };
-builder.Create.Table("Names").WithColumn("Name").AsString(100)
- .WithCollation(Collation.CaseInsensitive);
-```
-
-SQL expressions are trusted migration code and must exist on the target database.
-Ordinary string defaults remain quoted literals. Semantic collations have explicit
-provider limits; SQLite's `AsciiIgnoreCase` never substitutes for Unicode folding.
-Use `Collation.Named("provider_name")` for a specific language or installed collation.
-See the [mapping and migration guide](docs/migration-guide-12.1-to-13.md#explicit-sql-defaults-and-semantic-collations).
-
-Additional engines are admitted only with passing real-database CI.
-[SAP HANA provider scope, CI evidence and deferred engine requirements](docs/additional-database-qualification.md)
-cover the current FluentMigrator gaps without claiming untested support.
diff --git a/docs/README.md b/docs/README.md
index f620b7b4..cac5786f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -24,9 +24,9 @@ All site assets use relative URLs, so the repository subpath works without a cus
## Keep the comparison accurate
-The comparison distinguishes source capabilities from guarantees about released packages or database compatibility. Update the review date and source links together when reviewing it. Avoid equating transaction rollback with reversing completed migrations, treating a provider enum as a support guarantee, or assuming scopes isolate physical tables. The v13 runner filters explicitly scoped migrations and lets unscoped migrations inherit its effective scope.
+The comparison distinguishes source capabilities from guarantees about released packages or database compatibility. Update the review date and source links together when reviewing it. Avoid equating transaction rollback with reversing completed migrations, treating a provider enum as a support guarantee, or assuming scopes isolate physical tables. The runner filters explicitly scoped migrations and lets unscoped migrations inherit its effective scope.
-The quick start targets the unreleased v13 source's .NET 9 API and references the source project. Check the selected NuGet release's target frameworks. The SQLite driver version matches the repository test dependency. Validate authoring and runner snippets together when changing them.
+The quick start targets the current repository’s .NET 9 API and references the source project. Check the selected NuGet release's target frameworks. The SQLite driver version matches the repository test dependency. Validate authoring and runner snippets together when changing them.
## Status badges and test counts
@@ -41,3 +41,5 @@ The renderer only changes the uploaded Pages artifact; it does not commit genera
Keep the homepage, README summary and detailed comparison aligned. The fluent homepage
example replaces the imperative version-1 class and uses the same quick-start runner.
+
+Present capabilities as ordinary features, without version-specific preview banners. Keep version numbers in the upgrade guide where they explain compatibility changes. Highlight automatic live-schema SQLite reconstruction in the homepage and README, distinguishing it from EF Core's model-based rebuilds and SQL runners' author-written scripts. Retain preservation limits and links to the operation matrix.
diff --git a/docs/additional-database-qualification.md b/docs/additional-database-qualification.md
index 403d02b1..cf733ec8 100644
--- a/docs/additional-database-qualification.md
+++ b/docs/additional-database-qualification.md
@@ -7,7 +7,7 @@ This is an implementation gate, not a claim of released provider support.
| Additional engine | Real-engine GitHub Actions route | Current disposition |
| --- | --- | --- |
-| SAP HANA | Official HANA Express Linux container and SAP's .NET driver, disposable schema | Implemented in the v13 source stack with a mandatory actual-engine matrix job; require green PR checks before merge |
+| SAP HANA | Official HANA Express Linux container and SAP's .NET driver, disposable schema | Implemented with a mandatory actual-engine matrix job; require green PR checks before merge |
| Amazon Redshift | AWS test warehouse/serverless endpoint with CI credentials, network access and resource cleanup | No configured test infrastructure; defer provider |
| Snowflake | Snowflake test account, warehouse, credentials and disposable database/schema | No configured test infrastructure; defer provider |
| Db2 for IBM i | IBM i endpoint on Power infrastructure and compatible .NET/ODBC driver | No configured test infrastructure; defer provider |
diff --git a/docs/fluent-operation-coverage.md b/docs/fluent-operation-coverage.md
index ebc87b33..f81686a3 100644
--- a/docs/fluent-operation-coverage.md
+++ b/docs/fluent-operation-coverage.md
@@ -11,7 +11,7 @@ The machine-readable [inventory](fluent-operation-coverage.json) maps every name
| Drop/rename operations | `Delete` / `Rename` | SQLite schema tests, reversal tests; destructive changes need explicit reverse definitions |
| Inserts, conditional insert, update, delete | `Insert`, `Update`, `Delete.FromTable` | FluentDataChangesAndSchemaReadsPersistExpectedRows |
| Truncate, data copy, update from another table | `Execute.Truncate/CopyData/UpdateFrom` | Normal provider tests; mutable pair snapshot regression |
-| SQL, files, resources | `Execute.Sql/Script/EmbeddedScript` | SQL execution/preview tests; provider-specific batch splitting is separate work |
+| SQL, files, resources | `Execute.Sql/Script/EmbeddedScript` | SQL execution/preview tests; SQL Server GO batch splitting through the script APIs, with explicit rejection of unsupported client directives |
| Scalars/readers/existence/metadata | `Schema`, `Schema.Table`, `Select`, `SelectScalar` | Reader disposal and persisted-data assertions; nullable helpers are additive |
| Database administration | `Administration` | Typed operations flag transaction incompatibility; backend capabilities still apply |
| Provider conditions, commands/connections | `IfDatabase`, `Execute.WithCommand/WithConnection/WithProvider` | Inactive reversal, explicit preview rejection; callbacks execute trusted code |
diff --git a/docs/index.html b/docs/index.html
index b4ae8b20..02731859 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -5,7 +5,7 @@
Migrator.NET — Database changes, in your code.
@@ -38,7 +38,7 @@
Database changes.
Part of your code.
Write schema changes in C# with imperative or fluent APIs. Version them with your application.
- Run them with the database provider and ORM you choose.
+ Run them with the database provider and ORM you choose. Rebuild SQLite tables automatically from their live schema, without an ORM model.
-
+
+ SQLITE SCHEMA MIGRATIONS
+ Change existing tables. Keep your data.
+ Migrator reads the live SQLite schema and automatically rebuilds tables for
+ supported column type, nullability and default changes, plus primary, foreign,
+ unique and check constraint changes. No ORM model is required.
+
+
+ Automatic reconstruction
+ FluentMigrator leaves general column alterations and later foreign-key changes
+ to manual reconstruction. DbUp and Evolve execute your scripts. EF Core also
+ rebuilds tables, using artifacts represented in its model.
+
+
+ Preserve supported schema details
+ Rebuilds retain mapped rows, named and composite keys, column collations,
+ supported indexes and triggers, and AUTOINCREMENT high-water state.
+ Foreign keys retain independent update and delete actions.
+
+
+ Explicit preservation limits
+ Reconstruction rejects generated columns, STRICT and WITHOUT ROWID tables,
+ and indexes with explicit collations. Hidden rowid values can change;
+ arbitrary dependent SQL requires a migration plan.
+
+
+ Compare SQLite operations, sources and preservation limits →
+
+
-
VERSION 13 · SOURCE PREVIEW
Explicit definitions, shared authoring.
-
Breaking source changes. These features are not yet a released NuGet version.
+
SCHEMA DEFINITIONS
Explicit definitions, shared authoring.
+
Named constraints, explicit defaults and provider-aware collations.
Define primary, unique, foreign-key and check constraints as table objects.
The imperative and fluent APIs share column definitions, trusted SQL defaults and typed collation requests.
@@ -149,10 +177,15 @@
Separate histories by scope
.WithColumn("Id").AsString(27)
.WithDefaultValue(RawSql.Insert("ksuid_new()"))
.WithColumn("Name").AsString(100)
- .WithCollation(Collation.CaseInsensitive);
+ .WithCollation(Collation.AsciiIgnoreCase);
The target database must supply the SQL function. Collation mappings have explicit provider limits:
- SQLite ASCII folding does not satisfy a Unicode case-insensitive request.
- Read the 12.1-to-13 migration guide ↗.
+ The SQLite example uses ASCII-only NOCASE; it does not satisfy a Unicode case-insensitive request.
+ Read the migration guide ↗.
+ Use TimeOnly for time-of-day values and TimeSpan for intervals.
+ Review type support, precision and data limits by provider.
+ Runner options support tags, named profiles, ordered maintenance and consolidated history.
+ Integrate migration constructors and lifecycle logging with the optional Microsoft DI package.
+ Explore runner and deployment options.
Additional databases require passing real-engine CI.
SAP HANA provider qualification ↗;
Redshift, Snowflake and Db2 for IBM i remain unsupported.
@@ -170,14 +203,14 @@ Separate histories by scope
From code to schema.
- A minimal SQLite example for unreleased v13 source.
+ A minimal SQLite example using the current repository API.
Use .NET 9 and a checkout of this repository.
1
-
Reference the v13 source
+
Reference the library
Run these commands from your Migrator.NET checkout. This example references
the source project and passes an open SQLite connection to the provider.
@@ -298,7 +331,7 @@
Run pending migrations
-
FLUENT API · V13 SOURCE PREVIEW
+
FLUENT API
Chain operations. Keep control.
Use fluent and imperative migrations in the same assembly and runner.
@@ -384,7 +417,7 @@
Additional dialects in source
Firebird
Ingres
Sybase
-
SAP HANA (v13 source)
+
SAP HANA
@@ -393,12 +426,12 @@
Additional dialects in source
server or driver version. Schema operations and transactional DDL vary
by provider. Check the
provider factory
and
provider tests
for your database.
@@ -427,16 +460,16 @@
Evidence from CI.
Choose by how you work.
- Feature comparison · Reviewed 22 September 2026
Read the sources and qualifications ↓
- Version 13 source preview, not a NuGet release:
- fluent operations, SQL-preview subset, runner options, native locks and source CLI.
- Read the runner guide and limitations.
- Read the merged runner changes.
+
+ Use fluent operations, version planning, a SQL-preview subset, runner options,
+ native locks and the CLI.
+ Read the runner guide and provider limits.
Migrator fits applications that want explicit C# migrations and
@@ -560,7 +593,7 @@
Choose by how you work.
| Execution / deployment |
- Library + source CLI (unreleased) |
+ Library + CLI |
In-process runner + CLI |
CLI, SQL scripts, bundles, runtime API |
Library; host in a console app or application |
@@ -584,6 +617,30 @@ Choose by how you work.
RunAlways scripts |
Repeatable SQL reruns on checksum change |
+
+ | Automatic SQLite reconstruction |
+ Live-schema rebuilds; no ORM model |
+ Manual for general column and foreign-key alterations |
+ Rebuilds for model-represented artifacts |
+ Author scripts |
+ Author scripts |
+
+
+ | Planning and SQL preview |
+ Read-only version plan; connected/offline SQL subset |
+ Preview/output |
+ Generated SQL scripts |
+ Authored SQL / pending scripts |
+ Authored SQL |
+
+
+ | Deployment coordination |
+ Opt-in native locks: SQL Server, PostgreSQL, MySQL/MariaDB |
+ Application-lock pattern / deployment orchestration |
+ Migration locking; execution-path dependent |
+ Host/provider concern |
+ Cluster setting; provider-dependent |
+
@@ -609,7 +666,7 @@ Choose by how you work.
Keep migrations in C#
Migrator: imperative and fluent schema operations, scoped
- history, tags/profiles, and a source CLI or your own host.
+ history, tags/profiles, and the CLI or your own host.
FluentMigrator: a fluent DSL with packaged
runners, tags and profiles.
@@ -636,7 +693,7 @@ Keep SQL as the source
Our column is based on the current repository source, which
targets net9.0. Other columns summarize official
- documentation reviewed on 22 September 2026, rather than claiming
+ documentation reviewed on 22 September 2026, with SQLite comparisons rechecked on 23 September, rather than claiming
parity across every released package. Check your chosen release,
provider and database version. Suitability notes are our
interpretation of these documented capabilities.
@@ -687,6 +744,7 @@
Keep SQL as the source
href="https://fluentmigrator.github.io/migration-types/profiles.html"
>profiles,
+ SQLite generator,
authoring and providers.
@@ -716,7 +774,8 @@ Keep SQL as the source
seeding.
+ >,
+ SQLite rebuilds and locking.
DbUp:
diff --git a/docs/migration-framework-comparison.md b/docs/migration-framework-comparison.md
index 2378ecbb..c9a9330d 100644
--- a/docs/migration-framework-comparison.md
+++ b/docs/migration-framework-comparison.md
@@ -1,10 +1,10 @@
# .NET database migration frameworks: detailed feature comparison
-**Reviewed: 22 September 2026.** This is a capability comparison, not a benchmark or an overall ranking.
+**Reviewed: 23 September 2026.** This is a capability comparison, not a benchmark or an overall ranking.
The main matrices cover **DotNetProjects.Migrator, FluentMigrator, EF Core migrations, DbUp and Evolve**—all five frameworks on the homepage. Additional sections cover **EF6, grate and RoundhousE**, with a short boundary comparison for **Flyway and Liquibase**. This is a defined shortlist, not a claim to catalogue every migration package ever published.
-Migrator findings are pinned to v13 upgrade-stack commit [`eabec55`][m-revision]. These source capabilities were merged through PRs [#173](https://github.com/dotnetprojects/Migrator.NET/pull/173), [#174](https://github.com/dotnetprojects/Migrator.NET/pull/174), [#175](https://github.com/dotnetprojects/Migrator.NET/pull/175) [#177](https://github.com/dotnetprojects/Migrator.NET/pull/177), [#180](https://github.com/dotnetprojects/Migrator.NET/pull/180) [#181](https://github.com/dotnetprojects/Migrator.NET/pull/181) and [#182](https://github.com/dotnetprojects/Migrator.NET/pull/182), **not a claim that these features have shipped on NuGet**. FluentMigrator's SQLite implementation is pinned to [`2e0acdb`][f-sqlite-generator]. Other findings describe the linked official documentation as reviewed, not guaranteed behavior of every historical release. EF Core features introduced in version 9 are labeled. Check provider and release compatibility separately.
+Migrator findings are pinned to repository commit [`482b4d1`][m-revision]. FluentMigrator's SQLite implementation is pinned to [`2e0acdb`][f-sqlite-generator]. Other findings describe the linked official documentation, not guaranteed behavior of every historical release. SQLite comparisons were rechecked on 23 September; the broader competitor review was performed on 22 September. Check provider and release compatibility separately.
[Homepage](https://dotnetprojects.github.io/Migrator.NET/) · [Fluent API example](https://dotnetprojects.github.io/Migrator.NET/#fluent-api) · [Project README](../README.md) · [SQLite emulation comparison](#sqlite-emulation-comparison) · [Source index](#source-index)
@@ -17,6 +17,7 @@ Migrator findings are pinned to v13 upgrade-stack commit [`eabec55`][m-revision]
- [Transactions, rollback and coordination](#transactions-rollback-and-coordination)
- [Deployment, inspection and configuration](#deployment-inspection-and-configuration)
- [Database coverage and portability](#database-coverage-and-portability)
+- [Schema definitions and provider behavior](#schema-definitions-and-provider-behavior)
- [SQLite emulation comparison](#sqlite-emulation-comparison)
- [EF6, grate and RoundhousE](#ef6-grate-and-roundhouse)
- [Flyway and Liquibase in a .NET deployment](#flyway-and-liquibase-in-a-net-deployment)
@@ -53,7 +54,7 @@ Evidence: [Migrator runner][m-runner], [loader][m-loader], [migration contract][
| Migration discovery | Assembly scan or explicit `Type[]` | Assembly scanning / filters | Context's migration assembly | Configurable script providers | Locations or embedded resources |
| Constructor dependency injection | Optional Microsoft DI/options package; custom activator supported | Runner/DI integration | Context services; migration customization is separate | Custom script provider/host if needed | No C# migration constructors |
| Embedded execution | Yes | Yes | Yes | Yes | Library mode |
-| Dedicated execution host | Library or source-built packaged .NET tool (unreleased) | Library or packaged runner | Tooling, bundles or custom host | Write your own | CLI, .NET tool or library |
+| Dedicated execution host | Library or packaged .NET tool (local build instructions in the runner guide) | Library or packaged runner | Tooling, bundles or custom host | Write your own | CLI, .NET tool or library |
EF Core's model snapshot comparison is not a live-database schema comparison. DbUp's C# support is more than static SQL file loading, but it does not supply a cross-database schema-operation layer.
@@ -101,6 +102,8 @@ Evidence: [Migrator loader][m-loader], [execution][m-execution] and [history sto
**Migrator scope detail:** unscoped migrations inherit the runner scope. Explicitly scoped migrations are selected only for that scope; duplicate validation and history access use the same effective scope. Custom legacy providers without `IMigrationHistory` retain their prior behavior. History isolation is not table isolation. [Loader][m-loader], [execution][m-execution], [provider][m-provider].
+**Consolidated baselines:** migrations may record covered versions with `MigrationApplied(version, scope)`. The runner rechecks history before each step and skips versions already applied (or already removed during downgrade), without duplicate callbacks or history records. [Runner][m-runner], [history regressions][t-history].
+
## Transactions, rollback and coordination
Evidence: [Migrator execution][m-execution] and [runner][m-runner]; [FluentMigrator configuration][f-config] and [auto-reverse][f-reverse]; [EF Core management][ef-managing], [deployment][ef-applying] and [SQLite limitations][ef-sqlite]; [DbUp transactions][d-transactions] and [philosophy][d-philosophy]; [Evolve concepts][e-concepts] and [options][e-options].
@@ -126,7 +129,7 @@ Evidence: [Migrator runner][m-runner] and [execution][m-execution]; [FluentMigra
| Capability | Migrator | FluentMigrator | EF Core | DbUp | Evolve |
| ------------------------------------ | ------------------------------------------------- | ------------------------------------------ | --------------------------------- | -------------------------------- | ------------------------------------------------ |
-| Packaged CLI | Source project `DotNetProjects.Migrator.Tool`; not published by this upgrade | Yes | `dotnet ef` | Core library; custom host | Yes |
+| Packaged CLI | `DotNetProjects.Migrator.Tool`; see local pack/install instructions | Yes | `dotnet ef` | Core library; custom host | Yes |
| Dedicated migration bundle generator | No; publish host | Package runner/migrations | Yes | Publish host | CLI distribution, not EF-style bundle generation |
| Review SQL without applying | Connected/offline structured subset; unsupported operations fail explicitly | Preview/output | Scripts | Authored SQL / pending scripts | Authored SQL |
| Dry-run qualification | `DryRun` plans versions without migration bodies, callbacks, transactions or history creation | Processor preview; user code needs care | Not a full side-effect simulation | Pending list / custom simulation | `RollbackAll` actually executes |
@@ -137,13 +140,13 @@ Evidence: [Migrator runner][m-runner] and [execution][m-execution]; [FluentMigra
| SQL substitution | Custom | Script tokens | Custom logic | `$variable$` | `${placeholder}` |
| Deployment identity | Host connection | Runner connection | Migration connection | Host connection | Tool connection |
-**Migrator dry run is not an offline SQL preview.** Execution starts provider work while `Up()`/`Down()` are skipped. It cannot show SQL from those skipped bodies and should not be described as side-effect-free database validation. [Execution source][m-execution].
+**Planning and SQL preview are separate operations.** `Plan` and `DryRun` read history without creating/upgrading it or executing migration bodies, transactions or callbacks. `PreviewSql` reads connected history/schema; `MigrationSqlPreview.Generate` can generate the supported structured subset offline. Preview authoring executes trusted C#, so it is not a sandbox. [Runner source][m-runner], [runner guide](runner-guide.md#planning-and-sql-preview).
## Database coverage and portability
| Framework | How support is supplied | What it does not guarantee |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
-| Migrator | Source dialects + separate ADO.NET drivers. Live CI covers SQLite, SQL Server, PostgreSQL, Oracle, MySQL, MariaDB, Firebird, Db2, Informix, Sybase and the new HANA job; Ingres is another source dialect. [CI guide][m-live]. | Every server/driver release, operation or arbitrary SQL construct. |
+| Migrator | Source dialects + separate ADO.NET drivers. Live CI covers SQLite, SQL Server, PostgreSQL, Oracle, MySQL, MariaDB, Firebird, Db2, Informix, Sybase and HANA; Ingres is another source dialect. [CI guide][m-live]. | Every server/driver release, operation or arbitrary SQL construct. |
| FluentMigrator | Provider generators/processors. [Configuration][f-config]. | The same expression working on every engine. |
| EF Core | Relational provider packages. [Multiple providers][ef-providers]. | One provider's generated migrations working unchanged elsewhere. |
| DbUp | Database integrations. [Provider list][d-databases]. | SQL dialect translation. |
@@ -151,9 +154,9 @@ Evidence: [Migrator runner][m-runner] and [execution][m-execution]; [FluentMigra
A migration can compile yet require a table copy, lose an unsupported schema detail or fail on existing data. Compare the exact operation and data shape, not just database names.
-## Version 13 authoring and database additions
+## Schema definitions and provider behavior
-The v13 source uses `PrimaryKeyConstraint`, `UniqueConstraint`, `CheckConstraint`
+Migrator uses `PrimaryKeyConstraint`, `UniqueConstraint`, `CheckConstraint`
and `ForeignKeyConstraint` objects instead of key/uniqueness flags on columns.
`IsNullable`, `IsIdentity` and `IsUnsigned` describe column attributes. The duplicate
legacy schema builder is removed; see the [migration guide](migration-guide-12.1-to-13.md).
@@ -165,8 +168,7 @@ This does not make arbitrary SQL functions or linguistic ordering portable.
See [FluentMigrator's raw SQL helper](https://fluentmigrator.github.io/basics/raw-sql.html)
for the corresponding upstream default-expression feature.
-The new **SAP HANA** source provider in [PR #182](https://github.com/dotnetprojects/Migrator.NET/pull/182)
-has a mandatory GitHub Actions job using SAP's actual HANA Express engine and native
+The **SAP HANA** provider has a mandatory GitHub Actions job using SAP's actual HANA Express engine and native
.NET driver. It covers schema/data operations, metadata, constraints, migration
history, restart, DML rollback and imperative/fluent/preview parity. DDL may
autocommit; native migration locking, whole-session transactional DDL and the
@@ -177,6 +179,10 @@ Db2 for IBM i**. They require external test infrastructure and remain deferred.
PostgreSQL tests do not qualify Redshift, and Db2 LUW tests do not qualify IBM i.
[Qualification requirements, CI evidence and primary sources](additional-database-qualification.md).
+### Values, precision and engine limits
+
+Use `TimeOnly` for time of day and `TimeSpan` for intervals. PostgreSQL/Oracle have native interval mappings; SQLite, SQL Server and MySQL/MariaDB use signed ticks. Supported unsigned mappings, large text/binary, decimal precision and provider-specific limits are documented in the [data-type and boundary matrix](data-type-boundary-tests.md). SQLite does not enforce declared string lengths or decimal precision and rejects UInt64 values above Int64.MaxValue. Dialect availability does not imply identical storage semantics.
+
## SQLite emulation comparison
### What emulation means
@@ -248,7 +254,9 @@ Methods refer to the pinned [SQLite provider][m-sqlite]. Tests illustrate eviden
| Mapped rows | Named-column `INSERT … SELECT`. | New constraints/types must accept the data. |
| Names, parsed types, nullability, defaults | Included in column model. | Not a lossless representation of arbitrary CREATE SQL. |
| Composite PKs | Represented; dedicated rebuild test. | Check membership/order when replacing definitions. |
-| FKs and delete actions | Read from schema/PRAGMA; emitted into replacement DDL. | Not a promise about every clause, e.g. arbitrary deferrability. |
+| FKs and independent update/delete actions | Named/ordered definitions read from schema/PRAGMA and emitted into replacement DDL. | `MATCH FULL`/`PARTIAL` rejected; no promise of arbitrary deferrability. |
+| Column collations | Declared names read and preserved; explicit changes rebuild. | Custom collations must be registered on the connection; index-level collations are rejected for rebuilds. |
+| GUID defaults | CLR GUID defaults use the same blob format as inserted GUID parameters. | Existing text defaults are preserved; mixed representations require an explicit data migration. |
| Unique / CHECK definitions | Included in `SQLiteTableInfo`. | Reader restrictions apply; rename does not rewrite arbitrary CHECK expressions. |
| Indexes / represented filters | Recreated after replacement. | Complex predicates, expressions, collations and sort details require separate verification. |
| Triggers | Collected and replayed for supported rebuilds without renames; unsafe rename fallback rejected. | Trigger SQL is replayed only where the rebuild does not require rewriting its identifiers. |
@@ -259,7 +267,7 @@ Methods refer to the pinned [SQLite provider][m-sqlite]. Tests illustrate eviden
| FK enforcement state | Runner and owned rebuild transactions restore the prior setting after success/failure. | Caller-owned active SQLite transactions require FK settings to be configured before beginning the transaction. |
| Whole-database FK validation | Runner and owned rebuild transactions validate integrity before commit. | Enabling enforcement alone does not validate existing rows. |
-Evidence: [SQLite provider][m-sqlite], [schema model][m-sqlite-model], [execution][m-execution], [SQLite reconstruction procedure][sqlite-alter]. Native drop-column selection and AUTOINCREMENT high-water preservation have regressions. Arbitrary dependency rewriting remains unsupported.
+Evidence: [SQLite provider][m-sqlite], [schema model][m-sqlite-model], [execution][m-execution], [SQLite reconstruction procedure][sqlite-alter]. Native drop-column selection and AUTOINCREMENT high-water preservation have regressions. Column collations, GUID defaults and FK match semantics have [collation][t-collation], [GUID][t-guid] and [FK match][t-match] regressions. Arbitrary dependency rewriting remains unsupported.
### How the other frameworks compare on preservation
@@ -323,8 +331,8 @@ These interpretations are grounded in the preceding evidence, rather than univer
| ---------------------------------------------- | ----------------------------------------------------------------------- |
| No ORM model, frequent SQLite alterations | Evaluate Migrator's live-schema reconstruction and preservation limits. |
| EF model defines schema | EF Core supplies scaffolding, rebuilds and deployment artifacts. |
-| Handwritten C# / fluent DSL | Migrator v13 source and FluentMigrator both provide fluent authoring, tags and profiles. Compare provider operations and reversal limits. |
-| Published packaged runner | FluentMigrator ships runners; Migrator’s v13 CLI is source-built and not a released-package claim. |
+| Handwritten C# / fluent DSL | Migrator and FluentMigrator both provide fluent authoring, tags and profiles. Compare provider operations and reversal limits. |
+| Dedicated deployment host | Migrator and FluentMigrator provide .NET tools; compare driver coverage and deployment requirements. Migrator documents local pack/install commands. |
| SQL-first runner composed in .NET | DbUp's script providers, journal and transaction strategies. |
| SQL checksums / change-triggered repeatables | Evolve's built-in conventions. |
| Existing RoundhousE folders | Evaluate grate's migration guide and history compatibility. |
@@ -333,19 +341,19 @@ These interpretations are grounded in the preceding evidence, rather than univer
Potential Migrator improvements, **not implemented-feature claims**:
-1. Broader structured SQL-preview coverage, more client-script dialects and CLI deployment validation. SQL Server GO scripts now use an explicit batch path. The source CLI and preview subset already exist.
+1. Broader structured SQL-preview coverage, more client-script dialects and CLI deployment validation. SQL Server GO scripts use an explicit batch path. The CLI and preview subset are available.
2. Validation of edits to already applied migration content.
-3. More native lock backends and recovery/concurrency validation; three database families now have opt-in locks.
+3. More native lock backends and recovery/concurrency validation; SQL Server, PostgreSQL and MySQL/MariaDB have opt-in locks.
4. Repeatable migrations distinct from execution hooks.
5. SQLite generated columns, table options, hidden rowid and complex-index preservation beyond the currently guarded subset.
-6. Broader behavioral parity tests beyond the [fluent method-family inventory](fluent-operation-coverage.md), and provider coverage for explicit adoption of historical uniqueness objects without ownership markers.
+6. Broader behavioral parity tests beyond the [fluent method-family inventory](fluent-operation-coverage.md), and metadata fidelity for complex provider-specific schemas. Column changes preserve explicit constraints; implicit uniqueness ownership/adoption is removed.
7. Continued operation-level provider documentation and live test coverage.
## Validation and maintenance
-The master baseline (`b7ae95c`) passed 139 SQLite tests with one skipped default-removal test. The earlier runner upgrade revision passed **93 unit tests and 184 SQLite tests, with no skips**, after rebuilding the solution. Test counts reflect replacement of assertion-free tests with behavioral checks. The packed/installed tool previously passed offline SQL, migration, status and rollback smoke checks. The provider fixes at `bdc8ac3` passed all eleven database/unit jobs and the coverage gate in [run 35737814671](https://github.com/dotnetprojects/Migrator.NET/actions/runs/35737814671). Concurrent-runner tests passed on SQL Server, PostgreSQL, MySQL and MariaDB at `bb88165` in [run 35741656276](https://github.com/dotnetprojects/Migrator.NET/actions/runs/35741656276). The earlier revision `bc35e0e`, including PostgreSQL metadata/time changes, passed all eleven database/unit jobs and the coverage gate in [run 35743265022](https://github.com/dotnetprojects/Migrator.NET/actions/runs/35743265022). A green earlier revision is not evidence for a later revision.
+The [homepage CI results](https://dotnetprojects.github.io/Migrator.NET/#test-results) report the latest completed master run with its commit, counts and missing-suite status. The [live database guide](live-database-tests.md) describes the eleven-engine matrix; [data-type boundary tests](data-type-boundary-tests.md) document supported mappings and behavioral limits. Historical fixes and run evidence remain in the [issue audit](issue-audit.md). A green earlier revision is not evidence for a later revision.
-This is not a complete implementation of the upgrade plan: SQL preview supports a structured subset; offline CLI rejects profiles/maintenance; full client-script dialects, remaining metadata/legacy ownership cases and broader deployment regressions remain work in progress. SQL Server GO splitting and explicit Oracle legacy sequence cleanup are implemented. See the [81-issue inventory](issue-audit.md) for verified closures and incomplete audit items. The operation inventory maps normal API method families to fluent/context entry points, but does not establish every overload/provider combination through execution. Competitors were reviewed through documentation/source, **not executed in a comparative harness**.
+Implementation limits: SQL preview supports a structured subset; offline CLI rejects profiles/maintenance; full client-script dialects, remaining metadata cases and broader deployment regressions remain work in progress. SQL Server GO splitting and explicit Oracle legacy sequence cleanup are implemented. See the [81-issue inventory](issue-audit.md) for verified closures and incomplete audit items. The operation inventory maps normal API method families to fluent/context entry points, but does not establish every overload/provider combination through execution. Competitors were reviewed through documentation/source, **not executed in a comparative harness**.
When updating:
@@ -366,29 +374,29 @@ When updating:
- **grate / RoundhousE:** [grate][g-home], [options][g-config], [script types][g-types], [migration guide][g-migrate], [RoundhousE][r-home].
- **SQLite engine:** [ALTER TABLE and reconstruction procedure][sqlite-alter].
-[m-runner]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Migrator.cs
-[m-loader]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/MigrationLoader.cs
-[m-execution]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/MigrationExecution.cs
-[m-migration]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Framework/Migration.cs
-[m-api]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Framework/ITransformationProvider.cs
-[m-provider]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Providers/TransformationProvider.cs
-[m-factory]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/ProviderFactory.cs
-[m-live]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/docs/live-database-tests.md
-[m-sqlite]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs
-[m-sqlite-model]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator/Providers/Impl/SQLite/Models/SQLiteTableInfo.cs
-[t-add-column]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddColumnTests.cs
-[t-change-column]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs
-[t-remove-column]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RemoveColumnTests.cs
-[t-rename-column]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RenameColumnTests.cs
-[t-pk]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddPrimaryKeyTests.cs
-[t-fk]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddForeignKeyTests.cs
-[t-integrity]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_CheckForeignKeyIntegrityTests.cs
-[t-uniques]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_GetUniques.cs
-[t-check]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_GetCheckConstraintsTests.cs
-[t-remove-constraints]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RemoveAllConstraintsTests.cs
-[t-recreate]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RecreateTable.cs
-[t-sqlite-general]: https://github.com/dotnetprojects/Migrator.NET/blob/eabec5561c2c9c77847b9adbb7b67474e3c70a50/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProviderTests.cs
-[m-revision]: https://github.com/dotnetprojects/Migrator.NET/tree/eabec5561c2c9c77847b9adbb7b67474e3c70a50/
+[m-runner]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Migrator.cs
+[m-loader]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/MigrationLoader.cs
+[m-execution]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/MigrationExecution.cs
+[m-migration]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Framework/Migration.cs
+[m-api]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Framework/ITransformationProvider.cs
+[m-provider]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Providers/TransformationProvider.cs
+[m-factory]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/ProviderFactory.cs
+[m-live]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/docs/live-database-tests.md
+[m-sqlite]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs
+[m-sqlite-model]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator/Providers/Impl/SQLite/Models/SQLiteTableInfo.cs
+[t-add-column]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddColumnTests.cs
+[t-change-column]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs
+[t-remove-column]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RemoveColumnTests.cs
+[t-rename-column]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RenameColumnTests.cs
+[t-pk]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddPrimaryKeyTests.cs
+[t-fk]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_AddForeignKeyTests.cs
+[t-integrity]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_CheckForeignKeyIntegrityTests.cs
+[t-uniques]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_GetUniques.cs
+[t-check]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_GetCheckConstraintsTests.cs
+[t-remove-constraints]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RemoveAllConstraintsTests.cs
+[t-recreate]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_RecreateTable.cs
+[t-sqlite-general]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProviderTests.cs
+[m-revision]: https://github.com/dotnetprojects/Migrator.NET/tree/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/
[f-start]: https://fluentmigrator.github.io/intro/quick-start.html
[f-config]: https://fluentmigrator.github.io/intro/configuration.html
[f-sql]: https://fluentmigrator.github.io/operations/execute-sql.html
@@ -436,9 +444,7 @@ When updating:
[liquibase-preconditions]: https://docs.liquibase.com/community/user-guide-5-0-4/what-are-preconditions
[f-generic-generator]: https://github.com/fluentmigrator/fluentmigrator/blob/2e0acdb7c375b03e50e65f34ddf50e44ee45df30/src/FluentMigrator.Runner.Core/Generators/Generic/GenericGenerator.cs
-The v13 column-model revision `11d6083` passed the complete existing-provider
-matrix in [run 35769034542](https://github.com/dotnetprojects/Migrator.NET/actions/runs/35769034542),
-including 87 unit and 197 SQLite tests. The additional HANA source is pinned at
-`eabec55` and its complete matrix is [run 35770116342](https://github.com/dotnetprojects/Migrator.NET/actions/runs/35770116342).
-Require successful actual-engine checks on the final PR head before merging;
-SQL-string assertions and skipped jobs do not qualify a new provider.
+[t-history]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/MigrationHistoryRegressionTests.cs
+[t-collation]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/SQLiteCollationRegressionTests.cs
+[t-guid]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/SQLiteGuidDefaultTests.cs
+[t-match]: https://github.com/dotnetprojects/Migrator.NET/blob/482b4d1b2a0a3672c3199c533a69cc4da330b8d6/src/Migrator.Tests/SQLiteForeignKeyMatchTests.cs
diff --git a/docs/runner-guide.md b/docs/runner-guide.md
index 4c171ac2..cdd0de8e 100644
--- a/docs/runner-guide.md
+++ b/docs/runner-guide.md
@@ -1,6 +1,6 @@
-# Runner and fluent API upgrade
+# Runner and fluent API
-These APIs describe the source upgrade merged through PRs #173, #174, #175 and #177. They are not a statement about the currently released NuGet packages. Build the repository to try them; no package publication is part of this change.
+Use imperative or fluent migrations with scope and tag filtering, profiles, ordered maintenance, transaction modes, planning, SQL preview and deployment locks. This guide describes the current repository API; check package compatibility when using an older release.
## Fluent quick start
@@ -31,7 +31,7 @@ The builder has `Create`, `Alter`, `Delete`, `Rename`, `Insert`, `Update`, `Exec
`Execute.Script(path)` and `Execute.EmbeddedScript(assembly, resourceName)` capture script text as dedicated operations. Imperative callers can use `ExecuteScript(path)`, `ExecuteResourceScript(assembly, name)` and `ExecuteSqlScript(text)`. SQL Server splits standalone `GO` lines, including an optional `--` comment, while respecting strings, quoted identifiers and nested comments. GO repetition and SQLCMD directives fail explicitly before executing batches. Ordinary `ExecuteNonQuery` and fluent `Execute.Sql` never split client separators. Other providers receive the script as one command unless they implement `IScriptBatchProvider`; this is not a complete SQL*Plus, mysql-client or isql interpreter.
-Oracle `RemoveTable` leaves unrelated sequences intact and relies on Oracle to remove table-owned triggers and native identity objects. For legacy sequences you explicitly own, use `OracleTransformationProvider.RemoveTableWithOwnedSequences(table, sequenceNames)` through an explicit provider context/callback. It accepts simple unquoted sequence names, validates existence before dropping the table, and propagates cleanup failures. Oracle DDL is not atomic. SQL Server removes only column-unique constraints carrying its ownership marker; historical unmarked objects can be adopted explicitly with `SqlServerTransformationProvider.AdoptColumnUniqueConstraint(table, column, constraint)`. Adoption verifies a single-column UNIQUE constraint before marking it and rejects composite constraints. Names alone never establish ownership.
+Oracle `RemoveTable` leaves unrelated sequences intact and relies on Oracle to remove table-owned triggers and native identity objects. For legacy sequences you explicitly own, use `OracleTransformationProvider.RemoveTableWithOwnedSequences(table, sequenceNames)` through an explicit provider context/callback. It accepts simple unquoted sequence names, validates existence before dropping the table, and propagates cleanup failures. Oracle DDL is not atomic. Column changes preserve explicit unique constraints and indexes. Use `AddUniqueConstraint`, `RemoveConstraint` or `RemoveIndex` to manage them independently. SQL Server no longer uses implicit ownership markers or exposes `AdoptColumnUniqueConstraint`; old markers do not cause constraints to be deleted.
## Runner options
@@ -49,6 +49,10 @@ Unscoped migrations inherit the provider scope; explicitly scoped migrations run
Maintenance classes use `[Maintenance(MaintenanceStage.BeforeRun)]`, `BeforeMigration`, `AfterMigration` or `AfterRun`. Profiles and maintenance accept `Order` and `Scope`. Ordering uses `Order` then ordinal full type name. Hooks stop on failure; later hooks are not cleanup guarantees. Connection/transaction restoration and lock release do not depend on hooks running. Profiles and maintenance use `Up`; they do not acquire version records.
+## Consolidated history
+
+A baseline migration can call `Database.MigrationApplied(version, scope)` for older versions whose schema it includes. Before each planned step, the runner rechecks the active scope's history. It skips versions already covered by the baseline, including their `AfterUp` callbacks, and does not record the baseline's own version twice. Downward runs similarly skip versions already removed by an earlier `Down`. Other scopes do not affect these decisions. History and schema changes follow the selected transaction mode.
+
## Transactions and locks
`PerMigration` commits each successful migration. `None` leaves transaction behavior to the provider/operations. `WholeSession` is accepted for SQLite, PostgreSQL and SQL Server dialects; history-table initialization occurs before that transaction. Other dialects fail explicitly because transactional DDL has not been verified. Arbitrary imperative SQL can still violate transaction assumptions; database administration and implicit-commit statements require separate runs.
@@ -93,7 +97,7 @@ Exit codes: `0` success, `1` execution/load failure, `2` invalid arguments, `3`
## Optional DI and logging
-The source package `DotNetProjects.Migrator.Extensions.DependencyInjection` provides `services.AddMigrator(providerFactory, migrationAssembly, configureOptions)`. Resolve `Migrator` inside a service scope; migration constructors use that scope's services. Options are scoped snapshots. Provider disposal follows the DI scope. Microsoft logging records lifecycle events while omitting SQL text and raw exception messages; the core retains its lightweight logger API.
+The optional package `DotNetProjects.Migrator.Extensions.DependencyInjection` provides `services.AddMigrator(providerFactory, migrationAssembly, configureOptions)`. Resolve `Migrator` inside a service scope; migration constructors use that scope's services. Options are scoped snapshots. Provider disposal follows the DI scope. Microsoft logging records lifecycle events while omitting SQL text and raw exception messages; the core retains its lightweight logger API.
## Validation
@@ -105,7 +109,7 @@ pwsh .github/scripts/test.ps1 -Database Unit
pwsh .github/scripts/test.ps1 -Database SQLite
```
-See [live database tests](live-database-tests.md) for the full matrix. Provider-specific changes need live provider evidence. Check PR CI and review threads after every push; reply with implementation/test evidence and resolve fixed findings. Keep commits descriptive and merge the PR stack in dependency order only after review.
+See [live database tests](live-database-tests.md) for the full matrix and [data-type boundary tests](data-type-boundary-tests.md) for supported mappings and precision, range and size limits. Provider-specific changes need live provider evidence.
An auxiliary-only `MigrateToLastVersion()` run preserves existing version history while executing selected profiles and maintenance. A completely empty run does not create a history table. Post-commit callbacks receive their migration context in both per-migration and whole-session modes; callback failure cannot undo a committed migration.
@@ -128,3 +132,13 @@ Oracle's Time representation remains DATE with a fixed 1970-01-01 date and whole
This changes the old shared parameter inference: TimeSpan now means Interval. Migrate time-of-day inputs with `TimeOnly.FromTimeSpan(value)`; it rejects negative or multi-day durations. Do not convert genuine intervals this way.
ASE 16.0 key constraints with dots or apostrophes in their names are rejected before DDL. The tested server can create a punctuated name but cannot reliably resolve its backing index when removing the constraint. Use a key name without those characters; this restriction applies to primary and unique keys.
+
+## SQLite schema and value behavior
+
+SQLite alterations use native rename/drop-column paths when eligible and live-schema reconstruction for supported changes that need a replacement table. Rebuilds retain column collations, named/composite keys, independent foreign-key update/delete actions, supported indexes/triggers and AUTOINCREMENT high-water state. They validate foreign-key integrity before committing owned transactions and restore the prior enforcement setting. Configure foreign-key settings before starting a caller-owned transaction.
+
+`MATCH FULL` and `MATCH PARTIAL` are rejected because SQLite does not enforce their semantics. Generated columns, `STRICT`, `WITHOUT ROWID`, and indexes with explicit collations are unsupported for reconstruction. Hidden rowid values are not preserved. See the [operation and preservation matrices](migration-framework-comparison.md#sqlite-emulation-comparison).
+
+`Collation.AsciiIgnoreCase` maps to SQLite's ASCII-only `NOCASE`; semantic Unicode case-insensitivity is not substituted with ASCII folding. Use `Collation.Named` for a registered custom collation. Changing a column collation rebuilds the table and rolls back on a uniqueness violation.
+
+CLR `Guid` defaults and inserted GUID parameters both use blobs from `Guid.ToByteArray()`. Existing text GUID defaults remain SQL expressions during unrelated rebuilds. Converting existing mixed text/blob identifiers requires an explicit migration of related keys. See the [GUID and identity guidance](migration-guide-12.1-to-13.md#sqlite-defaults-and-identity).