moves db context to injection

This commit is contained in:
Philipp Häfelfinger 2023-09-02 12:03:29 +02:00
parent f705babdc3
commit 647a1e44bd
6 changed files with 62 additions and 54 deletions

View File

@ -4,22 +4,11 @@ namespace PiwigoDirectorySync.Persistence;
public class PersistenceContext : DbContext
{
public PersistenceContext(DbContextOptions<PersistenceContext> options) : base(options)
{
}
public DbSet<ServerEntity> PiwigoServers { get; set; } = null!;
public DbSet<AlbumEntity> PiwigoAlbums { get; set; } = null!;
public DbSet<ImageEntity> PiwigoImages { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
switch (AppSettings.Settings.DbProvider)
{
case "Sqlite":
options.UseSqlite(AppSettings.ConnectionString);
break;
case "InMemory":
options.UseInMemoryDatabase(AppSettings.ConnectionString);
break;
default:
throw new InvalidOperationException($"DbProvider {AppSettings.Settings.DbProvider} is not supported");
}
}
}

View File

@ -1,7 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync;
using PiwigoDirectorySync.Commands;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Persistence;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
@ -18,6 +21,15 @@ registrations.AddTransient<IFileIndexer, FileIndexer>();
registrations.AddTransient<IFileSystemScanner, FileSystemScanner>();
registrations.AddTransient<IAlbumSynchronizer, AlbumSynchronizer>();
registrations.AddTransient<IImageSynchronizer, ImageSynchronizer>();
registrations.AddDbContext<PersistenceContext>(options =>
{
_ = AppSettings.Settings.DbProvider switch
{
"Sqlite" => options.UseSqlite(AppSettings.ConnectionString),
"InMemory" => options.UseInMemoryDatabase(AppSettings.ConnectionString),
_ => throw new Exception($"Unsupported dbType: {AppSettings.Settings.DbProvider}")
};
});
var registrar = new DependencyInjectionTypeRegistrar(registrations);

View File

