diff --git a/PiwigoDirectorySync/Persistence/PersistenceContext.cs b/PiwigoDirectorySync/Persistence/PersistenceContext.cs index deab50d..c0a4944 100644 --- a/PiwigoDirectorySync/Persistence/PersistenceContext.cs +++ b/PiwigoDirectorySync/Persistence/PersistenceContext.cs @@ -4,22 +4,11 @@ namespace PiwigoDirectorySync.Persistence; public class PersistenceContext : DbContext { + public PersistenceContext(DbContextOptions options) : base(options) + { + } + public DbSet PiwigoServers { get; set; } = null!; public DbSet PiwigoAlbums { get; set; } = null!; public DbSet 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"); - } - } } \ No newline at end of file diff --git a/PiwigoDirectorySync/Program.cs b/PiwigoDirectorySync/Program.cs index 933ec69..3f37f03 100644 --- a/PiwigoDirectorySync/Program.cs +++ b/PiwigoDirectorySync/Program.cs @@ -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(); registrations.AddTransient(); registrations.AddTransient(); registrations.AddTransient(); +registrations.AddDbContext(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); diff --git a/PiwigoDirectorySync/Services/AlbumSynchronizer.cs b/PiwigoDirectorySync/Services/AlbumSynchronizer.cs index fc0e759..03c3a43 100644 --- a/PiwigoDirectorySync/Services/AlbumSynchronizer.cs +++ b/PiwigoDirectorySync/Services/AlbumSynchronizer.cs @@ -10,18 +10,19 @@ namespace PiwigoDirectorySync.Services; public class AlbumSynchronizer : IAlbumSynchronizer { private readonly ILogger _logger; + private readonly PersistenceContext _persistenceContext; private readonly IPiwigoClientFactory _piwigoClientFactory; - public AlbumSynchronizer(ILogger logger, IPiwigoClientFactory piwigoClientFactory) + public AlbumSynchronizer(ILogger 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 GetOrAddPiwigoAlbumEntityFromServerAsync(PersistenceContext dbContext, ServerEntity piwigoServer, Album serverAlbum, - IDictionary serverAlbumDictionary, CancellationToken ct) + private async Task GetOrAddPiwigoAlbumEntityFromServerAsync(ServerEntity piwigoServer, Album serverAlbum, IDictionary 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; } diff --git a/PiwigoDirectorySync/Services/FileIndexer.cs b/PiwigoDirectorySync/Services/FileIndexer.cs index ed694ee..7b76cd1 100644 --- a/PiwigoDirectorySync/Services/FileIndexer.cs +++ b/PiwigoDirectorySync/Services/FileIndexer.cs @@ -10,10 +10,12 @@ public class FileIndexer : IFileIndexer { private readonly IList _failedFiles = new List(); private readonly ILogger _logger; + private readonly PersistenceContext _persistenceContext; - public FileIndexer(ILogger logger) + public FileIndexer(ILogger 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 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 GetOrAddImageAsync(PersistenceContext db, AlbumEntity album, string relativePath, CancellationToken ct) + private async Task 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 GetOrAddAlbumAsync(PersistenceContext db, ServerEntity server, DirectoryInfo directory, CancellationToken ct) + private async Task 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; } diff --git a/PiwigoDirectorySync/Services/FileSystemScanner.cs b/PiwigoDirectorySync/Services/FileSystemScanner.cs index f582fd3..665a232 100644 --- a/PiwigoDirectorySync/Services/FileSystemScanner.cs +++ b/PiwigoDirectorySync/Services/FileSystemScanner.cs @@ -7,18 +7,18 @@ namespace PiwigoDirectorySync.Services; public class FileSystemScanner : IFileSystemScanner { private readonly ILogger _logger; + private readonly PersistenceContext _persistenceContext; - public FileSystemScanner(ILogger logger) + public FileSystemScanner(ILogger logger, PersistenceContext persistenceContext) { _logger = logger; + _persistenceContext = persistenceContext; } public async Task ScanAsync(Channel 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); diff --git a/PiwigoDirectorySync/Services/ImageSynchronizer.cs b/PiwigoDirectorySync/Services/ImageSynchronizer.cs index 151ac5a..785c3e7 100644 --- a/PiwigoDirectorySync/Services/ImageSynchronizer.cs +++ b/PiwigoDirectorySync/Services/ImageSynchronizer.cs @@ -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(); + } } \ No newline at end of file