using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Threading.Tasks; using JetBrains.Annotations; using Kyoo.Models; namespace Kyoo.Controllers { public readonly struct Pagination { public int Count { get; } public int AfterID { get; } public Pagination(int count, int afterID = 0) { Count = count; AfterID = afterID; } } public readonly struct Sort { public Expression> Key { get; } public bool Descendant { get; } public Sort(Expression> key, bool descendant = false) { Key = key; Descendant = descendant; if (!(Key.Body is MemberExpression)) throw new ArgumentException("The given sort key is not valid."); } public Sort(string sortBy) { if (string.IsNullOrEmpty(sortBy)) { Key = null; Descendant = false; return; } string key = sortBy.Contains(':') ? sortBy.Substring(0, sortBy.IndexOf(':')) : sortBy; string order = sortBy.Contains(':') ? sortBy.Substring(sortBy.IndexOf(':') + 1) : null; Key = Expression.Lambda>(Expression.Property(Expression.Parameter(typeof(T), "x"), key)); Descendant = order switch { "desc" => true, "asc" => false, _ => throw new ArgumentException($"The sort order, if set, should be :asc or :desc but it was :{order}.") }; } } public interface IRepository : IDisposable, IAsyncDisposable { Task Get(int id); Task Get(string slug); Task> Search(string query); Task> GetAll(Expression> where = null, Sort sort = default, Pagination page = default); Task> GetAll([Optional] Expression> where, Expression> sort, Pagination page = default ) => GetAll(where, new Sort(sort), page); Task Create([NotNull] T obj); Task CreateIfNotExists([NotNull] T obj); Task Edit([NotNull] T edited, bool resetOld); Task Delete(int id); Task Delete(string slug); Task Delete([NotNull] T obj); Task DeleteRange(params T[] objs) => DeleteRange(objs.AsEnumerable()); Task DeleteRange(IEnumerable objs); Task DeleteRange(params int[] ids) => DeleteRange(ids.AsEnumerable()); Task DeleteRange(IEnumerable ids); Task DeleteRange(params string[] slugs) => DeleteRange(slugs.AsEnumerable()); Task DeleteRange(IEnumerable slugs); } public interface IShowRepository : IRepository { Task GetByPath(string path); Task AddShowLink(int showID, int? libraryID, int? collectionID); } public interface ISeasonRepository : IRepository { Task Get(string showSlug, int seasonNumber); Task Delete(string showSlug, int seasonNumber); Task> GetSeasons(int showID); Task> GetSeasons(string showSlug); } public interface IEpisodeRepository : IRepository { Task Get(string showSlug, int seasonNumber, int episodeNumber); Task Delete(string showSlug, int seasonNumber, int episodeNumber); Task> GetEpisodes(int showID, int seasonNumber); Task> GetEpisodes(string showSlug, int seasonNumber); Task> GetEpisodes(int seasonID); } public interface ITrackRepository : IRepository { Task Get(int episodeID, string languageTag, bool isForced); } public interface ILibraryRepository : IRepository {} public interface ICollectionRepository : IRepository {} public interface IGenreRepository : IRepository {} public interface IStudioRepository : IRepository {} public interface IPeopleRepository : IRepository {} public interface IProviderRepository : IRepository {} }