Fixing many bugs with the edit

This commit is contained in:
Zoe Roux 2021-01-24 20:21:48 +01:00
parent 664147f6eb
commit 135f8b3e5f
7 changed files with 65 additions and 14 deletions

View File

@ -177,6 +177,11 @@ namespace Kyoo
return obj; return obj;
} }
public static bool IsOfType([NotNull] object obj, [NotNull] Type type)
{
throw new NotImplementedException();
}
public static object RunGenericMethod( public static object RunGenericMethod(
[NotNull] Type owner, [NotNull] Type owner,
[NotNull] string methodName, [NotNull] string methodName,

View File

@ -12,6 +12,7 @@ using Kyoo.Models.Attributes;
using Kyoo.Models.Exceptions; using Kyoo.Models.Exceptions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Kyoo.Controllers namespace Kyoo.Controllers
{ {
@ -159,12 +160,37 @@ namespace Kyoo.Controllers
if (old == null) if (old == null)
throw new ItemNotFound($"No resource found with the ID {edited.ID}."); throw new ItemNotFound($"No resource found with the ID {edited.ID}.");
foreach (NavigationEntry navigation in Database.Entry(old).Navigations)
if (navigation.Metadata.PropertyInfo.GetCustomAttribute<EditableRelation>() != null
&& navigation.Metadata.GetGetter().GetClrValue(edited) != default)
await navigation.LoadAsync();
foreach (NavigationEntry navigation in Database.Entry(old).Navigations)
{
if (navigation.Metadata.PropertyInfo.GetCustomAttribute<EditableRelation>() != null)
{
if (resetOld)
{
await navigation.LoadAsync();
continue;
}
IClrPropertyGetter getter = navigation.Metadata.GetGetter();
if (getter.HasDefaultValue(edited))
continue;
await navigation.LoadAsync();
if (getter.GetClrValue(edited) != getter.GetClrValue(old))
{
navigation.Metadata.PropertyInfo.SetValue(edited, default);
Console.WriteLine($"Loaded: {navigation.Metadata.Name}");
}
else
Console.WriteLine($"Using: {navigation.Metadata.Name}");
}
else
{
navigation.Metadata.PropertyInfo.SetValue(edited, default);
Console.WriteLine($"Skipping: {navigation.Metadata.Name}");
}
}
Console.WriteLine("Loading done.");
if (resetOld) if (resetOld)
Utility.Nullify(old); Utility.Nullify(old);
Utility.Complete(old, edited); Utility.Complete(old, edited);
@ -178,6 +204,11 @@ namespace Kyoo.Controllers
} }
} }
protected bool ShouldValidate<T2>(T2 value)
{
return value != null && Database.Entry(value).State == EntityState.Detached;
}
protected virtual Task Validate(T resource) protected virtual Task Validate(T resource)
{ {
if (string.IsNullOrEmpty(resource.Slug)) if (string.IsNullOrEmpty(resource.Slug))
@ -203,7 +234,7 @@ namespace Kyoo.Controllers
&& !typeof(string).IsAssignableFrom(x.PropertyType))) && !typeof(string).IsAssignableFrom(x.PropertyType)))
{ {
object value = property.GetValue(resource); object value = property.GetValue(resource);
if (value is ICollection || value == null) if (value == null || value is ICollection || Utility.IsOfType(value, typeof(ICollection<>)))
continue; continue;
value = Utility.RunGenericMethod(typeof(Enumerable), "ToList", Utility.GetEnumerableType((IEnumerable)value), value); value = Utility.RunGenericMethod(typeof(Enumerable), "ToList", Utility.GetEnumerableType((IEnumerable)value), value);
property.SetValue(resource, value); property.SetValue(resource, value);
@ -299,6 +330,8 @@ namespace Kyoo.Controllers
Task<T> IRepository<T>.Create(T item) Task<T> IRepository<T>.Create(T item)
{ {
if (item == null)
throw new ArgumentNullException(nameof(item));
TInternal obj = item as TInternal ?? new TInternal(); TInternal obj = item as TInternal ?? new TInternal();
if (!(item is TInternal)) if (!(item is TInternal))
Utility.Assign(obj, item); Utility.Assign(obj, item);
@ -309,6 +342,8 @@ namespace Kyoo.Controllers
Task<T> IRepository<T>.CreateIfNotExists(T item, bool silentFail) Task<T> IRepository<T>.CreateIfNotExists(T item, bool silentFail)
{ {
if (item == null)
throw new ArgumentNullException(nameof(item));
TInternal obj = item as TInternal ?? new TInternal(); TInternal obj = item as TInternal ?? new TInternal();
if (!(item is TInternal)) if (!(item is TInternal))
Utility.Assign(obj, item); Utility.Assign(obj, item);
@ -319,6 +354,8 @@ namespace Kyoo.Controllers
public Task<T> Edit(T edited, bool resetOld) public Task<T> Edit(T edited, bool resetOld)
{ {
if (edited == null)
throw new ArgumentNullException(nameof(edited));
if (edited is TInternal intern) if (edited is TInternal intern)
return Edit(intern, resetOld).Cast<T>(); return Edit(intern, resetOld).Cast<T>();
TInternal obj = new TInternal(); TInternal obj = new TInternal();
@ -330,6 +367,8 @@ namespace Kyoo.Controllers
Task IRepository<T>.Delete(T obj) Task IRepository<T>.Delete(T obj)
{ {
if (obj == null)
throw new ArgumentNullException(nameof(obj));
if (obj is TInternal intern) if (obj is TInternal intern)
return Delete(intern); return Delete(intern);
TInternal item = new TInternal(); TInternal item = new TInternal();

View File

@ -120,7 +120,8 @@ namespace Kyoo.Controllers
if (resource.ExternalIDs != null) if (resource.ExternalIDs != null)
{ {
foreach (MetadataID link in resource.ExternalIDs) foreach (MetadataID link in resource.ExternalIDs)
link.Provider = await _providers.CreateIfNotExists(link.Provider, true); if (ShouldValidate(link))
link.Provider = await _providers.CreateIfNotExists(link.Provider, true);
} }
} }

View File

@ -76,7 +76,8 @@ namespace Kyoo.Controllers
if (resource.ProviderLinks != null) if (resource.ProviderLinks != null)
foreach (ProviderLink link in resource.ProviderLinks) foreach (ProviderLink link in resource.ProviderLinks)
link.Provider = await _providers.CreateIfNotExists(link.Provider, true); if (ShouldValidate(link))
link.Provider = await _providers.CreateIfNotExists(link.Provider, true);
} }
public override async Task Delete(LibraryDE obj) public override async Task Delete(LibraryDE obj)

View File

@ -75,7 +75,8 @@ namespace Kyoo.Controllers
if (resource.ExternalIDs != null) if (resource.ExternalIDs != null)
foreach (MetadataID link in resource.ExternalIDs) foreach (MetadataID link in resource.ExternalIDs)
link.Provider = await _providers.CreateIfNotExists(link.Provider, true); if (ShouldValidate(link))
link.Provider = await _providers.CreateIfNotExists(link.Provider, true);
} }
public override async Task Delete(People obj) public override async Task Delete(People obj)

View File

@ -104,7 +104,8 @@ namespace Kyoo.Controllers
if (resource.ExternalIDs != null) if (resource.ExternalIDs != null)
{ {
foreach (MetadataID link in resource.ExternalIDs) foreach (MetadataID link in resource.ExternalIDs)
link.Provider = await _providers.CreateIfNotExists(link.Provider, true); if (ShouldValidate(link))
link.Provider = await _providers.CreateIfNotExists(link.Provider, true);
} }
} }

View File

@ -111,20 +111,23 @@ namespace Kyoo.Controllers
{ {
await base.Validate(resource); await base.Validate(resource);
if (resource.Studio != null) if (ShouldValidate(resource.Studio))
resource.Studio = await _studios.CreateIfNotExists(resource.Studio, true); resource.Studio = await _studios.CreateIfNotExists(resource.Studio, true);
if (resource.GenreLinks != null) if (resource.GenreLinks != null)
foreach (GenreLink link in resource.GenreLinks) foreach (GenreLink link in resource.GenreLinks)
link.Genre = await _genres.CreateIfNotExists(link.Genre, true); if (ShouldValidate(link))
link.Genre = await _genres.CreateIfNotExists(link.Genre, true);
if (resource.People != null) if (resource.People != null)
foreach (PeopleRole link in resource.People) foreach (PeopleRole link in resource.People)
link.People = await _people.CreateIfNotExists(link.People, true); if (ShouldValidate(link))
link.People = await _people.CreateIfNotExists(link.People, true);
if (resource.ExternalIDs != null) if (resource.ExternalIDs != null)
foreach (MetadataID link in resource.ExternalIDs) foreach (MetadataID link in resource.ExternalIDs)
link.Provider = await _providers.CreateIfNotExists(link.Provider, true); if (ShouldValidate(link))
link.Provider = await _providers.CreateIfNotExists(link.Provider, true);
} }
public async Task AddShowLink(int showID, int? libraryID, int? collectionID) public async Task AddShowLink(int showID, int? libraryID, int? collectionID)