using Microsoft.Extensions.Logging; using SharpChat.Configuration; using SharpChat.Messages; using SharpChat.Storage; using System.Data.SQLite; using ZLogger; using NativeSQLiteConnection = System.Data.SQLite.SQLiteConnection; namespace SharpChat.SQLite; public class SQLiteStorage(ILogger logger, string connString) : StorageBackend, IDisposable { public const string MEMORY = "file::memory:?cache=shared"; public const string DEFAULT = "sharpchat.db"; public SQLiteConnection Connection { get; } = new SQLiteConnection(new NativeSQLiteConnection(connString).OpenAndReturn()); public MessageStorage CreateMessageStorage() { return new SQLiteMessageStorage(logger, Connection); } public async Task UpgradeStorage() { logger.ZLogInformation($"Upgrading storage..."); await new SQLiteMigrations(logger, Connection).RunMigrations(); } public static string BuildConnectionString(Config config, bool journalling = true) { return BuildConnectionString( config.ReadValue("path", DEFAULT)!, config.ReadValue("pass"), config.ReadValue("journal", journalling) ); } public static string BuildConnectionString(string path, string? password, bool journalling = true) { return new SQLiteConnectionStringBuilder { DataSource = string.IsNullOrWhiteSpace(path) ? MEMORY : path, DateTimeFormat = SQLiteDateFormats.ISO8601, DateTimeKind = DateTimeKind.Utc, FailIfMissing = false, ForeignKeys = true, JournalMode = journalling ? SQLiteJournalModeEnum.Wal : SQLiteJournalModeEnum.Off, LegacyFormat = false, Password = string.IsNullOrWhiteSpace(password) ? null : password, ReadOnly = false, UseUTF16Encoding = false, }.ToString(); } private bool disposed = false; ~SQLiteStorage() { DoDispose(); } public void Dispose() { DoDispose(); GC.SuppressFinalize(this); } private void DoDispose() { if(disposed) return; disposed = true; Connection.Dispose(); } }