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;
|
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; }
|
[LoadableRelation] public virtual ICollection<Collection> Collections { get; set; }
|
||||||
|
|
||||||
#if ENABLE_INTERNAL_LINKS
|
#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<Collection, Show>> CollectionLinks { get; set; }
|
||||||
[SerializeIgnore] public virtual ICollection<Link<Show, Genre>> GenreLinks { get; set; }
|
[SerializeIgnore] public virtual ICollection<Link<Show, Genre>> GenreLinks { get; set; }
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,7 +132,7 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
public void SetValue(object target, object value)
|
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;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
@ -153,6 +154,7 @@ namespace Kyoo.Controllers
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual async Task<T> Edit(T edited, bool resetOld)
|
public virtual async Task<T> Edit(T edited, bool resetOld)
|
||||||
{
|
{
|
||||||
@ -168,47 +170,77 @@ 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 (PropertyInfo navigation in typeof(T).GetProperties()
|
List<PropertyInfo> navigations = typeof(T).GetProperties()
|
||||||
// .Where(x => x.GetCustomAttribute<LoadableRelationAttribute>() != null))
|
.Where(x => x.GetCustomAttribute<EditableRelationAttribute>() != null)
|
||||||
// {
|
.ToList();
|
||||||
// if (navigation.GetCustomAttribute<EditableRelationAttribute>() == null)
|
List<string> links = typeof(T).GetProperties()
|
||||||
// {
|
.Select(x => x.GetCustomAttribute<LinkRelationAttribute>()?.Relation)
|
||||||
// navigation.SetValue(edited, default);
|
.Where(x => x != null)
|
||||||
// continue;
|
.ToList();
|
||||||
// }
|
|
||||||
//
|
// This handle every links so every Many to Many
|
||||||
// if (resetOld || navigation.GetValue(edited) != default)
|
// TODO should handle non links value (One to Many)
|
||||||
// {
|
foreach (string relationName in links)
|
||||||
// // 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)
|
PropertyInfo relation = navigations.Find(x => x.Name == relationName);
|
||||||
{
|
navigations.Remove(relation);
|
||||||
if (resetOld)
|
|
||||||
{
|
|
||||||
await navigation.LoadAsync();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
IClrPropertyGetter getter = navigation.Metadata.GetGetter();
|
|
||||||
|
|
||||||
if (getter.HasDefaultValue(edited))
|
if (relation!.GetValue(edited) == null && !resetOld)
|
||||||
continue;
|
continue;
|
||||||
await navigation.LoadAsync();
|
|
||||||
// TODO this may be usless for lists since the API does not return IDs but the
|
await _library.Load(old, relation.Name);
|
||||||
// TODO LinkEquality does not check slugs (their are lazy loaded and only the ID is available)
|
IEnumerable<IResource> oValues = (relation.GetValue(old) as IEnumerable)!.Cast<IResource>();
|
||||||
// if (Utility.ResourceEquals(getter.GetClrValue(edited), getter.GetClrValue(old)))
|
List<IResource> nValues = (relation.GetValue(edited) as IEnumerable)?.Cast<IResource>().ToList();
|
||||||
// navigation.Metadata.PropertyInfo.SetValue(edited, default);
|
|
||||||
|
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
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
navigation.Metadata.PropertyInfo.SetValue(edited, default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resetOld)
|
if (resetOld)
|
||||||
|
@ -15,6 +15,7 @@ namespace Kyoo
|
|||||||
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
|
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
|
||||||
{
|
{
|
||||||
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||||
|
ChangeTracker.LazyLoadingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<Library> Libraries { get; set; }
|
public DbSet<Library> Libraries { get; set; }
|
||||||
@ -40,6 +41,7 @@ namespace Kyoo
|
|||||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
|
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
|
||||||
|
|
||||||
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||||
|
ChangeTracker.LazyLoadingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user