M15: cross-provider migrations, closing Phase 5 (0.5.0)#15
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prepare the migrate and database commands to dispatch across providers without changing behaviour (SQL Server stays the only one wired): - Add IDatabaseAdmin in SqlBound.Migrations; SqlServerDatabaseAdmin implements it. - Make transactional DDL a ledger capability (IMigrationLedger. SupportsTransactionalDdl); MigrationRunner wraps each migration in a transaction only when the provider supports it, so a non-transactional provider (MySQL, coming next) applies migrations without one. - Add ProviderServices, a resolver for the connection, ledger, and database administrator per DatabaseTarget; route MigrationCli, DatabaseCommand, and PrepareRunner's connection creation through it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SqliteMigrationLedger stores the history in _sqlbound_migrations (with applied_on_utc as ISO-8601 text, since SQLite has no date type) and reports transactional DDL. SqliteDatabaseAdmin treats the Data Source file as the database: create materializes the file, drop deletes it. Both wired into the CLI provider resolver, so migrate run/revert/status and database create/drop now work against SQLite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NpgsqlMigrationLedger stores the history in _sqlbound_migrations (applied_on_utc as timestamptz, paired with the UTC-kind DateTime the runner produces) and reports transactional DDL. NpgsqlDatabaseAdmin creates and drops the target database from the maintenance 'postgres' database, checking pg_database for idempotent create and using DROP DATABASE ... WITH (FORCE) to evict connections. Both wired into the provider resolver, so migrate and database now work against PostgreSQL. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MySqlMigrationLedger stores the history in _sqlbound_migrations and, because MySQL commits DDL implicitly, reports SupportsTransactionalDdl = false — so MigrationRunner applies each migration without a transaction. MySqlDatabaseAdmin creates and drops the target database with CREATE/DROP DATABASE IF (NOT) EXISTS from a no-default-database connection. ADR 0007 records the non-transactional decision. Both wired into the resolver; MySQL now completes the four-provider migrate and database support. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update docs/migrations.md now that migrate and database support all four providers: replace the SQL-Server-only notes with a per-provider matrix covering transactional DDL and the create/drop mechanics, and link ADR 0007 for MySQL's non-transactional migrations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the prerelease suffix now that migrations and the database lifecycle work across all four providers. This is the commit the v0.5.0 tag will mark; PackageVersion reads a clean 0.5.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring the README up to date with all work through Phase 5: v0.5.0 status, the full migration and database command set, a provider support matrix (verification fidelity and migration transactionality per provider), the complete package list including SqlBound.Introspection and .Migrations, the ADR index through 0007, and the roadmap with Phases 1-5 done and only Phase 6 (Ship) remaining. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes Phase 5 — Migrations & CLI. Spreads the migration engine and database lifecycle from SQL Server across SQLite, PostgreSQL, and MySQL, reconciles the transactional-DDL differences, and cuts a clean
0.5.0.What's here
IDatabaseAdmin(M13 deferred this until a second implementation existed); make transactional DDL a ledger capability (IMigrationLedger.SupportsTransactionalDdl), soMigrationRunnerwraps each migration in a transaction only when the provider supports it. AProviderServicesresolver replaces the CLI's!= SqlServergates and centralises connection/ledger/admin selection (shared withPrepareRunner).SqliteMigrationLedger(ISO-8601applied_on_utctext) +SqliteDatabaseAdmin(theData Sourcefile is the database: create materializes it, drop deletes it).NpgsqlMigrationLedger(timestamptz, UTC-kind) +NpgsqlDatabaseAdmin(maintenancepostgresdb, idempotent create viapg_database,DROP DATABASE ... WITH (FORCE)).MySqlMigrationLedgerreportingSupportsTransactionalDdl = false+MySqlDatabaseAdmin(CREATE/DROP DATABASE IF (NOT) EXISTS). Migrations apply without a transaction; recorded in ADR 0007.docs/migrations.mdper-provider matrix; a full README rewrite for the v0.5.0 feature set (command set, provider support matrix, packages, ADR index 0001–0007, roadmap).PackageVersiondropped to a clean0.5.0(the commitv0.5.0will tag).Design notes
IDatabaseAdminextracted exactly when the second implementation arrived, matching howIQueryDescriberwas handled in M10.Verification
dotnet formatclean.0.5.0.Two provider wrinkles the integration tests caught: Npgsql can't read
regclassviaExecuteScalar(test-side fix), and the default MySQL container user lacksCREATE DATABASE, so the admin tests useroot— reflecting that database creation is a privileged operation.After merge: tag
v0.5.0on the squash commit and close the Phase 5 milestone.🤖 Generated with Claude Code