Skip to content

Instantly share code, notes, and snippets.

@praeclarum
Created August 30, 2020 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save praeclarum/58ca31d0d8675db6f340e85c56a4cbc1 to your computer and use it in GitHub Desktop.
Save praeclarum/58ca31d0d8675db6f340e85c56a4cbc1 to your computer and use it in GitHub Desktop.
Database migrations using Dapper
using System;
using System.Linq;
using Microsoft.Extensions.Logging;
using Dapper;
namespace Data
{
public class Migrations
{
private readonly Database database;
private readonly ILogger<Migrations> logger;
public Migrations(Database database, ILogger<Migrations> logger)
{
this.database = database;
this.logger = logger;
}
public void CreateUserTable_1()
{
database.Connection.Execute(@"create table AppUser(
Id uuid not null primary key,
LowerUsername text not null unique,
Username text not null unique,
CreatedUtc timestamp not null,
PasswordHash text not null);");
}
// More migrations
public void Run()
{
logger.LogInformation("Starting migrations");
var type = GetType();
var methsq =
from m in type.GetMethods()
where m.GetParameters().Length == 0
let s = m.Name.Split("_")
where s.Length == 2
let version = int.Parse(s[1])
orderby version
select (m, version);
var meths = methsq.ToArray();
var dbversion = GetDatabaseVersion();
logger.LogInformation("Database is at version: " + dbversion);
try
{
foreach (var (m, v) in methsq)
{
if (v <= dbversion)
continue;
logger.LogInformation("Applying migration: " + m.Name);
m.Invoke(this, null);
dbversion = v;
}
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to complete migration");
}
logger.LogInformation("Migrated to version: {0}", dbversion);
database.Connection.Execute("update _DbVersion set Version=@v",
new { v = dbversion });
logger.LogInformation("Done migrating");
}
class DbVersion
{
public int Version = 0;
}
int GetDatabaseVersion()
{
database.Connection.Execute("create table if not exists _DbVersion(Version int not null);");
var r = database.Connection.Query<DbVersion>("SELECT Version FROM _DbVersion").ToArray();
if (r.Length > 0)
return r[0].Version;
var v = -1;
database.Connection.Execute("insert into _DbVersion values (@v)",
new { v = v });
return v;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment