Files
annotations/Azaion.Common/Database/DbFactory.cs
T
Alex Bezdieniezhnykh 48c9ccbfda add db WIP 2, 80%
refactor, renames
2024-12-24 06:07:13 +02:00

109 lines
3.5 KiB
C#

using System.Data.SQLite;
using System.Diagnostics;
using System.IO;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using LinqToDB;
using LinqToDB.DataProvider.SQLite;
using LinqToDB.Mapping;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Azaion.Common.Database;
public interface IDbFactory
{
Task<T> Run<T>(Func<AnnotationsDb, Task<T>> func);
Task Run(Func<AnnotationsDb, Task> func);
void SaveToDisk();
}
public class DbFactory : IDbFactory
{
private readonly AnnotationConfig _annConfig;
private string MemoryConnStr => "Data Source=:memory:";
private readonly SQLiteConnection _memoryConnection;
private readonly DataOptions _memoryDataOptions;
private string FileConnStr => $"Data Source={_annConfig.AnnotationsDbFile}";
private readonly SQLiteConnection _fileConnection;
private readonly DataOptions _fileDataOptions;
public DbFactory(IOptions<AnnotationConfig> annConfig, ILogger<DbFactory> logger)
{
_annConfig = annConfig.Value;
_memoryConnection = new SQLiteConnection(MemoryConnStr);
_memoryConnection.Open();
_memoryDataOptions = new DataOptions()
.UseDataProvider(SQLiteTools.GetDataProvider())
.UseConnection(_memoryConnection)
.UseMappingSchema(AnnotationsDbSchemaHolder.MappingSchema);
_ = _memoryDataOptions.UseTracing(TraceLevel.Info, t => logger.LogInformation(t.SqlText));
_fileConnection = new SQLiteConnection(FileConnStr);
_fileDataOptions = new DataOptions()
.UseDataProvider(SQLiteTools.GetDataProvider())
.UseConnection(_fileConnection)
.UseMappingSchema(AnnotationsDbSchemaHolder.MappingSchema);
_ = _fileDataOptions.UseTracing(TraceLevel.Info, t => logger.LogInformation(t.SqlText));
if (!File.Exists(_annConfig.AnnotationsDbFile))
CreateDb();
_fileConnection.Open();
_fileConnection.BackupDatabase(_memoryConnection, "main", "main", -1, null, -1);
}
private void CreateDb()
{
SQLiteConnection.CreateFile(_annConfig.AnnotationsDbFile);
using var db = new AnnotationsDb(_fileDataOptions);
db.CreateTable<Annotation>();
db.CreateTable<AnnotationName>();
db.CreateTable<Detection>();
}
public async Task<T> Run<T>(Func<AnnotationsDb, Task<T>> func)
{
await using var db = new AnnotationsDb(_memoryDataOptions);
return await func(db);
}
public async Task Run(Func<AnnotationsDb, Task> func)
{
await using var db = new AnnotationsDb(_memoryDataOptions);
await func(db);
}
public void SaveToDisk()
{
_memoryConnection.BackupDatabase(_fileConnection, "main", "main", -1, null, -1);
}
}
public static class AnnotationsDbSchemaHolder
{
public static readonly MappingSchema MappingSchema;
static AnnotationsDbSchemaHolder()
{
MappingSchema = new MappingSchema();
var builder = new FluentMappingBuilder(MappingSchema);
builder.Entity<Annotation>()
.HasTableName(Constants.ANNOTATIONS_TABLENAME)
.HasPrimaryKey(x => x.Name)
.Association(a => a.Detections, (a, d) => a.Name == d.AnnotationName);
builder.Entity<Detection>()
.HasTableName(Constants.DETECTIONS_TABLENAME);
builder.Entity<AnnotationName>()
.HasTableName(Constants.ANNOTATIONS_QUEUE_TABLENAME);
builder.Build();
}
}