Fix repository's relations handling

This commit is contained in:
Zoe Roux 2024-04-21 19:39:40 +02:00
parent e846a1cc18
commit 00cd94d624
No known key found for this signature in database
6 changed files with 21 additions and 36 deletions

View File

@ -18,6 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Controllers;
@ -79,22 +80,15 @@ public class EpisodeRepository(DatabaseContext database, IRepository<Show> shows
protected override async Task Validate(Episode resource) protected override async Task Validate(Episode resource)
{ {
await base.Validate(resource); await base.Validate(resource);
resource.Show = null;
if (resource.ShowId == Guid.Empty) if (resource.ShowId == Guid.Empty)
{ throw new ValidationException("Missing show id");
if (resource.Show == null) resource.Season = null;
{
throw new ArgumentException(
$"Can't store an episode not related "
+ $"to any show (showID: {resource.ShowId})."
);
}
resource.ShowId = resource.Show.Id;
}
if (resource.SeasonId == null && resource.SeasonNumber != null) if (resource.SeasonId == null && resource.SeasonNumber != null)
{ {
resource.Season = await Database.Seasons.FirstOrDefaultAsync(x => resource.SeasonId = await Database.Seasons.Where(x =>
x.ShowId == resource.ShowId && x.SeasonNumber == resource.SeasonNumber x.ShowId == resource.ShowId && x.SeasonNumber == resource.SeasonNumber
); ).Select(x => x.Id).FirstOrDefaultAsync();
} }
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }

View File

@ -18,6 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
@ -268,7 +269,7 @@ public abstract class GenericRepository<T>(DatabaseContext database) : IReposito
public virtual async Task<T> Create(T obj) public virtual async Task<T> Create(T obj)
{ {
await Validate(obj); await Validate(obj);
Database.Entry(obj).State = EntityState.Added; Database.Add(obj);
await Database.SaveChangesAsync(() => Get(obj.Slug)); await Database.SaveChangesAsync(() => Get(obj.Slug));
await IRepository<T>.OnResourceCreated(obj); await IRepository<T>.OnResourceCreated(obj);
return obj; return obj;
@ -295,7 +296,7 @@ public abstract class GenericRepository<T>(DatabaseContext database) : IReposito
public virtual async Task<T> Edit(T edited) public virtual async Task<T> Edit(T edited)
{ {
await Validate(edited); await Validate(edited);
Database.Entry(edited).State = EntityState.Modified; Database.Update(edited);
await Database.SaveChangesAsync(); await Database.SaveChangesAsync();
await IRepository<T>.OnResourceEdited(edited); await IRepository<T>.OnResourceEdited(edited);
return edited; return edited;
@ -323,7 +324,7 @@ public abstract class GenericRepository<T>(DatabaseContext database) : IReposito
} }
} }
/// <exception cref="ArgumentException"> /// <exception cref="ValidationException">
/// You can throw this if the resource is illegal and should not be saved. /// You can throw this if the resource is illegal and should not be saved.
/// </exception> /// </exception>
protected virtual Task Validate(T resource) protected virtual Task Validate(T resource)
@ -334,9 +335,9 @@ public abstract class GenericRepository<T>(DatabaseContext database) : IReposito
) )
return Task.CompletedTask; return Task.CompletedTask;
if (string.IsNullOrEmpty(resource.Slug)) if (string.IsNullOrEmpty(resource.Slug))
throw new ArgumentException("Resource can't have null as a slug."); throw new ValidationException("Resource can't have null as a slug.");
if (resource.Slug == "random") if (resource.Slug == "random")
throw new ArgumentException("Resources slug can't be the literal \"random\"."); throw new ValidationException("Resources slug can't be the literal \"random\".");
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -30,7 +30,8 @@ namespace Kyoo.Core.Controllers;
/// <summary> /// <summary>
/// A local repository to handle library items. /// A local repository to handle library items.
/// </summary> /// </summary>
public class LibraryItemRepository : DapperRepository<ILibraryItem> public class LibraryItemRepository(DbConnection database, SqlVariableContext context)
: DapperRepository<ILibraryItem>(database, context)
{ {
// language=PostgreSQL // language=PostgreSQL
protected override FormattableString Sql => protected override FormattableString Sql =>
@ -78,9 +79,6 @@ public class LibraryItemRepository : DapperRepository<ILibraryItem>
throw new InvalidDataException(); throw new InvalidDataException();
} }
public LibraryItemRepository(DbConnection database, SqlVariableContext context)
: base(database, context) { }
public async Task<ICollection<ILibraryItem>> GetAllOfCollection( public async Task<ICollection<ILibraryItem>> GetAllOfCollection(
Guid collectionId, Guid collectionId,
Filter<ILibraryItem>? filter = default, Filter<ILibraryItem>? filter = default,

View File

@ -71,8 +71,8 @@ public class MovieRepository(
await base.Validate(resource); await base.Validate(resource);
if (resource.Studio != null) if (resource.Studio != null)
{ {
resource.Studio = await studios.CreateIfNotExists(resource.Studio); resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id;
resource.StudioId = resource.Studio.Id; resource.Studio = null;
} }
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }

View File

@ -80,17 +80,9 @@ public class SeasonRepository(DatabaseContext database, IThumbnailsManager thumb
protected override async Task Validate(Season resource) protected override async Task Validate(Season resource)
{ {
await base.Validate(resource); await base.Validate(resource);
resource.Show = null;
if (resource.ShowId == Guid.Empty) if (resource.ShowId == Guid.Empty)
{ throw new ValidationException("Missing show id");
if (resource.Show == null)
{
throw new ValidationException(
$"Can't store a season not related to any show "
+ $"(showID: {resource.ShowId})."
);
}
resource.ShowId = resource.Show.Id;
}
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }
} }

View File

@ -60,7 +60,7 @@ public class ShowRepository(
&& existing.StartAir?.Year != obj.StartAir?.Year && existing.StartAir?.Year != obj.StartAir?.Year
) )
{ {
obj.Slug = $"{obj.Slug}-{obj.StartAir!.Value.Year}"; obj.Slug = $"{obj.Slug}-{obj.AirDate!.Value.Year}";
return base.Create(obj); return base.Create(obj);
} }
} }
@ -71,8 +71,8 @@ public class ShowRepository(
await base.Validate(resource); await base.Validate(resource);
if (resource.Studio != null) if (resource.Studio != null)
{ {
resource.Studio = await studios.CreateIfNotExists(resource.Studio); resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id;
resource.StudioId = resource.Studio.Id; resource.Studio = null;
} }
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }