Add events when resources are changed

This commit is contained in:
Zoe Roux 2023-06-21 11:58:05 +09:00
parent 94d3b8676f
commit 58b799edb4
13 changed files with 67 additions and 1 deletions

View File

@ -33,6 +33,12 @@ namespace Kyoo.Abstractions.Controllers
public interface IRepository<T> : IBaseRepository public interface IRepository<T> : IBaseRepository
where T : class, IResource where T : class, IResource
{ {
/// <summary>
/// The event handler type for all events of this repository.
/// </summary>
/// <param name="resource">The resource created/modified/deleted</param>
public delegate void ResourceEventHandler(T resource);
/// <summary> /// <summary>
/// Get a resource from it's ID. /// Get a resource from it's ID.
/// </summary> /// </summary>
@ -128,6 +134,11 @@ namespace Kyoo.Abstractions.Controllers
[ItemNotNull] [ItemNotNull]
Task<T> CreateIfNotExists([NotNull] T obj); Task<T> CreateIfNotExists([NotNull] T obj);
/// <summary>
/// Called when a resource has been created.
/// </summary>
event ResourceEventHandler OnCreated;
/// <summary> /// <summary>
/// Edit a resource /// Edit a resource
/// </summary> /// </summary>
@ -138,6 +149,11 @@ namespace Kyoo.Abstractions.Controllers
[ItemNotNull] [ItemNotNull]
Task<T> Edit([NotNull] T edited, bool resetOld); Task<T> Edit([NotNull] T edited, bool resetOld);
/// <summary>
/// Called when a resource has been edited.
/// </summary>
event ResourceEventHandler OnEdited;
/// <summary> /// <summary>
/// Delete a resource by it's ID /// Delete a resource by it's ID
/// </summary> /// </summary>
@ -168,6 +184,11 @@ namespace Kyoo.Abstractions.Controllers
/// <param name="where">A predicate to filter resources to delete. Every resource that match this will be deleted.</param> /// <param name="where">A predicate to filter resources to delete. Every resource that match this will be deleted.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task DeleteAll([NotNull] Expression<Func<T, bool>> where); Task DeleteAll([NotNull] Expression<Func<T, bool>> where);
/// <summary>
/// Called when a resource has been edited.
/// </summary>
event ResourceEventHandler OnDeleted;
} }
/// <summary> /// <summary>

View File

@ -73,6 +73,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -118,6 +119,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -146,6 +146,7 @@ namespace Kyoo.Core.Controllers
obj.SeasonNumber != null && obj.EpisodeNumber != null obj.SeasonNumber != null && obj.EpisodeNumber != null
? Get(obj.ShowID, obj.SeasonNumber.Value, obj.EpisodeNumber.Value) ? Get(obj.ShowID, obj.SeasonNumber.Value, obj.EpisodeNumber.Value)
: GetAbsolute(obj.ShowID, obj.AbsoluteNumber.Value)); : GetAbsolute(obj.ShowID, obj.AbsoluteNumber.Value));
OnResourceCreated(obj);
return await _ValidateTracks(obj); return await _ValidateTracks(obj);
} }
@ -223,6 +224,7 @@ namespace Kyoo.Core.Controllers
await obj.Tracks.ForEachAsync(x => _tracks.Delete(x)); await obj.Tracks.ForEachAsync(x => _tracks.Delete(x));
obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted); obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -75,6 +75,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -86,6 +87,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -75,6 +75,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -122,6 +123,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -62,6 +62,15 @@ namespace Kyoo.Core.Controllers
/// <inheritdoc/> /// <inheritdoc/>
public Type RepositoryType => typeof(T); public Type RepositoryType => typeof(T);
/// <inheritdoc/>
public event IRepository<T>.ResourceEventHandler OnCreated;
/// <inheritdoc/>
public event IRepository<T>.ResourceEventHandler OnEdited;
/// <inheritdoc/>
public event IRepository<T>.ResourceEventHandler OnDeleted;
/// <summary> /// <summary>
/// Sort the given query. /// Sort the given query.
/// </summary> /// </summary>
@ -335,6 +344,15 @@ namespace Kyoo.Core.Controllers
return obj; return obj;
} }
/// <summary>
/// Callback that should be called after a resource has been created.
/// </summary>
/// <param name="obj">The resource newly created.</param>
protected void OnResourceCreated(T obj)
{
OnCreated.Invoke(obj);
}
/// <inheritdoc/> /// <inheritdoc/>
public virtual async Task<T> CreateIfNotExists(T obj) public virtual async Task<T> CreateIfNotExists(T obj)
{ {
@ -372,6 +390,7 @@ namespace Kyoo.Core.Controllers
Merger.Complete(old, edited, x => x.GetCustomAttribute<LoadableRelationAttribute>() == null); Merger.Complete(old, edited, x => x.GetCustomAttribute<LoadableRelationAttribute>() == null);
await EditRelations(old, edited, resetOld); await EditRelations(old, edited, resetOld);
await Database.SaveChangesAsync(); await Database.SaveChangesAsync();
OnEdited.Invoke(old);
return old; return old;
} }
finally finally
@ -448,7 +467,11 @@ namespace Kyoo.Core.Controllers
} }
/// <inheritdoc/> /// <inheritdoc/>
public abstract Task Delete(T obj); public virtual Task Delete(T obj)
{
OnDeleted.Invoke(obj);
return Task.CompletedTask;
}
/// <inheritdoc/> /// <inheritdoc/>
public async Task DeleteAll(Expression<Func<T, bool>> where) public async Task DeleteAll(Expression<Func<T, bool>> where)

View File

@ -85,6 +85,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -144,6 +145,7 @@ namespace Kyoo.Core.Controllers
obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted); obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
obj.Roles.ForEach(x => _database.Entry(x).State = EntityState.Deleted); obj.Roles.ForEach(x => _database.Entry(x).State = EntityState.Deleted);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -68,6 +68,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -79,6 +80,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -108,6 +108,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.ShowID, obj.SeasonNumber)); await _database.SaveChangesAsync(() => Get(obj.ShowID, obj.SeasonNumber));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -157,6 +158,7 @@ namespace Kyoo.Core.Controllers
_database.Remove(obj); _database.Remove(obj);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -100,6 +100,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -213,6 +214,7 @@ namespace Kyoo.Core.Controllers
{ {
_database.Remove(obj); _database.Remove(obj);
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -75,6 +75,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -116,6 +117,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -79,6 +79,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
OnResourceCreated(obj);
return obj; return obj;
} }
@ -90,6 +91,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }

View File

@ -67,6 +67,7 @@ namespace Kyoo.Core.Controllers
await base.Create(obj); await base.Create(obj);
_database.Entry(obj).State = EntityState.Added; _database.Entry(obj).State = EntityState.Added;
await _database.SaveChangesAsync(() => Get(obj.Slug)); await _database.SaveChangesAsync(() => Get(obj.Slug));
OnResourceCreated(obj);
return obj; return obj;
} }
@ -78,6 +79,7 @@ namespace Kyoo.Core.Controllers
_database.Entry(obj).State = EntityState.Deleted; _database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync(); await _database.SaveChangesAsync();
await base.Delete(obj);
} }
} }
} }