diff --git a/Kyoo.SqLite/SqLiteContext.cs b/Kyoo.SqLite/SqLiteContext.cs
index ca1a651e..1a2a392a 100644
--- a/Kyoo.SqLite/SqLiteContext.cs
+++ b/Kyoo.SqLite/SqLiteContext.cs
@@ -119,7 +119,8 @@ namespace Kyoo.SqLite
///
protected override bool IsDuplicateException(Exception ex)
{
- return ex.InnerException is SqliteException { SqliteExtendedErrorCode: 2067 /*SQLITE_CONSTRAINT_UNIQUE*/};
+ return ex.InnerException is SqliteException { SqliteExtendedErrorCode: 2067 /*SQLITE_CONSTRAINT_UNIQUE*/}
+ or SqliteException { SqliteExtendedErrorCode: 1555 /*SQLITE_CONSTRAINT_PRIMARYKEY*/};
}
///
diff --git a/Kyoo.Tests/Library/RepositoryActivator.cs b/Kyoo.Tests/Library/RepositoryActivator.cs
index 0d2dda01..42468a49 100644
--- a/Kyoo.Tests/Library/RepositoryActivator.cs
+++ b/Kyoo.Tests/Library/RepositoryActivator.cs
@@ -24,9 +24,7 @@ namespace Kyoo.Tests
StudioRepository studio = new(_database);
PeopleRepository people = new(_database, provider,
new Lazy(() => LibraryManager.ShowRepository));
- ShowRepository show = new(_database, studio, people, genre, provider,
- new Lazy(() => LibraryManager.SeasonRepository),
- new Lazy(() => LibraryManager.EpisodeRepository));
+ ShowRepository show = new(_database, studio, people, genre, provider);
SeasonRepository season = new(_database, provider, show,
new Lazy(() => LibraryManager.EpisodeRepository));
LibraryItemRepository libraryItem = new(_database,
diff --git a/Kyoo.Tests/Library/RepositoryTests.cs b/Kyoo.Tests/Library/RepositoryTests.cs
index 16bc4fa9..e8504a16 100644
--- a/Kyoo.Tests/Library/RepositoryTests.cs
+++ b/Kyoo.Tests/Library/RepositoryTests.cs
@@ -74,5 +74,17 @@ namespace Kyoo.Tests
await _repository.Delete(TestSample.Get());
Assert.Equal(0, await _repository.GetCount());
}
+
+ [Fact]
+ public async Task CreateTest()
+ {
+ await Assert.ThrowsAsync(() => _repository.Create(TestSample.Get()));
+ await _repository.Delete(TestSample.Get());
+
+ T expected = TestSample.Get();
+ expected.ID = 0;
+ await _repository.Create(expected);
+ KAssert.DeepEqual(expected, await _repository.Get(expected.Slug));
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo.Tests/Library/SpecificTests/GlobalTests.cs b/Kyoo.Tests/Library/SpecificTests/GlobalTests.cs
index 284c2ad7..57b8c4c3 100644
--- a/Kyoo.Tests/Library/SpecificTests/GlobalTests.cs
+++ b/Kyoo.Tests/Library/SpecificTests/GlobalTests.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Kyoo.Models;
@@ -5,12 +7,25 @@ using Xunit;
namespace Kyoo.Tests.SpecificTests
{
- public class GlobalTests
+ public class GlobalTests : IDisposable, IAsyncDisposable
{
+ private readonly RepositoryActivator _repositories;
+
+ public GlobalTests()
+ {
+ _repositories = new RepositoryActivator();
+ }
+
+ [Fact]
+ [SuppressMessage("ReSharper", "EqualExpressionComparison")]
+ public void SampleTest()
+ {
+ Assert.False(ReferenceEquals(TestSample.Get(), TestSample.Get()));
+ }
+
[Fact]
public async Task DeleteShowWithEpisodeAndSeason()
{
- RepositoryActivator repositories = new();
Show show = TestSample.Get();
show.Seasons = new[]
{
@@ -20,13 +35,24 @@ namespace Kyoo.Tests.SpecificTests
{
TestSample.Get()
};
- await repositories.Context.AddAsync(show);
+ await _repositories.Context.AddAsync(show);
- Assert.Equal(1, await repositories.LibraryManager.ShowRepository.GetCount());
- await repositories.LibraryManager.ShowRepository.Delete(show);
- Assert.Equal(0, await repositories.LibraryManager.ShowRepository.GetCount());
- Assert.Equal(0, await repositories.LibraryManager.SeasonRepository.GetCount());
- Assert.Equal(0, await repositories.LibraryManager.EpisodeRepository.GetCount());
+ Assert.Equal(1, await _repositories.LibraryManager.ShowRepository.GetCount());
+ await _repositories.LibraryManager.ShowRepository.Delete(show);
+ Assert.Equal(0, await _repositories.LibraryManager.ShowRepository.GetCount());
+ Assert.Equal(0, await _repositories.LibraryManager.SeasonRepository.GetCount());
+ Assert.Equal(0, await _repositories.LibraryManager.EpisodeRepository.GetCount());
+ }
+
+ public void Dispose()
+ {
+ _repositories.Dispose();
+ GC.SuppressFinalize(this);
+ }
+
+ public ValueTask DisposeAsync()
+ {
+ return _repositories.DisposeAsync();
}
}
}
\ No newline at end of file
diff --git a/Kyoo.Tests/Library/SpecificTests/ShowTests.cs b/Kyoo.Tests/Library/SpecificTests/ShowTests.cs
index 5cfcfea2..c49ca824 100644
--- a/Kyoo.Tests/Library/SpecificTests/ShowTests.cs
+++ b/Kyoo.Tests/Library/SpecificTests/ShowTests.cs
@@ -178,5 +178,43 @@ namespace Kyoo.Tests.SpecificTests
Assert.Null(edited.Genres);
Assert.Null(edited.Studio);
}
+
+ [Fact]
+ public async Task CreateWithRelationsTest()
+ {
+ Show expected = TestSample.Get();
+ expected.ID = 0;
+ expected.Slug = "created-relation-test";
+ expected.ExternalIDs = new[]
+ {
+ new MetadataID
+ {
+ First = expected,
+ Second = new Provider("provider", "provider.png"),
+ DataID = "ID"
+ }
+ };
+ expected.Genres = new[]
+ {
+ new Genre
+ {
+ Name = "Genre",
+ Slug = "genre"
+ }
+ };
+ expected.People = new[]
+ {
+ new PeopleRole
+ {
+ People = TestSample.Get(),
+ Show = expected,
+ ForPeople = false,
+ Role = "actor"
+ }
+ };
+ expected.Studio = new Studio("studio");
+ Show created = await _repository.Create(expected);
+ KAssert.DeepEqual(expected, created);
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo.Tests/Library/TestContext.cs b/Kyoo.Tests/Library/TestContext.cs
index a3d2a51e..30f8beb5 100644
--- a/Kyoo.Tests/Library/TestContext.cs
+++ b/Kyoo.Tests/Library/TestContext.cs
@@ -93,6 +93,7 @@ namespace Kyoo.Tests
public void Dispose()
{
_connection.Close();
+ GC.SuppressFinalize(this);
}
public async ValueTask DisposeAsync()
diff --git a/Kyoo.Tests/Library/TestSample.cs b/Kyoo.Tests/Library/TestSample.cs
index 3ad39969..7abf1ed1 100644
--- a/Kyoo.Tests/Library/TestSample.cs
+++ b/Kyoo.Tests/Library/TestSample.cs
@@ -6,11 +6,11 @@ namespace Kyoo.Tests
{
public static class TestSample
{
- private static readonly Dictionary Samples = new()
+ private static readonly Dictionary> Samples = new()
{
{
typeof(Show),
- new Show
+ () => new Show
{
ID = 1,
Slug = "anohana",
@@ -37,7 +37,7 @@ namespace Kyoo.Tests
},
{
typeof(Season),
- new Season
+ () => new Season
{
ID = 1,
ShowSlug = "anohana",
@@ -52,7 +52,7 @@ namespace Kyoo.Tests
},
{
typeof(Episode),
- new Episode
+ () => new Episode
{
ID = 1,
ShowSlug = "anohana",
@@ -70,7 +70,7 @@ namespace Kyoo.Tests
},
{
typeof(People),
- new People
+ () => new People
{
ID = 1,
Slug = "the-actor",
@@ -82,7 +82,7 @@ namespace Kyoo.Tests
public static T Get()
{
- return (T)Samples[typeof(T)];
+ return (T)Samples[typeof(T)]();
}
}
}
\ No newline at end of file
diff --git a/Kyoo/Controllers/Repositories/ShowRepository.cs b/Kyoo/Controllers/Repositories/ShowRepository.cs
index deeea623..360d5d28 100644
--- a/Kyoo/Controllers/Repositories/ShowRepository.cs
+++ b/Kyoo/Controllers/Repositories/ShowRepository.cs
@@ -33,14 +33,6 @@ namespace Kyoo.Controllers
/// A provider repository to handle externalID creation and deletion
///
private readonly IProviderRepository _providers;
- ///
- /// A lazy loaded season repository to handle cascade deletion (seasons deletion whith it's show)
- ///
- private readonly Lazy _seasons;
- ///
- /// A lazy loaded episode repository to handle cascade deletion (episode deletion whith it's show)
- ///
- private readonly Lazy _episodes;
///
protected override Expression> DefaultSort => x => x.Title;
@@ -53,15 +45,11 @@ namespace Kyoo.Controllers
/// A people repository
/// A genres repository
/// A provider repository
- /// A lazy loaded season repository
- /// A lazy loaded episode repository
public ShowRepository(DatabaseContext database,
IStudioRepository studios,
IPeopleRepository people,
IGenreRepository genres,
- IProviderRepository providers,
- Lazy seasons,
- Lazy episodes)
+ IProviderRepository providers)
: base(database)
{
_database = database;
@@ -69,8 +57,6 @@ namespace Kyoo.Controllers
_people = people;
_genres = genres;
_providers = providers;
- _seasons = seasons;
- _episodes = episodes;
}
@@ -103,12 +89,16 @@ namespace Kyoo.Controllers
await base.Validate(resource);
if (resource.Studio != null)
resource.Studio = await _studios.CreateIfNotExists(resource.Studio);
- resource.Genres = await TaskUtils.DefaultIfNull(resource.Genres
- ?.SelectAsync(x => _genres.CreateIfNotExists(x))
- .ToListAsync());
+
resource.GenreLinks = resource.Genres?
- .Select(x => Link.UCreate(resource, x))
+ .Select(x => Link.Create(resource, x))
.ToList();
+ await resource.GenreLinks.ForEachAsync(async id =>
+ {
+ id.Second = await _genres.CreateIfNotExists(id.Second);
+ id.SecondID = id.Second.ID;
+ _database.Entry(id.Second).State = EntityState.Detached;
+ });
await resource.ExternalIDs.ForEachAsync(async id =>
{
id.Second = await _providers.CreateIfNotExists(id.Second);
@@ -139,8 +129,8 @@ namespace Kyoo.Controllers
if (changed.Genres != null || resetOld)
{
- await Database.Entry(resource).Collection(x => x.GenreLinks).LoadAsync();
- resource.GenreLinks = changed.Genres?.Select(x => Link.UCreate(resource, x)).ToList();
+ await Database.Entry(resource).Collection(x => x.Genres).LoadAsync();
+ resource.Genres = changed.Genres;
}
if (changed.People != null || resetOld)
@@ -191,18 +181,8 @@ namespace Kyoo.Controllers
///
public override async Task Delete(Show obj)
{
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
-
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
-
- // TODO handle that with events maybe. (for now, seasons & episodes might not be loaded)
- if (obj.Seasons != null)
- await _seasons.Value.DeleteRange(obj.Seasons);
-
- if (obj.Episodes != null)
- await _episodes.Value.DeleteRange(obj.Episodes);
}
}
}
\ No newline at end of file