mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:06:30 +00:00
a493606f64
fix publishing
151 lines
5.2 KiB
C#
151 lines
5.2 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.Data;
|
|
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();
|
|
Task DeleteAnnotations(List<Annotation> annotations, CancellationToken cancellationToken = default);
|
|
Task DeleteAnnotations(List<string> annotationNames, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
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)
|
|
;//.UseTracing(TraceLevel.Info, t => logger.LogInformation(t.SqlText));
|
|
|
|
|
|
_fileConnection = new SQLiteConnection(FileConnStr);
|
|
_fileDataOptions = new DataOptions()
|
|
.UseDataProvider(SQLiteTools.GetDataProvider())
|
|
.UseConnection(_fileConnection)
|
|
.UseMappingSchema(AnnotationsDbSchemaHolder.MappingSchema);
|
|
|
|
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>();
|
|
db.CreateTable<QueueOffset>();
|
|
db.QueueOffsets.BulkCopy(new List<QueueOffset>
|
|
{
|
|
new()
|
|
{
|
|
Offset = 0,
|
|
QueueName = Constants.MQ_ANNOTATIONS_QUEUE
|
|
},
|
|
new()
|
|
{
|
|
Offset = 0,
|
|
QueueName = Constants.MQ_ANNOTATIONS_CONFIRM_QUEUE
|
|
}
|
|
});
|
|
}
|
|
|
|
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 async Task DeleteAnnotations(List<Annotation> annotations, CancellationToken cancellationToken = default)
|
|
{
|
|
var names = annotations.Select(x => x.Name).ToList();
|
|
await DeleteAnnotations(names, cancellationToken);
|
|
}
|
|
|
|
public async Task DeleteAnnotations(List<string> annotationNames, CancellationToken cancellationToken = default)
|
|
{
|
|
await Run(async db =>
|
|
{
|
|
var detDeleted = await db.Detections.DeleteAsync(x => annotationNames.Contains(x.AnnotationName), token: cancellationToken);
|
|
var annDeleted = await db.Annotations.DeleteAsync(x => annotationNames.Contains(x.Name), token: cancellationToken);
|
|
Console.WriteLine($"Deleted {detDeleted} detections, {annDeleted} annotations");
|
|
});
|
|
SaveToDisk();
|
|
}
|
|
}
|
|
|
|
public static class AnnotationsDbSchemaHolder
|
|
{
|
|
public static readonly MappingSchema MappingSchema;
|
|
|
|
static AnnotationsDbSchemaHolder()
|
|
{
|
|
MappingSchema = new MappingSchema();
|
|
var builder = new FluentMappingBuilder(MappingSchema);
|
|
|
|
var annotationBuilder = builder.Entity<Annotation>();
|
|
annotationBuilder.HasTableName(Constants.ANNOTATIONS_TABLENAME)
|
|
.HasPrimaryKey(x => x.Name)
|
|
.Association(a => a.Detections, (a, d) => a.Name == d.AnnotationName)
|
|
.Property(x => x.Time).HasDataType(DataType.Int64).HasConversion(ts => ts.Ticks, t => new TimeSpan(t));
|
|
|
|
annotationBuilder
|
|
.Ignore(x => x.Milliseconds)
|
|
.Ignore(x => x.Classes)
|
|
.Ignore(x => x.Classes)
|
|
.Ignore(x => x.ImagePath)
|
|
.Ignore(x => x.LabelPath)
|
|
.Ignore(x => x.ThumbPath);
|
|
|
|
builder.Entity<Detection>()
|
|
.HasTableName(Constants.DETECTIONS_TABLENAME);
|
|
|
|
builder.Entity<AnnotationName>()
|
|
.HasTableName(Constants.ANNOTATIONS_QUEUE_TABLENAME);
|
|
|
|
builder.Build();
|
|
}
|
|
}
|