mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-09-13 05:47:33 -04:00
75 lines
2.9 KiB
C#
75 lines
2.9 KiB
C#
using Cleanuparr.Domain.Enums;
|
|
using Cleanuparr.Persistence.Converters;
|
|
using Cleanuparr.Shared.Enums;
|
|
using Cleanuparr.Shared.Helpers;
|
|
using Microsoft.Data.Sqlite;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
|
|
namespace Cleanuparr.Persistence.Providers;
|
|
|
|
public sealed class SqliteDatabaseProvider : IDatabaseProvider
|
|
{
|
|
private const string MigrationsAssembly = "Cleanuparr.Persistence.Sqlite";
|
|
|
|
private static readonly IReadOnlyDictionary<DbContextKind, string> FileNames = new Dictionary<DbContextKind, string>
|
|
{
|
|
[DbContextKind.Data] = "cleanuparr.db",
|
|
[DbContextKind.Events] = "events.db",
|
|
[DbContextKind.Users] = "users.db",
|
|
};
|
|
|
|
public DatabaseProvider Kind => DatabaseProvider.Sqlite;
|
|
|
|
public void ConfigureContext(DbContextOptionsBuilder builder, DbContextKind kind)
|
|
{
|
|
string dbPath = Path.Combine(ConfigurationPathProvider.GetConfigPath(), FileNames[kind]);
|
|
builder
|
|
.UseSqlite($"Data Source={dbPath}", options => options.MigrationsAssembly(MigrationsAssembly))
|
|
.UseLowerCaseNamingConvention()
|
|
.UseSnakeCaseNamingConvention();
|
|
}
|
|
|
|
public string? GetSchema(DbContextKind kind) => null;
|
|
|
|
public string QualifyTable(string tableName, DbContextKind kind) => tableName;
|
|
|
|
public void ConfigureConventions(ModelConfigurationBuilder builder)
|
|
{
|
|
builder.Properties<DateTimeOffset>()
|
|
.HaveConversion<UtcDateTimeOffsetConverter>();
|
|
}
|
|
|
|
public string GetUnresolvedEventFilter() => "\"is_resolved\" = 0";
|
|
|
|
public async Task OnPostMigrateAsync(DatabaseFacade database, DbContextKind kind, CancellationToken cancellationToken)
|
|
{
|
|
if (kind == DbContextKind.Events)
|
|
{
|
|
await database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL;", cancellationToken);
|
|
}
|
|
}
|
|
|
|
public async Task PrepareBulkWriteAsync(DatabaseFacade database, CancellationToken cancellationToken)
|
|
{
|
|
await database.ExecuteSqlRawAsync("PRAGMA cache_size=-20000;", cancellationToken);
|
|
}
|
|
|
|
public async Task CheckpointAsync(DatabaseFacade database, CancellationToken cancellationToken)
|
|
{
|
|
await database.ExecuteSqlRawAsync("PRAGMA wal_checkpoint(TRUNCATE);", cancellationToken);
|
|
}
|
|
|
|
public string GetTimelineBucketExpr(TimelineBucketSize size) => size switch
|
|
{
|
|
TimelineBucketSize.Hour => "substr(timestamp, 1, 13)",
|
|
TimelineBucketSize.Day => "substr(timestamp, 1, 10)",
|
|
TimelineBucketSize.Week => "date(substr(timestamp, 1, 19), '-' || ((strftime('%w', substr(timestamp, 1, 19)) + 6) % 7) || ' days')",
|
|
TimelineBucketSize.Month => "strftime('%Y-%m-01', substr(timestamp, 1, 19))",
|
|
_ => throw new ArgumentOutOfRangeException(nameof(size), size, null),
|
|
};
|
|
|
|
public bool IsUniqueConstraintViolation(DbUpdateException exception) =>
|
|
exception.InnerException is SqliteException { SqliteErrorCode: 19 };
|
|
}
|