diff --git a/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs b/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
index fbe8d1ab..6e84c43a 100644
--- a/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
@@ -16,12 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
using Kyoo.Abstractions.Models;
-using Kyoo.Abstractions.Models.Exceptions;
namespace Kyoo.Abstractions.Controllers
{
@@ -30,413 +25,49 @@ namespace Kyoo.Abstractions.Controllers
///
public interface ILibraryManager
{
- ///
- /// Get the repository corresponding to the T item.
- ///
- /// The type you want
- /// If the item is not found
- /// The repository corresponding
- IRepository GetRepository()
- where T : class, IResource;
-
///
/// The repository that handle libraries items (a wrapper around shows and collections).
///
- ILibraryItemRepository LibraryItemRepository { get; }
+ IRepository LibraryItems { get; }
///
/// The repository that handle collections.
///
- ICollectionRepository CollectionRepository { get; }
+ IRepository Collections { get; }
///
/// The repository that handle shows.
///
- IMovieRepository MovieRepository { get; }
+ IRepository Movies { get; }
///
/// The repository that handle shows.
///
- IShowRepository ShowRepository { get; }
+ IRepository Shows { get; }
///
/// The repository that handle seasons.
///
- ISeasonRepository SeasonRepository { get; }
+ IRepository Seasons { get; }
///
/// The repository that handle episodes.
///
- IEpisodeRepository EpisodeRepository { get; }
+ IRepository Episodes { get; }
///
/// The repository that handle people.
///
- IPeopleRepository PeopleRepository { get; }
+ IRepository People { get; }
///
/// The repository that handle studios.
///
- IStudioRepository StudioRepository { get; }
+ IRepository Studios { get; }
///
/// The repository that handle users.
///
- IUserRepository UserRepository { get; }
-
- ///
- /// Get the resource by it's ID
- ///
- /// The id of the resource
- /// The type of the resource
- /// If the item is not found
- /// The resource found
- Task Get(int id)
- where T : class, IResource;
-
- ///
- /// Get the resource by it's slug
- ///
- /// The slug of the resource
- /// The type of the resource
- /// If the item is not found
- /// The resource found
- Task Get(string slug)
- where T : class, IResource;
-
- ///
- /// Get the resource by a filter function.
- ///
- /// The filter function.
- /// The type of the resource
- /// If the item is not found
- /// The first resource found that match the where function
- Task Get(Expression> where)
- where T : class, IResource;
-
- ///
- /// Get a season from it's showID and it's seasonNumber
- ///
- /// The id of the show
- /// The season's number
- /// If the item is not found
- /// The season found
- Task Get(int showID, int seasonNumber);
-
- ///
- /// Get a season from it's show slug and it's seasonNumber
- ///
- /// The slug of the show
- /// The season's number
- /// If the item is not found
- /// The season found
- Task Get(string showSlug, int seasonNumber);
-
- ///
- /// Get a episode from it's showID, it's seasonNumber and it's episode number.
- ///
- /// The id of the show
- /// The season's number
- /// The episode's number
- /// If the item is not found
- /// The episode found
- Task Get(int showID, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's show slug, it's seasonNumber and it's episode number.
- ///
- /// The slug of the show
- /// The season's number
- /// The episode's number
- /// If the item is not found
- /// The episode found
- Task Get(string showSlug, int seasonNumber, int episodeNumber);
-
- ///
- /// Get the resource by it's ID or null if it is not found.
- ///
- /// The id of the resource
- /// The type of the resource
- /// The resource found
- Task GetOrDefault(int id)
- where T : class, IResource;
-
- ///
- /// Get the resource by it's slug or null if it is not found.
- ///
- /// The slug of the resource
- /// The type of the resource
- /// The resource found
- Task GetOrDefault(string slug)
- where T : class, IResource;
-
- ///
- /// Get the resource by a filter function or null if it is not found.
- ///
- /// The filter function.
- /// A custom sort method to handle cases where multiples items match the filters.
- /// The type of the resource
- /// The first resource found that match the where function
- Task GetOrDefault(Expression> where, Sort? sortBy = default)
- where T : class, IResource;
-
- ///
- /// Get a season from it's showID and it's seasonNumber or null if it is not found.
- ///
- /// The id of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(int showID, int seasonNumber);
-
- ///
- /// Get a season from it's show slug and it's seasonNumber or null if it is not found.
- ///
- /// The slug of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(string showSlug, int seasonNumber);
-
- ///
- /// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
- ///
- /// The id of the show
- /// The season's number
- /// The episode's number
- /// The episode found
- Task GetOrDefault(int showID, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's show slug, it's seasonNumber and it's episode number or null if it is not found.
- ///
- /// The slug of the show
- /// The season's number
- /// The episode's number
- /// The episode found
- Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
-
- ///
- /// Load a related resource
- ///
- /// The source object.
- /// A getter function for the member to load
- ///
- /// true if you want to load the relation even if it is not null, false otherwise.
- ///
- /// The type of the source object
- /// The related resource's type
- /// The param
- ///
- ///
- ///
- Task Load(T obj, Expression> member, bool force = false)
- where T : class, IResource
- where T2 : class, IResource;
-
- ///
- /// Load a collection of related resource
- ///
- /// The source object.
- /// A getter function for the member to load
- ///
- /// true if you want to load the relation even if it is not null, false otherwise.
- ///
- /// The type of the source object
- /// The related resource's type
- /// The param
- ///
- ///
- ///
- Task Load(T obj, Expression>> member, bool force = false)
- where T : class, IResource
- where T2 : class;
-
- ///
- /// Load a related resource by it's name
- ///
- /// The source object.
- /// The name of the resource to load (case sensitive)
- ///
- /// true if you want to load the relation even if it is not null, false otherwise.
- ///
- /// The type of the source object
- /// The param
- ///
- ///
- ///
- Task Load(T obj, string memberName, bool force = false)
- where T : class, IResource;
-
- ///
- /// Load a related resource without specifying it's type.
- ///
- /// The source object.
- /// The name of the resource to load (case sensitive)
- ///
- /// true if you want to load the relation even if it is not null, false otherwise.
- ///
- ///
- ///
- ///
- /// A representing the asynchronous operation.
- Task Load(IResource obj, string memberName, bool force = false);
-
- ///
- /// Get people's roles from a show.
- ///
- /// The ID of the show
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given ID.
- /// A list of items that match every filters
- Task> GetPeopleFromShow(int showID,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a show.
- ///
- /// The slug of the show
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given slug.
- /// A list of items that match every filters
- Task> GetPeopleFromShow(string showSlug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a person.
- ///
- /// The id of the person
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given ID.
- /// A list of items that match every filters
- Task> GetRolesFromPeople(int id,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a person.
- ///
- /// The slug of the person
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given slug.
- /// A list of items that match every filters
- Task> GetRolesFromPeople(string slug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get all resources with filters
- ///
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// The type of resources to load
- /// A list of resources that match every filters
- Task> GetAll(Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- where T : class, IResource;
-
- ///
- /// Get the count of resources that match the filter
- ///
- /// A filter function
- /// The type of resources to load
- /// A list of resources that match every filters
- Task GetCount(Expression>? where = null)
- where T : class, IResource;
-
- ///
- /// Search for a resource
- ///
- /// The search query
- /// The type of resources
- /// A list of 20 items that match the search query
- Task> Search(string query)
- where T : class, IResource;
-
- ///
- /// Create a new resource.
- ///
- /// The item to register
- /// The type of resource
- /// The resource registers and completed by database's information (related items and so on)
- Task Create(T item)
- where T : class, IResource;
-
- ///
- /// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
- ///
- /// The item to register
- /// The type of resource
- /// The newly created item or the existing value if it existed.
- Task CreateIfNotExists(T item)
- where T : class, IResource;
-
- ///
- /// Edit a resource
- ///
- /// The resource to edit, it's ID can't change.
- /// The type of resources
- /// If the item is not found
- /// The resource edited and completed by database's information (related items and so on)
- Task Edit(T item)
- where T : class, IResource;
-
- ///
- /// Edit only specific properties of a resource
- ///
- /// The id of the resource to edit
- ///
- /// A method that will be called when you need to update every properties that you want to
- /// persist. It can return false to abort the process via an ArgumentException
- ///
- /// The type of resources
- /// If the item is not found
- /// The resource edited and completed by database's information (related items and so on)
- Task Patch(int id, Func> patch)
- where T : class, IResource;
-
- ///
- /// Delete a resource.
- ///
- /// The resource to delete
- /// The type of resource to delete
- /// If the item is not found
- /// A representing the asynchronous operation.
- Task Delete(T item)
- where T : class, IResource;
-
- ///
- /// Delete a resource by it's ID.
- ///
- /// The id of the resource to delete
- /// The type of resource to delete
- /// If the item is not found
- /// A representing the asynchronous operation.
- Task Delete(int id)
- where T : class, IResource;
-
- ///
- /// Delete a resource by it's slug.
- ///
- /// The slug of the resource to delete
- /// The type of resource to delete
- /// If the item is not found
- /// A representing the asynchronous operation.
- Task Delete(string slug)
- where T : class, IResource;
+ IRepository Users { get; }
}
}
diff --git a/back/src/Kyoo.Abstractions/Controllers/IRepository.cs b/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
index df64bbd7..a13fcd10 100644
--- a/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
+++ b/back/src/Kyoo.Abstractions/Controllers/IRepository.cs
@@ -22,6 +22,7 @@ using System.Linq.Expressions;
using System.Threading.Tasks;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Exceptions;
+using Kyoo.Abstractions.Models.Utils;
namespace Kyoo.Abstractions.Controllers
{
@@ -42,47 +43,55 @@ namespace Kyoo.Abstractions.Controllers
/// Get a resource from it's ID.
///
/// The id of the resource
+ /// The related fields to include.
/// If the item could not be found.
/// The resource found
- Task Get(int id);
+ Task Get(int id, Include? include = default);
///
/// Get a resource from it's slug.
///
/// The slug of the resource
+ /// The related fields to include.
/// If the item could not be found.
/// The resource found
- Task Get(string slug);
+ Task Get(string slug, Include? include = default);
///
/// Get the first resource that match the predicate.
///
/// A predicate to filter the resource.
+ /// The related fields to include.
/// If the item could not be found.
/// The resource found
- Task Get(Expression> where);
+ Task Get(Expression> where, Include? include = default);
///
/// Get a resource from it's ID or null if it is not found.
///
/// The id of the resource
+ /// The related fields to include.
/// The resource found
- Task GetOrDefault(int id);
+ Task GetOrDefault(int id, Include? include = default);
///
/// Get a resource from it's slug or null if it is not found.
///
/// The slug of the resource
+ /// The related fields to include.
/// The resource found
- Task GetOrDefault(string slug);
+ Task GetOrDefault(string slug, Include? include = default);
///
/// Get the first resource that match the predicate or null if it is not found.
///
/// A predicate to filter the resource.
+ /// The related fields to include.
/// A custom sort method to handle cases where multiples items match the filters.
/// The resource found
- Task GetOrDefault(Expression> where, Sort? sortBy = default);
+ Task GetOrDefault(Expression> where,
+ Include? include = default,
+ Sort? sortBy = default);
///
/// Search for resources.
@@ -97,10 +106,12 @@ namespace Kyoo.Abstractions.Controllers
/// A filter predicate
/// Sort information about the query (sort by, sort order)
/// How pagination should be done (where to start and how many to return)
+ /// The related fields to include.
/// A list of resources that match every filters
Task> GetAll(Expression>? where = null,
Sort? sort = default,
- Pagination? limit = default);
+ Pagination? limit = default,
+ Include? include = default);
///
/// Get the number of resources that match the filter's predicate.
@@ -200,209 +211,4 @@ namespace Kyoo.Abstractions.Controllers
///
Type RepositoryType { get; }
}
-
- ///
- /// A repository to handle shows.
- ///
- public interface IMovieRepository : IRepository { }
-
- ///
- /// A repository to handle shows.
- ///
- public interface IShowRepository : IRepository
- {
- ///
- /// Get a show's slug from it's ID.
- ///
- /// The ID of the show
- /// If a show with the given ID is not found.
- /// The show's slug
- Task GetSlug(int showID);
- }
-
- ///
- /// A repository to handle seasons.
- ///
- public interface ISeasonRepository : IRepository
- {
- ///
- /// Get a season from it's showID and it's seasonNumber
- ///
- /// The id of the show
- /// The season's number
- /// If the item is not found
- /// The season found
- Task Get(int showID, int seasonNumber);
-
- ///
- /// Get a season from it's show slug and it's seasonNumber
- ///
- /// The slug of the show
- /// The season's number
- /// If the item is not found
- /// The season found
- Task Get(string showSlug, int seasonNumber);
-
- ///
- /// Get a season from it's showID and it's seasonNumber or null if it is not found.
- ///
- /// The id of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(int showID, int seasonNumber);
-
- ///
- /// Get a season from it's show slug and it's seasonNumber or null if it is not found.
- ///
- /// The slug of the show
- /// The season's number
- /// The season found
- Task GetOrDefault(string showSlug, int seasonNumber);
- }
-
- ///
- /// The repository to handle episodes
- ///
- public interface IEpisodeRepository : IRepository
- {
- // TODO replace the next methods with extension methods.
-
- ///
- /// Get a episode from it's showID, it's seasonNumber and it's episode number.
- ///
- /// The id of the show
- /// The season's number
- /// The episode's number
- /// If the item is not found
- /// The episode found
- Task Get(int showID, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's show slug, it's seasonNumber and it's episode number.
- ///
- /// The slug of the show
- /// The season's number
- /// The episode's number
- /// If the item is not found
- /// The episode found
- Task Get(string showSlug, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
- ///
- /// The id of the show
- /// The season's number
- /// The episode's number
- /// The episode found
- Task GetOrDefault(int showID, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's show slug, it's seasonNumber and it's episode number or null if it is not found.
- ///
- /// The slug of the show
- /// The season's number
- /// The episode's number
- /// The episode found
- Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
-
- ///
- /// Get a episode from it's showID and it's absolute number.
- ///
- /// The id of the show
- /// The episode's absolute number (The episode number does not reset to 1 after the end of a season.
- /// If the item is not found
- /// The episode found
- Task GetAbsolute(int showID, int absoluteNumber);
-
- ///
- /// Get a episode from it's showID and it's absolute number.
- ///
- /// The slug of the show
- /// The episode's absolute number (The episode number does not reset to 1 after the end of a season.
- /// If the item is not found
- /// The episode found
- Task GetAbsolute(string showSlug, int absoluteNumber);
- }
-
- ///
- /// A repository to handle library items (A wrapper around shows and collections).
- ///
- public interface ILibraryItemRepository : IRepository { }
-
- ///
- /// A repository for collections
- ///
- public interface ICollectionRepository : IRepository { }
-
- ///
- /// A repository for studios.
- ///
- public interface IStudioRepository : IRepository { }
-
- ///
- /// A repository for people.
- ///
- public interface IPeopleRepository : IRepository
- {
- ///
- /// Get people's roles from a show.
- ///
- /// The ID of the show
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given ID.
- /// A list of items that match every filters
- Task> GetFromShow(int showID,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a show.
- ///
- /// The slug of the show
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given slug.
- /// A list of items that match every filters
- Task> GetFromShow(string showSlug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a person.
- ///
- /// The id of the person
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given ID.
- /// A list of items that match every filters
- Task> GetFromPeople(int id,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
-
- ///
- /// Get people's roles from a person.
- ///
- /// The slug of the person
- /// A filter function
- /// Sort information (sort order and sort by)
- /// How many items to return and where to start
- /// No exist with the given slug.
- /// A list of items that match every filters
- Task> GetFromPeople(string slug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default);
- }
-
- ///
- /// A repository to handle users.
- ///
- public interface IUserRepository : IRepository { }
}
diff --git a/back/src/Kyoo.Abstractions/Models/Utils/Include.cs b/back/src/Kyoo.Abstractions/Models/Utils/Include.cs
new file mode 100644
index 00000000..6cedf16c
--- /dev/null
+++ b/back/src/Kyoo.Abstractions/Models/Utils/Include.cs
@@ -0,0 +1,48 @@
+// Kyoo - A portable and vast media library solution.
+// Copyright (c) Kyoo.
+//
+// See AUTHORS.md and LICENSE file in the project root for full license information.
+//
+// Kyoo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// Kyoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Kyoo. If not, see .
+
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+using Kyoo.Abstractions.Models.Attributes;
+
+namespace Kyoo.Abstractions.Models.Utils;
+
+public class Include
+ where T : IResource
+{
+ public string[] Fields { get; private init; }
+
+ public static Include From(string fields)
+ {
+ if (string.IsNullOrEmpty(fields))
+ return new();
+
+ string[] values = fields.Split(',');
+ foreach (string field in values)
+ {
+ PropertyInfo? prop = typeof(T).GetProperty(field, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
+ if (prop?.GetCustomAttribute() == null)
+ throw new ValidationException($"No loadable relation with the name {field}.");
+ }
+
+ return new()
+ {
+ Fields = values,
+ };
+ }
+}
diff --git a/back/src/Kyoo.Authentication/Views/AuthApi.cs b/back/src/Kyoo.Authentication/Views/AuthApi.cs
index 2040ac13..5effe83d 100644
--- a/back/src/Kyoo.Authentication/Views/AuthApi.cs
+++ b/back/src/Kyoo.Authentication/Views/AuthApi.cs
@@ -47,7 +47,7 @@ namespace Kyoo.Authentication.Views
///
/// The repository to handle users.
///
- private readonly IUserRepository _users;
+ private readonly IRepository _users;
///
/// The token generator.
@@ -65,7 +65,7 @@ namespace Kyoo.Authentication.Views
/// The repository used to check if the user exists.
/// The token generator.
/// The permission opitons.
- public AuthApi(IUserRepository users, ITokenController token, PermissionOption permissions)
+ public AuthApi(IRepository users, ITokenController token, PermissionOption permissions)
{
_users = users;
_token = token;
diff --git a/back/src/Kyoo.Core/Controllers/LibraryManager.cs b/back/src/Kyoo.Core/Controllers/LibraryManager.cs
index 664f56bb..bceab8f8 100644
--- a/back/src/Kyoo.Core/Controllers/LibraryManager.cs
+++ b/back/src/Kyoo.Core/Controllers/LibraryManager.cs
@@ -16,16 +16,8 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
-using Kyoo.Abstractions.Models.Exceptions;
-using Kyoo.Utils;
namespace Kyoo.Core.Controllers
{
@@ -34,438 +26,53 @@ namespace Kyoo.Core.Controllers
///
public class LibraryManager : ILibraryManager
{
- ///
- /// The list of repositories
- ///
- private readonly IBaseRepository[] _repositories;
-
- ///
- public ILibraryItemRepository LibraryItemRepository { get; }
-
- ///
- public ICollectionRepository CollectionRepository { get; }
-
- ///
- public IMovieRepository MovieRepository { get; }
-
- ///
- public IShowRepository ShowRepository { get; }
-
- ///
- public ISeasonRepository SeasonRepository { get; }
-
- ///
- public IEpisodeRepository EpisodeRepository { get; }
-
- ///
- public IPeopleRepository PeopleRepository { get; }
-
- ///
- public IStudioRepository StudioRepository { get; }
-
- ///
- public IUserRepository UserRepository { get; }
-
- ///
- /// Create a new instance with every repository available.
- ///
- /// The list of repositories that this library manager should manage.
- /// If a repository for every base type is not available, this instance won't be stable.
- public LibraryManager(IEnumerable repositories)
+ public LibraryManager(
+ IRepository libraryItemRepository,
+ IRepository collectionRepository,
+ IRepository movieRepository,
+ IRepository showRepository,
+ IRepository seasonRepository,
+ IRepository episodeRepository,
+ IRepository peopleRepository,
+ IRepository studioRepository,
+ IRepository userRepository)
{
- _repositories = repositories.ToArray();
- LibraryItemRepository = (ILibraryItemRepository)GetRepository();
- CollectionRepository = (ICollectionRepository)GetRepository();
- MovieRepository = (IMovieRepository)GetRepository();
- ShowRepository = (IShowRepository)GetRepository();
- SeasonRepository = (ISeasonRepository)GetRepository();
- EpisodeRepository = (IEpisodeRepository)GetRepository();
- PeopleRepository = (IPeopleRepository)GetRepository();
- StudioRepository = (IStudioRepository)GetRepository();
- UserRepository = (IUserRepository)GetRepository();
+ LibraryItems = libraryItemRepository;
+ Collections = collectionRepository;
+ Movies = movieRepository;
+ Shows = showRepository;
+ Seasons = seasonRepository;
+ Episodes = episodeRepository;
+ People = peopleRepository;
+ Studios = studioRepository;
+ Users = userRepository;
}
///
- public IRepository GetRepository()
- where T : class, IResource
- {
- if (_repositories.FirstOrDefault(x => x.RepositoryType == typeof(T)) is IRepository ret)
- return ret;
- throw new ItemNotFoundException($"No repository found for the type {typeof(T).Name}.");
- }
+ public IRepository LibraryItems { get; }
///
- public Task Get(int id)
- where T : class, IResource
- {
- return GetRepository().Get(id);
- }
+ public IRepository Collections { get; }
///
- public Task Get(string slug)
- where T : class, IResource
- {
- return GetRepository().Get(slug);
- }
+ public IRepository Movies { get; }
///
- public Task Get(Expression> where)
- where T : class, IResource
- {
- return GetRepository().Get(where);
- }
+ public IRepository Shows { get; }
///
- public Task Get(int showID, int seasonNumber)
- {
- return SeasonRepository.Get(showID, seasonNumber);
- }
+ public IRepository Seasons { get; }
///
- public Task Get(string showSlug, int seasonNumber)
- {
- return SeasonRepository.Get(showSlug, seasonNumber);
- }
+ public IRepository Episodes { get; }
///
- public Task Get(int showID, int seasonNumber, int episodeNumber)
- {
- return EpisodeRepository.Get(showID, seasonNumber, episodeNumber);
- }
+ public IRepository People { get; }
///
- public Task Get(string showSlug, int seasonNumber, int episodeNumber)
- {
- return EpisodeRepository.Get(showSlug, seasonNumber, episodeNumber);
- }
+ public IRepository Studios { get; }
///
- public async Task GetOrDefault(int id)
- where T : class, IResource
- {
- return await GetRepository().GetOrDefault(id);
- }
-
- ///
- public async Task GetOrDefault(string slug)
- where T : class, IResource
- {
- return await GetRepository().GetOrDefault(slug);
- }
-
- ///
- public async Task GetOrDefault(Expression> where, Sort? sortBy)
- where T : class, IResource
- {
- return await GetRepository().GetOrDefault(where, sortBy);
- }
-
- ///
- public async Task GetOrDefault(int showID, int seasonNumber)
- {
- return await SeasonRepository.GetOrDefault(showID, seasonNumber);
- }
-
- ///
- public async Task GetOrDefault(string showSlug, int seasonNumber)
- {
- return await SeasonRepository.GetOrDefault(showSlug, seasonNumber);
- }
-
- ///
- public async Task GetOrDefault(int showID, int seasonNumber, int episodeNumber)
- {
- return await EpisodeRepository.GetOrDefault(showID, seasonNumber, episodeNumber);
- }
-
- ///
- public async Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber)
- {
- return await EpisodeRepository.GetOrDefault(showSlug, seasonNumber, episodeNumber);
- }
-
- ///
- /// Set relations between to objects.
- ///
- /// The owner object
- /// A Task to load a collection of related objects
- /// A setter function to store the collection of related objects
- /// A setter function to store the owner of a releated object loaded
- /// The type of the owner object
- /// The type of the related object
- private static async Task _SetRelation(T1 obj,
- Task> loader,
- Action> setter,
- Action inverse)
- {
- ICollection loaded = await loader;
- setter(obj, loaded);
- foreach (T2 item in loaded)
- inverse(item, obj);
- }
-
- ///
- public Task Load(T obj, Expression> member, bool force = false)
- where T : class, IResource
- where T2 : class, IResource
- {
- return Load(obj, Utility.GetPropertyName(member), force);
- }
-
- ///
- public Task Load(T obj, Expression>> member, bool force = false)
- where T : class, IResource
- where T2 : class
- {
- return Load(obj, Utility.GetPropertyName(member), force);
- }
-
- ///
- public async Task Load(T obj, string memberName, bool force = false)
- where T : class, IResource
- {
- await Load(obj as IResource, memberName, force);
- return obj;
- }
-
- ///
- [SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:CodeMustNotContainMultipleBlankLinesInARow",
- Justification = "Separate the code by semantics and simplify the code read.")]
- [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1107:Code should not contain multiple statements on one line",
- Justification = "Assing IDs and Values in the same line.")]
- public Task Load(IResource obj, string memberName, bool force = false)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
-
- object? existingValue = obj.GetType()
- .GetProperties()
- .FirstOrDefault(x => string.Equals(x.Name, memberName, StringComparison.InvariantCultureIgnoreCase))
- ?.GetValue(obj);
- if (existingValue != null && !force)
- return Task.CompletedTask;
-
- return (obj, member: memberName) switch
- {
- (Collection c, nameof(Collection.Shows)) => ShowRepository
- .GetAll(x => x.Collections!.Any(y => y.Id == obj.Id))
- .Then(x => c.Shows = x),
-
- (Collection c, nameof(Collection.Movies)) => MovieRepository
- .GetAll(x => x.Collections!.Any(y => y.Id == obj.Id))
- .Then(x => c.Movies = x),
-
-
- (Movie m, nameof(Movie.People)) => PeopleRepository
- .GetFromShow(obj.Id)
- .Then(x => m.People = x),
-
- (Movie m, nameof(Movie.Collections)) => CollectionRepository
- .GetAll(x => x.Movies!.Any(y => y.Id == obj.Id))
- .Then(x => m.Collections = x),
-
- (Movie m, nameof(Movie.Studio)) => StudioRepository
- .GetOrDefault(x => x.Movies!.Any(y => y.Id == obj.Id))
- .Then(x =>
- {
- m.Studio = x;
- m.StudioID = x?.Id ?? 0;
- }),
-
-
- (Show s, nameof(Show.People)) => PeopleRepository
- .GetFromShow(obj.Id)
- .Then(x => s.People = x),
-
- (Show s, nameof(Show.Seasons)) => _SetRelation(s,
- SeasonRepository.GetAll(x => x.Show!.Id == obj.Id),
- (x, y) => x.Seasons = y,
- (x, y) => { x.Show = y; x.ShowId = y.Id; }),
-
- (Show s, nameof(Show.Episodes)) => _SetRelation(s,
- EpisodeRepository.GetAll(x => x.Show!.Id == obj.Id),
- (x, y) => x.Episodes = y,
- (x, y) => { x.Show = y; x.ShowId = y.Id; }),
-
- (Show s, nameof(Show.Collections)) => CollectionRepository
- .GetAll(x => x.Shows!.Any(y => y.Id == obj.Id))
- .Then(x => s.Collections = x),
-
- (Show s, nameof(Show.Studio)) => StudioRepository
- .GetOrDefault(x => x.Shows!.Any(y => y.Id == obj.Id))
- .Then(x =>
- {
- s.Studio = x;
- s.StudioId = x?.Id ?? 0;
- }),
-
-
- (Season s, nameof(Season.Episodes)) => _SetRelation(s,
- EpisodeRepository.GetAll(x => x.Season!.Id == obj.Id),
- (x, y) => x.Episodes = y,
- (x, y) => { x.Season = y; x.SeasonId = y.Id; }),
-
- (Season s, nameof(Season.Show)) => ShowRepository
- .GetOrDefault(x => x.Seasons!.Any(y => y.Id == obj.Id))
- .Then(x =>
- {
- s.Show = x;
- s.ShowId = x?.Id ?? 0;
- }),
-
-
- (Episode e, nameof(Episode.Show)) => ShowRepository
- .GetOrDefault(x => x.Episodes!.Any(y => y.Id == obj.Id))
- .Then(x =>
- {
- e.Show = x;
- e.ShowId = x?.Id ?? 0;
- }),
-
- (Episode e, nameof(Episode.Season)) => SeasonRepository
- .GetOrDefault(x => x.Episodes!.Any(y => y.Id == e.Id))
- .Then(x =>
- {
- e.Season = x;
- e.SeasonId = x?.Id ?? 0;
- }),
-
- (Episode e, nameof(Episode.PreviousEpisode)) => EpisodeRepository
- .GetAll(
- where: x => x.ShowId == e.ShowId,
- limit: new Pagination(1, e.Id, true)
- ).Then(x => e.PreviousEpisode = x.FirstOrDefault()),
-
- (Episode e, nameof(Episode.NextEpisode)) => EpisodeRepository
- .GetAll(
- where: x => x.ShowId == e.ShowId,
- limit: new Pagination(1, e.Id)
- ).Then(x => e.NextEpisode = x.FirstOrDefault()),
-
-
- (Studio s, nameof(Studio.Shows)) => ShowRepository
- .GetAll(x => x.Studio!.Id == obj.Id)
- .Then(x => s.Shows = x),
-
- (Studio s, nameof(Studio.Movies)) => MovieRepository
- .GetAll(x => x.Studio!.Id == obj.Id)
- .Then(x => s.Movies = x),
-
-
- (People p, nameof(People.Roles)) => PeopleRepository
- .GetFromPeople(obj.Id)
- .Then(x => p.Roles = x),
-
- _ => throw new ArgumentException($"Couldn't find a way to load {memberName} of {obj.Slug}.")
- };
- }
-
- ///
- public Task> GetPeopleFromShow(int showID,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- {
- return PeopleRepository.GetFromShow(showID, where, sort, limit);
- }
-
- ///
- public Task> GetPeopleFromShow(string showSlug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- {
- return PeopleRepository.GetFromShow(showSlug, where, sort, limit);
- }
-
- ///
- public Task> GetRolesFromPeople(int id,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- {
- return PeopleRepository.GetFromPeople(id, where, sort, limit);
- }
-
- ///
- public Task> GetRolesFromPeople(string slug,
- Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- {
- return PeopleRepository.GetFromPeople(slug, where, sort, limit);
- }
-
- ///
- public Task> GetAll(Expression>? where = null,
- Sort? sort = default,
- Pagination? limit = default)
- where T : class, IResource
- {
- return GetRepository().GetAll(where, sort, limit);
- }
-
- ///
- public Task GetCount(Expression>? where = null)
- where T : class, IResource
- {
- return GetRepository().GetCount(where);
- }
-
- ///
- public Task> Search(string query)
- where T : class, IResource
- {
- return GetRepository().Search(query);
- }
-
- ///
- public Task Create(T item)
- where T : class, IResource
- {
- return GetRepository().Create(item);
- }
-
- ///
- public Task CreateIfNotExists(T item)
- where T : class, IResource
- {
- return GetRepository().CreateIfNotExists(item);
- }
-
- ///
- public Task Edit(T item)
- where T : class, IResource
- {
- return GetRepository().Edit(item);
- }
-
- ///
- public Task Patch(int id, Func> patch)
- where T : class, IResource
- {
- return GetRepository().Patch(id, patch);
- }
-
- ///
- public Task Delete(T item)
- where T : class, IResource
- {
- return GetRepository().Delete(item);
- }
-
- ///
- public Task Delete(int id)
- where T : class, IResource
- {
- return GetRepository().Delete(id);
- }
-
- ///
- public Task Delete(string slug)
- where T : class, IResource
- {
- return GetRepository