Simple.Migrations

repository·master·Indexed 42 days ago

https://github.com/canton7/simple.migrations

A lightweight, bare-bones migration framework for .NET Core and .NET Standard. It provides composable tools for integrating database migrations without enforcing a specific SQL generation syntax, supporting providers for MSSQL, SQLite, PostgreSQL, and MySQL.

Tokens
1.8K
Snippets
4
Records
7
Agent score
3%

What's inside Simple.Migrations

  1. How to write a custom Database Provider

    master

    To support a new database engine, you must implement IDatabaseProvider<TConnection>. The implementation strategy depends on whether you want to support concurrent migrators:

    1. No Concurrency Support

    Subclass DatabaseProviderBaseWithAdvisoryLock. Override AcquireAdvisoryLock() and ReleaseAdvisoryLock() to do nothing. Implement the SQL methods: GetcreateVersionTableSql(), GetCurrentVersionSql(), and GetSetVersionSql().

    2. Concurrency via Advisory Locks

    Subclass DatabaseProviderBaseWithAdvisoryLock. Implement AcquireAdvisoryLock() and ReleaseAdvisoryLock() using your database's specific advisory lock mechanism. Implement the SQL methods: GetcreateVersionTableSql(), GetCurrentVersionSql(), and GetSetVersionSql().

    3. Concurrency via Version Table Locking

    Subclass DatabaseProviderBaseWithVersionTableLock. Implement AcquireVersionTableLock() by creating a transaction on this.VersionTableConnection and executing SQL to lock the table. Implement ReleaseVersionTableLock() by destroying the transaction. Implement the SQL methods: GetcreateVersionTableSql(), GetCurrentVersionSql(), and GetSetVersionSql().

  2. Install Simple.Migrations via NuGet

    master

    Simple.Migrations is available on NuGet. You can install it using the Package Manager Console:

    PM> Install-Package Simple.Migrations

    Alternatively, use the NuGet Package Manager UI in Visual Studio to search for Simple.Migrations and install it.

    PM> Install-Package Simple.Migrations
  3. Configure Database Provider settings

    master

    Database providers have several configurable properties to control how they interact with the database:

    • TableName: The name of the table used to track the current schema version.
    • MaxDescriptionLength: The width of the 'description' column in the version table (useful for databases with fixed-width requirements).
    • AdvisoryLockName / AdvisoryLockKey: Used by databases that require a named advisory lock.
    • LockTimeout: The timeout for attempting to acquire an advisory lock before aborting.
    • SchemaName: The name of the database schema to use (and attempt to create if it doesn't exist).
    • CreateSchema: If false, the provider will not attempt to create the schema automatically (useful if permissions are restricted).
  4. Use SimpleMigrator to manage migrations

    master

    The SimpleMigrator class is the primary entry point for managing migrations. It handles finding migrations in an assembly and executing them against a database.

    Important: You must call .Load() before calling any other methods on the migrator instance.

    Key Methods:

    • Load(): Discovers migrations in the provided assembly and queries the database for the current version.
    • MigrateTo(n): Migrates the database to a specific version n. Use MigrateTo(0) to remove all migrations.
    • MigrateToLatest(): A shortcut to migrate to the most recent version found in the assembly.
    • Baseline(n): Updates the version table to version n without actually running any migration classes. Useful for existing databases.
    • CurrentMigration: Property returning the current version of the schema.
    • Migrations: Property returning an ordered list of all discovered migrations.
    var migrationsAssembly = typeof(Program).Assembly;
    using (var db = new SQLiteConnection("DataSource=database.sqlite"))
    {
        var databaseProvider = new SqliteDatabaseProvider(db);
        var migrator = new SimpleMigrator(migrationsAssembly, databaseProvider);
    
        migrator.Load();
        migrator.MigrateToLatest();
    }
  5. Run migrations via ConsoleRunner

    master

    If you are building a command-line tool, ConsoleRunner provides a ready-to-use CLI for interacting with a SimpleMigrator.

    Note: ConsoleRunner is available in .NET Standard 1.3+ and .NET 4.5. It is not available in .NET Standard 1.2.

    To use it, pass your SimpleMigrator instance to the ConsoleRunner constructor and call .Run(args) in your Main method.

    static int Main(string[] args)
    {
        var migrationsAssembly = typeof(Program).Assembly;
        using (var db = new SQLiteConnection("DataSource=database.sqlite"))
        {
            var databaseProvider = new SqliteDatabaseProvider(db);
            var migrator = new SimpleMigrator(migrationsAssembly, databaseProvider);
            
            var consoleRunner = new ConsoleRunner(migrator);
            return consoleRunner.Run(args);
        }
    }
  6. Create a Migration class

    master

    Migrations are classes that derive from Migration (for ADO.NET) or implement IMigration<TConnection>. They must be decorated with the [Migration(versionNumber)] attribute.

    Key features:

    • Up(): Overridden method to apply changes. Invoked when migrating up.
    • Down(): Overridden method to revert changes. Invoked when migrating down.
    • Execute(string sql): Inherited method to execute raw SQL. It automatically logs the SQL via the Logger.
    • UseTransaction: A boolean property (default true) that determines if the migration runs inside a transaction. Set to false if your database engine requires non-transactional SQL for certain operations.
    using SimpleMigrations;
    
    namespace Migrations
    {
        [Migration(1, "Create Users table")]
        public class CreateUsers : Migration
        {
            protected override void Up()
            {
                Execute(@"CREATE TABLE Users (
                    Id SERIAL NOT NULL PRIMARY KEY,
                    Name TEXT NOT NULL
                )");
            }
    
            protected override void Down()
            {
                Execute("DROP TABLE Users");
            }
        }
    }
  7. Supported Database Providers

    master

    Simple.Migrations uses IDatabaseProvider<TConnection> to manage the schema version table and handle concurrency locks. The following built-in providers are supported:

    EngineProvider ClassConcurrency Support
    MSSQLMssqlDatabaseProviderYes (via app locks)
    SQLiteSqliteDatabaseProviderNo
    PostgreSQLPostgresqlDatabaseProviderYes (via advisory locks)
    MySQLMysqlDatabaseProviderYes (via advisory locks)