如果需要检查表中是否已存在列,如果不存在则添加它。在应用程序中检查它是 NOT ,因为迁移会连续调用sql脚本/文件。如果我们向数据库添加一个新列,那么当应用程序(带有新版本)为startet时,该列应自动添加。
我有两个SQL Statements
:
skiptime
添加到recipes
ALTER TABLE recipes ADD COLUMN skiptime INTEGER NOT NULL DEFAULT 5;
Column
是否已存在SELECT * FROM sqlite_master WHERE type = 'table' AND name = 'recipes' AND sql LIKE '%skiptime%'
我得到的结果取决于column
是否存在。现在我想结合这两个陈述。但我不知道如何。
RunMigrations()
在Application
启动时被调用一次。
ProviderInvariantName
可以是SQLite
或PostgreSQL
。
/// <summary>
/// Reads all ressource names from the assembly and saves those containing the db namespace in a private list
/// </summary>
private void _CacheDbRessources()
{
_RessourcesNamespace = $"FooName.Data.{_ProviderInvariantName}";
_RessourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames().Where(item => item.Contains(_RessourcesNamespace));
}
/// <summary>
/// Does the first-time setup for the database and runs migrations.
/// </summary>
private void _RunMigrations()
{
IEnumerable<string> migrations =
_RessourceNames.Where(item => item.Contains("_Migrations"))
.Select(s => s.Replace(_RessourcesNamespace + ".", ""))
.OrderBy(item => item);
if (migrations.Any())
_Logger.Debug("Running database migrations...");
using (DbConnection conn = GetConnection())
{
foreach (string item in migrations)
{
using (DbTransaction tran = conn.BeginTransaction())
{
_Logger.Debug("Executing query '{0}'...", item);
using (DbCommand cmd = conn.CreateCommand(GetQueryResource(item), tran))
{
int rows = cmd.ExecuteNonQuery();
_Logger.Debug($"{rows} rows where affected.");
}
tran.Commit();
}
}
}
}
/* users */
CREATE TABLE IF NOT EXISTS "users" (
"ident" INTEGER PRIMARY KEY AUTOINCREMENT,
"user_name" TEXT NOT NULL UNIQUE,
"real_name" TEXT,
"password" TEXT NOT NULL,
"userlevel" INTEGER NOT NULL DEFAULT 0,
"enabled" INTEGER NOT NULL DEFAULT 1,
"language" TEXT,
"lock" TEXT
);
/* users */
CREATE TABLE IF NOT EXISTS "users" (
"ident" SERIAL PRIMARY KEY,
"user_name" TEXT NOT NULL UNIQUE,
"real_name" TEXT,
"password" TEXT NOT NULL,
"userlevel" INTEGER NOT NULL DEFAULT 0,
"enabled" INTEGER NOT NULL DEFAULT 1,
"language" TEXT,
"lock" TEXT
);