1
0
mirror of https://github.com/chylex/Discord-History-Tracker.git synced 2025-03-01 05:46:05 +01:00
Discord-History-Tracker/app/Server/Database/Sqlite/SqliteDatabaseFile.cs

90 lines
3.0 KiB
C#

using System.Collections.Generic;
using System.Threading.Tasks;
using DHT.Server.Data.Settings;
using DHT.Server.Database.Repositories;
using DHT.Server.Database.Sqlite.Repositories;
using DHT.Server.Database.Sqlite.Schema;
using DHT.Server.Database.Sqlite.Utils;
namespace DHT.Server.Database.Sqlite;
public sealed class SqliteDatabaseFile : IDatabaseFile {
private const int DefaultPoolSize = 5;
public static async Task<SqliteDatabaseFile?> OpenOrCreate(string path, ISchemaUpgradeCallbacks schemaUpgradeCallbacks) {
var connectionString = new SqliteConnectionStringFactory(path);
var attachedDatabaseCollector = new AttachedDatabaseCollector(path);
bool wasOpened;
await using (var conn = await CustomSqliteConnection.OpenUnpooled(connectionString)) {
wasOpened = await new SqliteSchema(conn).Setup(attachedDatabaseCollector, schemaUpgradeCallbacks);
}
if (wasOpened) {
var pool = await SqliteConnectionPool.Create(connectionString, DefaultPoolSize, attachedDatabaseCollector);
return new SqliteDatabaseFile(path, pool);
}
else {
return null;
}
}
private sealed class AttachedDatabaseCollector(string path) : ISqliteAttachedDatabaseCollector {
public async IAsyncEnumerable<AttachedDatabase> GetAttachedDatabases(ISqliteConnection conn) {
bool useSeparateFileForDownloads = await SqliteSettingsRepository.Get(conn, SettingsKey.SeparateFileForDownloads, defaultValue: false);
if (useSeparateFileForDownloads) {
yield return new AttachedDatabase(path + "_dl", SqliteDownloadRepository.Schema);
}
}
}
public string Path { get; }
public ISettingsRepository Settings => settings;
public IUserRepository Users => users;
public IServerRepository Servers => servers;
public IChannelRepository Channels => channels;
public IMessageRepository Messages => messages;
public IDownloadRepository Downloads => downloads;
private readonly SqliteConnectionPool pool;
private readonly SqliteSettingsRepository settings;
private readonly SqliteUserRepository users;
private readonly SqliteServerRepository servers;
private readonly SqliteChannelRepository channels;
private readonly SqliteMessageRepository messages;
private readonly SqliteDownloadRepository downloads;
private SqliteDatabaseFile(string path, SqliteConnectionPool pool) {
this.Path = path;
this.pool = pool;
downloads = new SqliteDownloadRepository(pool);
settings = new SqliteSettingsRepository(pool);
users = new SqliteUserRepository(pool, downloads);
servers = new SqliteServerRepository(pool);
channels = new SqliteChannelRepository(pool);
messages = new SqliteMessageRepository(pool, downloads);
}
public async ValueTask DisposeAsync() {
users.Dispose();
servers.Dispose();
channels.Dispose();
messages.Dispose();
downloads.Dispose();
await pool.DisposeAsync();
}
public async Task Vacuum() {
await using var conn = await pool.Take();
await conn.ExecuteAsync("VACUUM");
if (await conn.HasAttachedDatabase(SqliteDownloadRepository.Schema)) {
await conn.ExecuteAsync("VACUUM " + SqliteDownloadRepository.Schema);
}
}
}