Make Migrate3 idempotent against partial application

If Migrate3 has already applied its schema changes but failed to
bump user_version (e.g. process crashed between ALTER and
SetMigrationVersion), the next run currently hits a duplicate
column error because ALTER TABLE ADD COLUMN is not idempotent in
SQLite.

Detect the recovery case by checking for the presence of the v3
target columns and the absence of the dropped Code column, and
just record the migration version when found.
This commit is contained in:
2026-05-01 18:19:39 +02:00
parent 89e1da1211
commit 94064bf9e4
+24
View File
@@ -237,9 +237,33 @@ internal class MessageStore : IDisposable
SetMigrationVersion(2);
}
private bool ColumnExists(string table, string column)
{
using var cmd = Connection.CreateCommand();
cmd.CommandText = $"PRAGMA table_info({table});";
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
if (reader.GetString(1) == column)
return true;
}
return false;
}
private void Migrate3()
{
Plugin.Log.Information("Running migration 3: Fix log kinds to fit the new format");
// Recovery for partially-applied Migrate3: if the schema is already
// in its target shape (new columns exist, old Code column gone) but
// user_version was never bumped, just record the version and exit.
if (ColumnExists("messages", "ChatType") && !ColumnExists("messages", "Code"))
{
Plugin.Log.Information("Migration 3: schema already migrated, only bumping user_version");
SetMigrationVersion(3);
return;
}
Connection.Execute(@"
-- Migration 3: Fix log kinds to fit the new format
-- Add new ChatType, SourceKind, TargetKind (byte), SortCodeV2