using System.Data.Common; using System.Data.SQLite; using NativeSQLiteConnection = System.Data.SQLite.SQLiteConnection; namespace SharpChat.SQLite; public class SQLiteConnection(NativeSQLiteConnection conn) : IDisposable { public NativeSQLiteConnection Connection { get; } = conn; public async Task<int> RunCommand(string command, params SQLiteParameter[] parameters) { using SQLiteCommand cmd = Connection.CreateCommand(); cmd.Parameters.Clear(); if(parameters?.Length > 0) cmd.Parameters.AddRange(parameters); cmd.CommandText = command; return await cmd.ExecuteNonQueryAsync(); } public async Task<DbDataReader?> RunQuery(string command, params SQLiteParameter[] parameters) { using SQLiteCommand cmd = Connection.CreateCommand(); cmd.Parameters.Clear(); if(parameters?.Length > 0) cmd.Parameters.AddRange(parameters); cmd.CommandText = command; return await cmd.ExecuteReaderAsync(); } public async Task<T> RunQueryValue<T>(string command, params SQLiteParameter[] parameters) where T : struct { using SQLiteCommand cmd = Connection.CreateCommand(); cmd.Parameters.Clear(); if(parameters?.Length > 0) cmd.Parameters.AddRange(parameters); cmd.CommandText = command; await cmd.PrepareAsync(); object? raw = await cmd.ExecuteScalarAsync(); return raw is T value ? value : default; } private bool disposed = false; ~SQLiteConnection() { DoDispose(); } public void Dispose() { DoDispose(); GC.SuppressFinalize(this); } private void DoDispose() { if(disposed) return; disposed = true; RunCommand("VACUUM").Wait(); Connection.Dispose(); } }