Starting to implement a dispose pattern for the library manager/repositories

This commit is contained in:
Zoe Roux 2020-06-11 16:46:17 +02:00
parent b0eab43d52
commit d34a6fd75a
6 changed files with 77 additions and 14 deletions

View File

@ -1,11 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Kyoo.Models;
namespace Kyoo.Controllers
{
public interface ILibraryManager
public interface ILibraryManager : IDisposable, IAsyncDisposable
{
// Get by slug
Task<Library> GetLibrary(string slug);

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
@ -5,7 +6,7 @@ using Kyoo.Models;
namespace Kyoo.Controllers
{
public interface IRepository<T>
public interface IRepository<T> : IDisposable, IAsyncDisposable
{
Task<T> Get(int id);
Task<T> Get(string slug);

View File

@ -0,0 +1,14 @@
using System;
namespace Kyoo.Models.Exceptions
{
public class DuplicatedItemException : Exception
{
public override string Message { get; }
public DuplicatedItemException(string message)
{
Message = message;
}
}
}

View File

@ -40,6 +40,28 @@ namespace Kyoo.Controllers
_providers = providers;
_people = people;
}
public void Dispose()
{
_libraries?.Dispose();
_collections?.Dispose();
_shows?.Dispose();
_seasons?.Dispose();
_episodes?.Dispose();
_tracks?.Dispose();
_genres?.Dispose();
_studios?.Dispose();
_people?.Dispose();
_providers?.Dispose();
}
public async ValueTask DisposeAsync()
{
return ValueTask.(new []
{
_libraries.DisposeAsync()
});
}
public Task<Library> GetLibrary(string slug)
{

View File

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Kyoo.Models;
using Kyoo.Models.Exceptions;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace Kyoo.Controllers
{
@ -45,9 +46,19 @@ namespace Kyoo.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
await _database.Collections.AddAsync(obj);
await _database.SaveChangesAsync();
try
{
await _database.Collections.AddAsync(obj);
await _database.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
if (ex.InnerException is PostgresException inner && inner.SqlState == PostgresErrorCodes.UniqueViolation)
throw new DuplicatedItemException($"Trying to insert a duplicated collection (slug {obj.Slug} already exists).");
throw;
}
return obj.ID;
}
@ -59,7 +70,17 @@ namespace Kyoo.Controllers
Collection old = await Get(obj.Slug);
if (old != null)
return old.ID;
return await Create(obj);
try
{
return await Create(obj);
}
catch (DuplicatedItemException)
{
old = await Get(obj.Slug);
if (old == null)
throw new SystemException("Unknown database state.");
return old.ID;
}
}
public async Task Edit(Collection edited, bool resetOld)

View File

@ -63,6 +63,10 @@ namespace Kyoo.Controllers
await libraryManager.DeleteEpisode(episode);
}
// TODO replace this grotesque way to load the providers.
foreach (Library library in libraries)
library.Providers = library.Providers;
await Task.WhenAll(libraries.Select(x => Scan(x, episodes, cancellationToken)));
}
catch (Exception ex)
@ -72,7 +76,7 @@ namespace Kyoo.Controllers
Console.WriteLine("Scan finished!");
}
private Task Scan(Library library, ICollection<Episode> episodes, CancellationToken cancellationToken)
private Task Scan(Library library, IEnumerable<Episode> episodes, CancellationToken cancellationToken)
{
Console.WriteLine($"Scanning library {library.Name} at {string.Join(", ", library.Paths)}.");
return Task.WhenAll(library.Paths.Select(async path =>
@ -106,16 +110,16 @@ namespace Kyoo.Controllers
return Task.CompletedTask;
}
// return Task.WhenAll(files.Select(file =>
foreach (string file in files)
return Task.WhenAll(files.Select(file =>
//foreach (string file in files)
{
if (!IsVideo(file) || episodes.Any(x => x.Path == file))
continue; //return Task.CompletedTask;
/*continue;*/ return Task.CompletedTask;
string relativePath = file.Substring(path.Length);
/*return*/ await RegisterFile(file, relativePath, library, cancellationToken);
}//));
return /*await*/ RegisterFile(file, relativePath, library, cancellationToken);
}));
return Task.CompletedTask;
// return Task.CompletedTask;
}));
}