diff --git a/Content.IntegrationTests/PoolManager.Cvars.cs b/Content.IntegrationTests/PoolManager.Cvars.cs index b64ed526e3..d7f7044322 100644 --- a/Content.IntegrationTests/PoolManager.Cvars.cs +++ b/Content.IntegrationTests/PoolManager.Cvars.cs @@ -12,6 +12,7 @@ public static partial class PoolManager { // @formatter:off (CCVars.DatabaseSynchronous.Name, "true"), + (CCVars.DatabaseSnapshot.Name, "true"), (CCVars.DatabaseSqliteDelay.Name, "0"), (CCVars.HolidaysEnabled.Name, "false"), (CCVars.GameMap.Name, TestMap), diff --git a/Content.IntegrationTests/Tests/Preferences/ServerDbSqliteTests.cs b/Content.IntegrationTests/Tests/Preferences/ServerDbSqliteTests.cs index ad93e083fb..f4657010d3 100644 --- a/Content.IntegrationTests/Tests/Preferences/ServerDbSqliteTests.cs +++ b/Content.IntegrationTests/Tests/Preferences/ServerDbSqliteTests.cs @@ -64,7 +64,7 @@ namespace Content.IntegrationTests.Tests.Preferences var conn = new SqliteConnection("Data Source=:memory:"); conn.Open(); builder.UseSqlite(conn); - return new ServerDbSqlite(() => builder.Options, true, cfg, true, opsLog, serialization); + return new ServerDbSqlite(() => builder.Options, true, cfg, true, opsLog, serialization, false); } [Test] diff --git a/Content.Server/Database/ServerDbManager.cs b/Content.Server/Database/ServerDbManager.cs index 2fbddd6026..5e699c197b 100644 --- a/Content.Server/Database/ServerDbManager.cs +++ b/Content.Server/Database/ServerDbManager.cs @@ -421,6 +421,7 @@ namespace Content.Server.Database private ISawmill _sawmill = default!; private bool _synchronous; + private bool _snapshot; // When running in integration tests, we'll use a single in-memory SQLite database connection. // This is that connection, close it when we shut down. private SqliteConnection? _sqliteInMemoryConnection; @@ -437,6 +438,7 @@ namespace Content.Server.Database _sawmill = _logMgr.GetSawmill("db.manager"); _synchronous = _cfg.GetCVar(CCVars.DatabaseSynchronous); + _snapshot = _cfg.GetCVar(CCVars.DatabaseSnapshot); var engine = _cfg.GetCVar(CCVars.DatabaseEngine).ToLower(); var opsLog = _logMgr.GetSawmill("db.op"); @@ -445,7 +447,7 @@ namespace Content.Server.Database { case "sqlite": SetupSqlite(out var contextFunc, out var inMemory); - _db = new ServerDbSqlite(contextFunc, inMemory, _cfg, _synchronous, opsLog, _serialization); + _db = new ServerDbSqlite(contextFunc, inMemory, _cfg, _synchronous, opsLog, _serialization, _snapshot); break; case "postgres": var (pgOptions, conString) = CreatePostgresOptions(); diff --git a/Content.Server/Database/ServerDbSqlite.cs b/Content.Server/Database/ServerDbSqlite.cs index 97e265dbff..b7bc76032e 100644 --- a/Content.Server/Database/ServerDbSqlite.cs +++ b/Content.Server/Database/ServerDbSqlite.cs @@ -38,7 +38,8 @@ namespace Content.Server.Database IConfigurationManager cfg, bool synchronous, ISawmill opsLog, - ISerializationManager serialization) + ISerializationManager serialization, + bool snapshot) : base(opsLog, serialization) { _options = options; @@ -51,7 +52,12 @@ namespace Content.Server.Database if (synchronous) { - prefsCtx.Database.Migrate(); + // EnsureCreated means you can't apply migrations later, fine for tests + if (snapshot) + prefsCtx.Database.EnsureCreated(); + else + prefsCtx.Database.Migrate(); + _dbReadyTask = Task.CompletedTask; prefsCtx.Dispose(); } diff --git a/Content.Shared/CCVar/CCVars.Database.cs b/Content.Shared/CCVar/CCVars.Database.cs index c549bd7e03..c6deb73339 100644 --- a/Content.Shared/CCVar/CCVars.Database.cs +++ b/Content.Shared/CCVar/CCVars.Database.cs @@ -74,4 +74,12 @@ public sealed partial class CCVars /// public static readonly CVarDef DatabaseSynchronous = CVarDef.Create("database.sync", false, CVar.SERVERONLY); + + /// + /// Creates the SQLite database using EnsureCreated instead of Migrate, if using SQLite. + /// Setting this to true means you cannot apply migrations later. + /// Meant to be used in integration tests only. + /// + public static readonly CVarDef DatabaseSnapshot = + CVarDef.Create("database.snapshot", false, CVar.SERVERONLY); }