public void Migrate() { var conn = _db.GetDbConnection(); conn.Open(); // get sqlite version var sqliteVersion = conn.ExecuteScalar <string>("SELECT SQLITE_VERSION();"); _logger.LogInformation($"SQLite DB engine version: {sqliteVersion}"); // get current db version // test if the table exists var dbVersion = 0; var hasMetaTable = conn.Query(@"SELECT name FROM sqlite_master WHERE name = 'META_INFO';").Any(); if (hasMetaTable) { dbVersion = conn.ExecuteScalar <int?>(@"SELECT m_value FROM META_INFO WHERE m_key = 'DB_VERSION';") ?? 0; } // run migrations var versionType = typeof(MigrationVersion); foreach (var migrationType in MigrationTypes) { try { var version = ((MigrationVersion)System.Attribute.GetCustomAttribute(migrationType, versionType)) .version; if (version == dbVersion + 1) { dbVersion++; var routine = (IMigrationRoutine)Activator.CreateInstance(migrationType); routine.Migrate(conn, _serviceProvider); } } catch (Exception e) { _logger.LogCritical($"Failed to run migration for {versionType.Name}: {e.Message}"); conn.Close(); Environment.Exit(-1); } } // clean up using var cleanupCommand = conn.CreateCommand(); cleanupCommand.CommandText = @" PRAGMA journal_mode=DELETE; VACUUM; PRAGMA journal_mode=WAL; "; cleanupCommand.ExecuteNonQuery(); conn.Close(); }