@ -10,18 +10,19 @@ namespace PiwigoDirectorySync.Services;
public class AlbumSynchronizer : IAlbumSynchronizer
{
private readonly ILogger<AlbumSynchronizer> _logger;
private readonly PersistenceContext _persistenceContext;
private readonly IPiwigoClientFactory _piwigoClientFactory;
public AlbumSynchronizer(ILogger<AlbumSynchronizer> logger, IPiwigoClientFactory piwigoClientFactory)
public AlbumSynchronizer(ILogger<AlbumSynchronizer> logger, IPiwigoClientFactory piwigoClientFactory, PersistenceContext persistenceContext)
{
_logger = logger;
_piwigoClientFactory = piwigoClientFactory;
_persistenceContext = persistenceContext;
}
public async Task SynchronizeAlbums(int piwigoServerId, CancellationToken ct)
{
await using var dbContext = new PersistenceContext();
var piwigoServer = await dbContext.PiwigoServers.FindAsync(new object?[] { piwigoServerId }, ct);
var piwigoServer = await _persistenceContext.PiwigoServers.FindAsync(new object?[] { piwigoServerId }, ct);
if (piwigoServer is null)
{
_logger.LogError("Could not sync albums with piwigo server {PiwigoServerId}", piwigoServerId);
@ -30,30 +31,30 @@ public class AlbumSynchronizer : IAlbumSynchronizer
var piwigoClient = await _piwigoClientFactory.GetPiwigoClientAsync(piwigoServer, ct);
await UpdatePiwigoAlbumsFromServerAsync(dbContext, piwigoClient, piwigoServer, ct);
await AddMissingAlbumsToServerAsync(dbContext, piwigoClient, piwigoServer, ct);
await UpdatePiwigoAlbumsFromServerAsync(piwigoClient, piwigoServer, ct);
await AddMissingAlbumsToServerAsync(piwigoClient, piwigoServer, ct);
}
private static async Task AddMissingAlbumsToServerAsync(PersistenceContext dbContext, IPiwigoClient piwigoClient, ServerEntity piwigoServer, CancellationToken ct)
private async Task AddMissingAlbumsToServerAsync(IPiwigoClient piwigoClient, ServerEntity piwigoServer, CancellationToken ct)
{
var albumsToCreate = await dbContext.PiwigoAlbums.Where(a => a.ServerAlbumId == null && a.ServerId == piwigoServer.Id)
var albumsToCreate = await _persistenceContext.PiwigoAlbums.Where(a => a.ServerAlbumId == null && a.ServerId == piwigoServer.Id)
.OrderBy(a => a.Path)
.Select(a => a.Id)
.ToListAsync(ct);
foreach (var albumId in albumsToCreate)
{
var albumEntity = await dbContext.PiwigoAlbums.GetByIdAsync(albumId, ct);
var piwigoParentId = albumEntity.ParentId.HasValue ? (await dbContext.PiwigoAlbums.GetByIdAsync(albumEntity.ParentId.Value, ct)).ServerAlbumId : null;
var albumEntity = await _persistenceContext.PiwigoAlbums.GetByIdAsync(albumId, ct);
var piwigoParentId = albumEntity.ParentId.HasValue ? (await _persistenceContext.PiwigoAlbums.GetByIdAsync(albumEntity.ParentId.Value, ct)).ServerAlbumId : null;
albumEntity.ServerAlbumId = await piwigoClient.Album.AddAsync(albumEntity.Name, piwigoParentId, visible: true, position: AlbumPosition.First,
status: AlbumStatus.Public, cancellationToken: ct);
await dbContext.SaveChangesAsync(ct);
await _persistenceContext.SaveChangesAsync(ct);
}
}
private async Task UpdatePiwigoAlbumsFromServerAsync(PersistenceContext dbContext, IPiwigoClient piwigoClient, ServerEntity piwigoServer, CancellationToken ct)
private async Task UpdatePiwigoAlbumsFromServerAsync(IPiwigoClient piwigoClient, ServerEntity piwigoServer, CancellationToken ct)
{
var serverAlbums = await piwigoClient.Album.GetListAsync(null, true, false, ThumbnailSize.Thumb, ct);
var serverAlbumDictionary = serverAlbums.ToDictionary(a => a.Id, a => a);
@ -62,21 +63,21 @@ public class AlbumSynchronizer : IAlbumSynchronizer
{
_logger.LogInformation("Updating piwigo server album {ServerAlbumName} with piwigo id {ServerAlbumId}", serverAlbum.Name, serverAlbum.Id);
var albumEntity = await GetOrAddPiwigoAlbumEntityFromServerAsync(dbContext, piwigoServer, serverAlbum, serverAlbumDictionary, ct);
var albumEntity = await GetOrAddPiwigoAlbumEntityFromServerAsync(piwigoServer, serverAlbum, serverAlbumDictionary, ct);
if (serverAlbum.IdUpperCat.HasValue)
{
albumEntity.ParentId = (await dbContext.PiwigoAlbums.FindByServerIdAsync(piwigoServer.Id, serverAlbum.IdUpperCat.Value, ct))?.Id;
albumEntity.ParentId = (await _persistenceContext.PiwigoAlbums.FindByServerIdAsync(piwigoServer.Id, serverAlbum.IdUpperCat.Value, ct))?.Id;
}
await dbContext.SaveChangesAsync(ct);
await _persistenceContext.SaveChangesAsync(ct);
}
}
private async Task<AlbumEntity> GetOrAddPiwigoAlbumEntityFromServerAsync(PersistenceContext dbContext, ServerEntity piwigoServer, Album serverAlbum,
IDictionary<int, Album> serverAlbumDictionary, CancellationToken ct)
private async Task<AlbumEntity> GetOrAddPiwigoAlbumEntityFromServerAsync(ServerEntity piwigoServer, Album serverAlbum, IDictionary<int, Album> serverAlbumDictionary,
CancellationToken ct)
{
// Already synchronized so it is easy to return
var albumEntity = await dbContext.PiwigoAlbums.FindByServerIdAsync(piwigoServer.Id, serverAlbum.Id, ct);
var albumEntity = await _persistenceContext.PiwigoAlbums.FindByServerIdAsync(piwigoServer.Id, serverAlbum.Id, ct);
if (albumEntity != null)
{
_logger.LogDebug("Found existing album {AlbumEntityName} with local id {AlbumEntityId} and piwigo server id {ServerAlbumId}", albumEntity.Name, albumEntity.Id,
@ -87,7 +88,7 @@ public class AlbumSynchronizer : IAlbumSynchronizer
// might exist already as the file system got scanned and created the local entries
// In this case we save the server id in our local album and link them.
var path = GeneratePath(serverAlbum, serverAlbumDictionary);
albumEntity = await dbContext.PiwigoAlbums.FindByServerAndPathAsync(piwigoServer.Id, path, ct);
albumEntity = await _persistenceContext.PiwigoAlbums.FindByServerAndPathAsync(piwigoServer.Id, path, ct);
if (albumEntity != null)
{
albumEntity.ServerAlbumId = serverAlbum.Id;
@ -106,7 +107,7 @@ public class AlbumSynchronizer : IAlbumSynchronizer
};
_logger.LogInformation("Adding piwigo album {AlbumEntityName} with local id {AlbumEntityId} and piwigo server id {ServerAlbumId}", albumEntity.Name, albumEntity.Id,
albumEntity.ServerAlbumId);
dbContext.PiwigoAlbums.Add(albumEntity);
_persistenceContext.PiwigoAlbums.Add(albumEntity);
return albumEntity;
}

View File

@ -10,10 +10,12 @@ public class FileIndexer : IFileIndexer
{
private readonly IList<string> _failedFiles = new List<string>();
private readonly ILogger<FileIndexer> _logger;
private readonly PersistenceContext _persistenceContext;
public FileIndexer(ILogger<FileIndexer> logger)
public FileIndexer(ILogger<FileIndexer> logger, PersistenceContext persistenceContext)
{
_logger = logger;
_persistenceContext = persistenceContext;
}
public int TotalFilesScanned { get; private set; }
@ -21,8 +23,7 @@ public class FileIndexer : IFileIndexer
public async Task StartProcessingAsync(Channel<string> fileQueue, int piwigoServerId, CancellationToken ct)
{
await using var db = new PersistenceContext();
var piwigoServer = await db.PiwigoServers.GetByIdAsync(piwigoServerId, ct);
var piwigoServer = await _persistenceContext.PiwigoServers.GetByIdAsync(piwigoServerId, ct);
await foreach (var fullFilePath in fileQueue.Reader.ReadAllAsync(ct))
{
@ -46,9 +47,9 @@ public class FileIndexer : IFileIndexer
var relativePath = Path.GetRelativePath(piwigoServer.RootDirectory, fullFilePath);
var album = await GetOrAddAlbumAsync(db, piwigoServer, fileInfo.Directory!, ct);
var album = await GetOrAddAlbumAsync(piwigoServer, fileInfo.Directory!, ct);
var image = await GetOrAddImageAsync(db, album, relativePath, ct);
var image = await GetOrAddImageAsync(album, relativePath, ct);
if (image.LastChange != fileInfo.LastWriteTimeUtc)
{
@ -59,7 +60,7 @@ public class FileIndexer : IFileIndexer
image.DeleteRequired = false;
image.LastChange = fileInfo.LastWriteTimeUtc;
await db.SaveChangesAsync(ct);
await _persistenceContext.SaveChangesAsync(ct);
TotalFilesScanned++;
}
@ -71,9 +72,9 @@ public class FileIndexer : IFileIndexer
}
}
private static async Task<ImageEntity> GetOrAddImageAsync(PersistenceContext db, AlbumEntity album, string relativePath, CancellationToken ct)
private async Task<ImageEntity> GetOrAddImageAsync(AlbumEntity album, string relativePath, CancellationToken ct)
{
var imageEntity = await db.PiwigoImages.Where(i => i.AlbumId == album.Id && i.FilePath == relativePath).FirstOrDefaultAsync(ct);
var imageEntity = await _persistenceContext.PiwigoImages.Where(i => i.AlbumId == album.Id && i.FilePath == relativePath).FirstOrDefaultAsync(ct);
if (imageEntity is null)
{
imageEntity = new ImageEntity
@ -84,16 +85,16 @@ public class FileIndexer : IFileIndexer
UploadRequired = true,
DeleteRequired = false
};
db.PiwigoImages.Add(imageEntity);
_persistenceContext.PiwigoImages.Add(imageEntity);
}
return imageEntity;
}
private async Task<AlbumEntity> GetOrAddAlbumAsync(PersistenceContext db, ServerEntity server, DirectoryInfo directory, CancellationToken ct)
private async Task<AlbumEntity> GetOrAddAlbumAsync(ServerEntity server, DirectoryInfo directory, CancellationToken ct)
{
var albumPath = Path.GetRelativePath(server.RootDirectory, directory.FullName);
var album = await db.PiwigoAlbums.FindByServerAndPathAsync(server.Id, albumPath, ct);
var album = await _persistenceContext.PiwigoAlbums.FindByServerAndPathAsync(server.Id, albumPath, ct);
if (album != null)
{
return album;
@ -106,7 +107,7 @@ public class FileIndexer : IFileIndexer
}
else
{
parentAlbum = await GetOrAddAlbumAsync(db, server, directory.Parent!, ct);
parentAlbum = await GetOrAddAlbumAsync(server, directory.Parent!, ct);
}
album = new AlbumEntity
@ -118,9 +119,9 @@ public class FileIndexer : IFileIndexer
ParentId = parentAlbum?.Id,
Parent = parentAlbum
};
db.PiwigoAlbums.Add(album);
_persistenceContext.PiwigoAlbums.Add(album);
await db.SaveChangesAsync(ct);
await _persistenceContext.SaveChangesAsync(ct);
return album;
}

View File

@ -7,18 +7,18 @@ namespace PiwigoDirectorySync.Services;
public class FileSystemScanner : IFileSystemScanner
{
private readonly ILogger<FileSystemScanner> _logger;
private readonly PersistenceContext _persistenceContext;
public FileSystemScanner(ILogger<FileSystemScanner> logger)
public FileSystemScanner(ILogger<FileSystemScanner> logger, PersistenceContext persistenceContext)
{
_logger = logger;
_persistenceContext = persistenceContext;
}
public async Task ScanAsync(Channel<string> fileQueue, int piwigoServerId, CancellationToken ct)
{
await using var db = new PersistenceContext();
var piwigoServer = await db.PiwigoServers.GetByIdAsync(piwigoServerId, ct);
var piwigoServer = await _persistenceContext.PiwigoServers.GetByIdAsync(piwigoServerId, ct);
_logger.LogInformation("Scanning files for piwigo server {PiwigoServerName} in directory {PiwigoServerRootDirectory}", piwigoServer.Name, piwigoServer.RootDirectory);
await ScanRootDirectory(fileQueue, new DirectoryInfo(piwigoServer.RootDirectory), ct);

View File

@ -2,5 +2,10 @@
public class ImageSynchronizer : IImageSynchronizer
{
public Task SynchronizeImages(int piwigoServerId, CancellationToken ct) => throw new NotImplementedException();
public Task SynchronizeImages(int piwigoServerId, CancellationToken ct)
{
throw new NotImplementedException();
}
}