mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Trying things with a generic edit function with repositories
This commit is contained in:
parent
b84baae99a
commit
27c89ccc85
@ -17,4 +17,15 @@ namespace Kyoo.Models.Attributes
|
||||
RelationID = relationID;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class LinkRelationAttribute : Attribute
|
||||
{
|
||||
public string Relation { get; }
|
||||
|
||||
public LinkRelationAttribute(string relation)
|
||||
{
|
||||
Relation = relation;
|
||||
}
|
||||
}
|
||||
}
|
@ -37,7 +37,8 @@ namespace Kyoo.Models
|
||||
[LoadableRelation] public virtual ICollection<Collection> Collections { get; set; }
|
||||
|
||||
#if ENABLE_INTERNAL_LINKS
|
||||
[SerializeIgnore] public virtual ICollection<Link<Library, Show>> LibraryLinks { get; set; }
|
||||
[LinkRelation(nameof(Libraries))] [SerializeIgnore]
|
||||
public virtual ICollection<Link<Library, Show>> LibraryLinks { get; set; }
|
||||
[SerializeIgnore] public virtual ICollection<Link<Collection, Show>> CollectionLinks { get; set; }
|
||||
[SerializeIgnore] public virtual ICollection<Link<Show, Genre>> GenreLinks { get; set; }
|
||||
#endif
|
||||
|
@ -132,7 +132,7 @@ namespace Kyoo.Controllers
|
||||
|
||||
public void SetValue(object target, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Values are ignored and should not be editable, except if the internal value is set.
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
@ -154,6 +155,7 @@ namespace Kyoo.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<T> Edit(T edited, bool resetOld)
|
||||
{
|
||||
if (edited == null)
|
||||
@ -168,47 +170,77 @@ namespace Kyoo.Controllers
|
||||
if (old == null)
|
||||
throw new ItemNotFound($"No resource found with the ID {edited.ID}.");
|
||||
|
||||
// foreach (PropertyInfo navigation in typeof(T).GetProperties()
|
||||
// .Where(x => x.GetCustomAttribute<LoadableRelationAttribute>() != null))
|
||||
// {
|
||||
// if (navigation.GetCustomAttribute<EditableRelationAttribute>() == null)
|
||||
// {
|
||||
// navigation.SetValue(edited, default);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (resetOld || navigation.GetValue(edited) != default)
|
||||
// {
|
||||
// // TODO only works for X To One and not X to Many
|
||||
// await _library.Value.Load(old, navigation.Name);
|
||||
// object value = navigation.GetValue(old);
|
||||
// if (value is IEnumerable list) // TODO handle externalIds & PeopleRoles
|
||||
// list.ForEach(x => _library.Value.Delete(x));
|
||||
// else if (value is IResource resource)
|
||||
// _library.Value.Delete(resource);
|
||||
// }
|
||||
// }
|
||||
foreach (NavigationEntry navigation in Database.Entry(old).Navigations)
|
||||
{
|
||||
if (navigation.Metadata.PropertyInfo.GetCustomAttribute<EditableRelationAttribute>() != null)
|
||||
{
|
||||
if (resetOld)
|
||||
{
|
||||
await navigation.LoadAsync();
|
||||
continue;
|
||||
}
|
||||
IClrPropertyGetter getter = navigation.Metadata.GetGetter();
|
||||
List<PropertyInfo> navigations = typeof(T).GetProperties()
|
||||
.Where(x => x.GetCustomAttribute<EditableRelationAttribute>() != null)
|
||||
.ToList();
|
||||
List<string> links = typeof(T).GetProperties()
|
||||
.Select(x => x.GetCustomAttribute<LinkRelationAttribute>()?.Relation)
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
|
||||
if (getter.HasDefaultValue(edited))
|
||||
// This handle every links so every Many to Many
|
||||
// TODO should handle non links value (One to Many)
|
||||
foreach (string relationName in links)
|
||||
{
|
||||
PropertyInfo relation = navigations.Find(x => x.Name == relationName);
|
||||
navigations.Remove(relation);
|
||||
|
||||
if (relation!.GetValue(edited) == null && !resetOld)
|
||||
continue;
|
||||
await navigation.LoadAsync();
|
||||
// TODO this may be usless for lists since the API does not return IDs but the
|
||||
// TODO LinkEquality does not check slugs (their are lazy loaded and only the ID is available)
|
||||
// if (Utility.ResourceEquals(getter.GetClrValue(edited), getter.GetClrValue(old)))
|
||||
// navigation.Metadata.PropertyInfo.SetValue(edited, default);
|
||||
}
|
||||
|
||||
await _library.Load(old, relation.Name);
|
||||
IEnumerable<IResource> oValues = (relation.GetValue(old) as IEnumerable)!.Cast<IResource>();
|
||||
List<IResource> nValues = (relation.GetValue(edited) as IEnumerable)?.Cast<IResource>().ToList();
|
||||
|
||||
foreach (IResource x in oValues)
|
||||
{
|
||||
int nIndex = nValues?.FindIndex(y => Utility.ResourceEquals(x, y)) ?? -1;
|
||||
if (nIndex == -1 || resetOld)
|
||||
await _linkManager.Delete(old, x);
|
||||
else
|
||||
navigation.Metadata.PropertyInfo.SetValue(edited, default);
|
||||
nValues!.RemoveAt(nIndex);
|
||||
}
|
||||
|
||||
await nValues.ForEachAsync(x => _linkManager.Add(old, x));
|
||||
}
|
||||
|
||||
// This handle every X to One
|
||||
foreach (PropertyInfo relation in navigations)
|
||||
{
|
||||
IResource oValues = relation.GetValue(old) as IResource;
|
||||
IResource nValues = relation.GetValue(edited) as IResource;
|
||||
|
||||
if (nValues == null && !resetOld)
|
||||
continue;
|
||||
|
||||
if (false) // TODO change if false with if relation is casquade delete
|
||||
await _library.Delete(oValue);
|
||||
relation.SetValue(old, nValues);
|
||||
// TODO call create if not exist
|
||||
// TODO change relationID to the new value ID.
|
||||
}
|
||||
|
||||
|
||||
// This handle every One to Many or Many to One
|
||||
foreach (PropertyInfo navigation in navigations)
|
||||
{
|
||||
if (resetOld || navigation.GetValue(edited) != default)
|
||||
{
|
||||
// TODO only works for X To One and not X to Many
|
||||
await _library.Value.Load(old, navigation.Name);
|
||||
object value = navigation.GetValue(old);
|
||||
if (value is IEnumerable list) // TODO handle externalIds & PeopleRoles (implement Link<> for those)
|
||||
list.ForEach(x => _library.Value.Delete(x));
|
||||
else if (value is IResource resource)
|
||||
_library.Value.Delete(resource);
|
||||
}
|
||||
|
||||
|
||||
if (navigation.GetCustomAttribute<EditableRelationAttribute>() == null)
|
||||
{
|
||||
navigation.SetValue(edited, default);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (resetOld)
|
||||
|
@ -15,6 +15,7 @@ namespace Kyoo
|
||||
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
|
||||
{
|
||||
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
ChangeTracker.LazyLoadingEnabled = false;
|
||||
}
|
||||
|
||||
public DbSet<Library> Libraries { get; set; }
|
||||
@ -40,6 +41,7 @@ namespace Kyoo
|
||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
|
||||
|
||||
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
ChangeTracker.LazyLoadingEnabled = false;
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
Loading…
x
Reference in New Issue
Block a user