mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 10:37:13 -04:00 
			
		
		
		
	Add watchlists on news and library items
This commit is contained in:
		
							parent
							
								
									948c98f95b
								
							
						
					
					
						commit
						6fbd00a38f
					
				| @ -0,0 +1,37 @@ | |||||||
|  | // 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 <https://www.gnu.org/licenses/>. | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using Kyoo.Utils; | ||||||
|  | 
 | ||||||
|  | namespace Kyoo.Abstractions.Models.Attributes; | ||||||
|  | 
 | ||||||
|  | [AttributeUsage(AttributeTargets.Class)] | ||||||
|  | public class SqlFirstColumnAttribute : Attribute | ||||||
|  | { | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// The name of the first column of the element. Used to split multiples | ||||||
|  | 	/// items on a single sql query. If not specified, it defaults to "Id". | ||||||
|  | 	/// </summary> | ||||||
|  | 	public string Name { get; set; } | ||||||
|  | 
 | ||||||
|  | 	public SqlFirstColumnAttribute(string name) | ||||||
|  | 	{ | ||||||
|  | 		Name = name.ToSnakeCase(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -244,7 +244,11 @@ namespace Kyoo.Abstractions.Models | |||||||
| 		/// Metadata of what an user as started/planned to watch. | 		/// Metadata of what an user as started/planned to watch. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | ||||||
| 		[LoadableRelation] public EpisodeWatchStatus? WatchStatus { get; set; } | 		[LoadableRelation( | ||||||
|  | 			Sql = "episode_watch_status", | ||||||
|  | 			On = "episode_id = \"this\".id and \"relation\".user_id = [current_user]" | ||||||
|  | 		)] | ||||||
|  | 		public EpisodeWatchStatus? WatchStatus { get; set; } | ||||||
| 
 | 
 | ||||||
| 		// There is a global query filter to filter by user so we just need to do single. | 		// There is a global query filter to filter by user so we just need to do single. | ||||||
| 		private EpisodeWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | 		private EpisodeWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ using System; | |||||||
| using System.ComponentModel; | using System.ComponentModel; | ||||||
| using System.ComponentModel.DataAnnotations; | using System.ComponentModel.DataAnnotations; | ||||||
| using System.Globalization; | using System.Globalization; | ||||||
|  | using Kyoo.Abstractions.Models.Attributes; | ||||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||||
| 
 | 
 | ||||||
| namespace Kyoo.Abstractions.Models | namespace Kyoo.Abstractions.Models | ||||||
| @ -47,6 +48,7 @@ namespace Kyoo.Abstractions.Models | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	[TypeConverter(typeof(ImageConvertor))] | 	[TypeConverter(typeof(ImageConvertor))] | ||||||
|  | 	[SqlFirstColumn(nameof(Source))] | ||||||
| 	public class Image | 	public class Image | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
|  | |||||||
| @ -152,7 +152,11 @@ namespace Kyoo.Abstractions.Models | |||||||
| 		/// Metadata of what an user as started/planned to watch. | 		/// Metadata of what an user as started/planned to watch. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | ||||||
| 		[LoadableRelation] public MovieWatchStatus? WatchStatus { get; set; } | 		[LoadableRelation( | ||||||
|  | 			Sql = "movie_watch_status", | ||||||
|  | 			On = "movie_id = \"this\".id and \"relation\".user_id = [current_user]" | ||||||
|  | 		)] | ||||||
|  | 		public MovieWatchStatus? WatchStatus { get; set; } | ||||||
| 
 | 
 | ||||||
| 		// There is a global query filter to filter by user so we just need to do single. | 		// There is a global query filter to filter by user so we just need to do single. | ||||||
| 		private MovieWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | 		private MovieWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | ||||||
|  | |||||||
| @ -193,7 +193,11 @@ namespace Kyoo.Abstractions.Models | |||||||
| 		/// Metadata of what an user as started/planned to watch. | 		/// Metadata of what an user as started/planned to watch. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | 		[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)] | ||||||
| 		[LoadableRelation] public ShowWatchStatus? WatchStatus { get; set; } | 		[LoadableRelation( | ||||||
|  | 			Sql = "show_watch_status", | ||||||
|  | 			On = "show_id = \"this\".id and \"relation\".user_id = [current_user]" | ||||||
|  | 		)] | ||||||
|  | 		public ShowWatchStatus? WatchStatus { get; set; } | ||||||
| 
 | 
 | ||||||
| 		// There is a global query filter to filter by user so we just need to do single. | 		// There is a global query filter to filter by user so we just need to do single. | ||||||
| 		private ShowWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | 		private ShowWatchStatus? _WatchStatus => Watched!.FirstOrDefault(); | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ namespace Kyoo.Abstractions.Models | |||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// Metadata of what an user as started/planned to watch. | 	/// Metadata of what an user as started/planned to watch. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
|  | 	[SqlFirstColumn(nameof(UserId))] | ||||||
| 	public class MovieWatchStatus : IAddedDate | 	public class MovieWatchStatus : IAddedDate | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| @ -105,6 +106,7 @@ namespace Kyoo.Abstractions.Models | |||||||
| 		public int? WatchedPercent { get; set; } | 		public int? WatchedPercent { get; set; } | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	[SqlFirstColumn(nameof(UserId))] | ||||||
| 	public class EpisodeWatchStatus : IAddedDate | 	public class EpisodeWatchStatus : IAddedDate | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| @ -157,6 +159,7 @@ namespace Kyoo.Abstractions.Models | |||||||
| 		public int? WatchedPercent { get; set; } | 		public int? WatchedPercent { get; set; } | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	[SqlFirstColumn(nameof(UserId))] | ||||||
| 	public class ShowWatchStatus : IAddedDate | 	public class ShowWatchStatus : IAddedDate | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
|  | |||||||
| @ -28,15 +28,35 @@ using System.Text.RegularExpressions; | |||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| using Dapper; | using Dapper; | ||||||
| using InterpolatedSql.Dapper; | using InterpolatedSql.Dapper; | ||||||
|  | using InterpolatedSql.Dapper.SqlBuilders; | ||||||
| using Kyoo.Abstractions.Controllers; | using Kyoo.Abstractions.Controllers; | ||||||
| using Kyoo.Abstractions.Models; | using Kyoo.Abstractions.Models; | ||||||
|  | using Kyoo.Abstractions.Models.Attributes; | ||||||
| using Kyoo.Abstractions.Models.Utils; | using Kyoo.Abstractions.Models.Utils; | ||||||
|  | using Kyoo.Authentication; | ||||||
| using Kyoo.Utils; | using Kyoo.Utils; | ||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
| 
 | 
 | ||||||
| namespace Kyoo.Core.Controllers; | namespace Kyoo.Core.Controllers; | ||||||
| 
 | 
 | ||||||
| public static class DapperHelper | public static class DapperHelper | ||||||
| { | { | ||||||
|  | 	public static SqlBuilder ProcessVariables(SqlBuilder sql, SqlVariableContext context) | ||||||
|  | 	{ | ||||||
|  | 		int start = 0; | ||||||
|  | 		while ((start = sql.IndexOf("[", start, false)) != -1) | ||||||
|  | 		{ | ||||||
|  | 			int end = sql.IndexOf("]", start, false); | ||||||
|  | 			if (end == -1) | ||||||
|  | 				throw new ArgumentException("Invalid sql variable substitue (missing ])"); | ||||||
|  | 			string var = sql.Format[(start + 1)..end]; | ||||||
|  | 			sql.Remove(start, end - start + 1); | ||||||
|  | 			sql.Insert(start, $"{context.ReadVar(var)}"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return sql; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public static string Property(string key, Dictionary<string, Type> config) | 	public static string Property(string key, Dictionary<string, Type> config) | ||||||
| 	{ | 	{ | ||||||
| 		if (key == "kind") | 		if (key == "kind") | ||||||
| @ -95,10 +115,12 @@ public static class DapperHelper | |||||||
| 					string owner = config.First(x => x.Value == declaring).Key; | 					string owner = config.First(x => x.Value == declaring).Key; | ||||||
| 					string lateral = sql.Contains("\"this\"") ? " lateral" : string.Empty; | 					string lateral = sql.Contains("\"this\"") ? " lateral" : string.Empty; | ||||||
| 					sql = sql.Replace("\"this\"", owner); | 					sql = sql.Replace("\"this\"", owner); | ||||||
| 					on = on?.Replace("\"this\"", owner); | 					on = on?.Replace("\"this\"", owner)?.Replace("\"relation\"", $"r{relation}"); | ||||||
|  | 					if (sql.Any(char.IsWhiteSpace)) | ||||||
|  | 						sql = $"({sql})"; | ||||||
| 					types.Add(type); | 					types.Add(type); | ||||||
| 					projection.AppendLine($", r{relation}.*"); | 					projection.AppendLine($", r{relation}.*"); | ||||||
| 					join.Append($"\nleft join{lateral} ({sql}) as r{relation} on r{relation}.{on}"); | 					join.Append($"\nleft join{lateral} {sql} as r{relation} on r{relation}.{on}"); | ||||||
| 					break; | 					break; | ||||||
| 				case Include.ProjectedRelation: | 				case Include.ProjectedRelation: | ||||||
| 					continue; | 					continue; | ||||||
| @ -197,13 +219,14 @@ public static class DapperHelper | |||||||
| 		Dictionary<string, Type> config, | 		Dictionary<string, Type> config, | ||||||
| 		Func<List<object?>, T> mapper, | 		Func<List<object?>, T> mapper, | ||||||
| 		Func<Guid, Task<T>> get, | 		Func<Guid, Task<T>> get, | ||||||
|  | 		SqlVariableContext context, | ||||||
| 		Include<T>? include, | 		Include<T>? include, | ||||||
| 		Filter<T>? filter, | 		Filter<T>? filter, | ||||||
| 		Sort<T>? sort, | 		Sort<T>? sort, | ||||||
| 		Pagination? limit) | 		Pagination? limit) | ||||||
| 		where T : class, IResource, IQuery | 		where T : class, IResource, IQuery | ||||||
| 	{ | 	{ | ||||||
| 		InterpolatedSql.Dapper.SqlBuilders.SqlBuilder query = new(db, command); | 		SqlBuilder query = new(db, command); | ||||||
| 
 | 
 | ||||||
| 		// Include handling | 		// Include handling | ||||||
| 		include ??= new(); | 		include ??= new(); | ||||||
| @ -227,6 +250,8 @@ public static class DapperHelper | |||||||
| 		if (limit != null) | 		if (limit != null) | ||||||
| 			query += $"\nlimit {limit.Limit}"; | 			query += $"\nlimit {limit.Limit}"; | ||||||
| 
 | 
 | ||||||
|  | 		ProcessVariables(query, context); | ||||||
|  | 
 | ||||||
| 		// Build query and prepare to do the query/projections | 		// Build query and prepare to do the query/projections | ||||||
| 		IDapperSqlCommand cmd = query.Build(); | 		IDapperSqlCommand cmd = query.Build(); | ||||||
| 		string sql = cmd.Sql; | 		string sql = cmd.Sql; | ||||||
| @ -280,7 +305,7 @@ public static class DapperHelper | |||||||
| 				return mapIncludes(mapper(nItems), nItems.Skip(config.Count)); | 				return mapIncludes(mapper(nItems), nItems.Skip(config.Count)); | ||||||
| 			}, | 			}, | ||||||
| 			ParametersDictionary.LoadFrom(cmd), | 			ParametersDictionary.LoadFrom(cmd), | ||||||
| 			splitOn: string.Join(',', types.Select(x => x == typeof(Image) ? "source" : "id")) | 			splitOn: string.Join(',', types.Select(x => x.GetCustomAttribute<SqlFirstColumnAttribute>()?.Name ?? "id")) | ||||||
| 		); | 		); | ||||||
| 		if (limit?.Reverse == true) | 		if (limit?.Reverse == true) | ||||||
| 			data = data.Reverse(); | 			data = data.Reverse(); | ||||||
| @ -292,6 +317,7 @@ public static class DapperHelper | |||||||
| 		FormattableString command, | 		FormattableString command, | ||||||
| 		Dictionary<string, Type> config, | 		Dictionary<string, Type> config, | ||||||
| 		Func<List<object?>, T> mapper, | 		Func<List<object?>, T> mapper, | ||||||
|  | 		SqlVariableContext context, | ||||||
| 		Include<T>? include, | 		Include<T>? include, | ||||||
| 		Filter<T>? filter, | 		Filter<T>? filter, | ||||||
| 		Sort<T>? sort = null, | 		Sort<T>? sort = null, | ||||||
| @ -303,6 +329,7 @@ public static class DapperHelper | |||||||
| 			config, | 			config, | ||||||
| 			mapper, | 			mapper, | ||||||
| 			get: null!, | 			get: null!, | ||||||
|  | 			context, | ||||||
| 			include, | 			include, | ||||||
| 			filter, | 			filter, | ||||||
| 			sort, | 			sort, | ||||||
| @ -315,6 +342,7 @@ public static class DapperHelper | |||||||
| 		this IDbConnection db, | 		this IDbConnection db, | ||||||
| 		FormattableString command, | 		FormattableString command, | ||||||
| 		Dictionary<string, Type> config, | 		Dictionary<string, Type> config, | ||||||
|  | 		SqlVariableContext context, | ||||||
| 		Filter<T>? filter) | 		Filter<T>? filter) | ||||||
| 		where T : class, IResource | 		where T : class, IResource | ||||||
| 	{ | 	{ | ||||||
| @ -322,7 +350,7 @@ public static class DapperHelper | |||||||
| 
 | 
 | ||||||
| 		if (filter != null) | 		if (filter != null) | ||||||
| 			query += ProcessFilter(filter, config); | 			query += ProcessFilter(filter, config); | ||||||
| 
 | 		ProcessVariables(query, context); | ||||||
| 		IDapperSqlCommand cmd = query.Build(); | 		IDapperSqlCommand cmd = query.Build(); | ||||||
| 
 | 
 | ||||||
| 		// language=postgreSQL | 		// language=postgreSQL | ||||||
| @ -334,3 +362,22 @@ public static class DapperHelper | |||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | public class SqlVariableContext | ||||||
|  | { | ||||||
|  | 	private readonly IHttpContextAccessor _accessor; | ||||||
|  | 
 | ||||||
|  | 	public SqlVariableContext(IHttpContextAccessor accessor) | ||||||
|  | 	{ | ||||||
|  | 		_accessor = accessor; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public object? ReadVar(string var) | ||||||
|  | 	{ | ||||||
|  | 		return var switch | ||||||
|  | 		{ | ||||||
|  | 			"current_user" => _accessor.HttpContext?.User.GetId(), | ||||||
|  | 			_ => throw new ArgumentException($"Invalid sql variable name: {var}") | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -25,7 +25,6 @@ using Kyoo.Abstractions.Controllers; | |||||||
| using Kyoo.Abstractions.Models; | using Kyoo.Abstractions.Models; | ||||||
| using Kyoo.Abstractions.Models.Exceptions; | using Kyoo.Abstractions.Models.Exceptions; | ||||||
| using Kyoo.Abstractions.Models.Utils; | using Kyoo.Abstractions.Models.Utils; | ||||||
| using static Kyoo.Core.Controllers.DapperHelper; |  | ||||||
| 
 | 
 | ||||||
| namespace Kyoo.Core.Controllers; | namespace Kyoo.Core.Controllers; | ||||||
| 
 | 
 | ||||||
| @ -42,9 +41,13 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 
 | 
 | ||||||
| 	protected DbConnection Database { get; init; } | 	protected DbConnection Database { get; init; } | ||||||
| 
 | 
 | ||||||
| 	public DapperRepository(DbConnection database) | 	protected SqlVariableContext Context { get; init; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	public DapperRepository(DbConnection database, SqlVariableContext context) | ||||||
| 	{ | 	{ | ||||||
| 		Database = database; | 		Database = database; | ||||||
|  | 		Context = context; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// <inheritdoc/> | 	/// <inheritdoc/> | ||||||
| @ -83,6 +86,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 				Config, | 				Config, | ||||||
| 				Mapper, | 				Mapper, | ||||||
| 				(id) => Get(id), | 				(id) => Get(id), | ||||||
|  | 				Context, | ||||||
| 				include, | 				include, | ||||||
| 				Filter.Or(ids.Select(x => new Filter<T>.Eq("id", x)).ToArray()), | 				Filter.Or(ids.Select(x => new Filter<T>.Eq("id", x)).ToArray()), | ||||||
| 				sort: null, | 				sort: null, | ||||||
| @ -99,6 +103,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 			Sql, | 			Sql, | ||||||
| 			Config, | 			Config, | ||||||
| 			Mapper, | 			Mapper, | ||||||
|  | 			Context, | ||||||
| 			include, | 			include, | ||||||
| 			new Filter<T>.Eq(nameof(IResource.Id), id) | 			new Filter<T>.Eq(nameof(IResource.Id), id) | ||||||
| 		); | 		); | ||||||
| @ -113,6 +118,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 				Sql, | 				Sql, | ||||||
| 				Config, | 				Config, | ||||||
| 				Mapper, | 				Mapper, | ||||||
|  | 				Context, | ||||||
| 				include, | 				include, | ||||||
| 				filter: null, | 				filter: null, | ||||||
| 				new Sort<T>.Random() | 				new Sort<T>.Random() | ||||||
| @ -122,6 +128,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 			Sql, | 			Sql, | ||||||
| 			Config, | 			Config, | ||||||
| 			Mapper, | 			Mapper, | ||||||
|  | 			Context, | ||||||
| 			include, | 			include, | ||||||
| 			new Filter<T>.Eq(nameof(IResource.Slug), slug) | 			new Filter<T>.Eq(nameof(IResource.Slug), slug) | ||||||
| 		); | 		); | ||||||
| @ -137,6 +144,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 			Sql, | 			Sql, | ||||||
| 			Config, | 			Config, | ||||||
| 			Mapper, | 			Mapper, | ||||||
|  | 			Context, | ||||||
| 			include, | 			include, | ||||||
| 			filter, | 			filter, | ||||||
| 			sortBy | 			sortBy | ||||||
| @ -154,6 +162,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 			Config, | 			Config, | ||||||
| 			Mapper, | 			Mapper, | ||||||
| 			(id) => Get(id), | 			(id) => Get(id), | ||||||
|  | 			Context, | ||||||
| 			include, | 			include, | ||||||
| 			filter, | 			filter, | ||||||
| 			sort ?? new Sort<T>.Default(), | 			sort ?? new Sort<T>.Default(), | ||||||
| @ -167,6 +176,7 @@ public abstract class DapperRepository<T> : IRepository<T> | |||||||
| 		return Database.Count( | 		return Database.Count( | ||||||
| 			Sql, | 			Sql, | ||||||
| 			Config, | 			Config, | ||||||
|  | 			Context, | ||||||
| 			filter | 			filter | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -76,8 +76,8 @@ namespace Kyoo.Core.Controllers | |||||||
| 			throw new InvalidDataException(); | 			throw new InvalidDataException(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public LibraryItemRepository(DbConnection database) | 		public LibraryItemRepository(DbConnection database, SqlVariableContext context) | ||||||
| 			: base(database) | 			: base(database, context) | ||||||
| 		{ } | 		{ } | ||||||
| 
 | 
 | ||||||
| 		public async Task<ICollection<ILibraryItem>> GetAllOfCollection( | 		public async Task<ICollection<ILibraryItem>> GetAllOfCollection( | ||||||
| @ -118,6 +118,7 @@ namespace Kyoo.Core.Controllers | |||||||
| 				}, | 				}, | ||||||
| 				Mapper, | 				Mapper, | ||||||
| 				(id) => Get(id), | 				(id) => Get(id), | ||||||
|  | 				Context, | ||||||
| 				include, | 				include, | ||||||
| 				filter, | 				filter, | ||||||
| 				sort ?? new Sort<ILibraryItem>.Default(), | 				sort ?? new Sort<ILibraryItem>.Default(), | ||||||
|  | |||||||
| @ -60,8 +60,8 @@ namespace Kyoo.Core.Controllers | |||||||
| 			throw new InvalidDataException(); | 			throw new InvalidDataException(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public NewsRepository(DbConnection database) | 		public NewsRepository(DbConnection database, SqlVariableContext context) | ||||||
| 			: base(database) | 			: base(database, context) | ||||||
| 		{ } | 		{ } | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -68,6 +68,7 @@ namespace Kyoo.Core | |||||||
| 			builder.RegisterRepository<UserRepository>(); | 			builder.RegisterRepository<UserRepository>(); | ||||||
| 			builder.RegisterRepository<NewsRepository>(); | 			builder.RegisterRepository<NewsRepository>(); | ||||||
| 			builder.RegisterType<WatchStatusRepository>().As<IWatchStatusRepository>().AsSelf().InstancePerLifetimeScope(); | 			builder.RegisterType<WatchStatusRepository>().As<IWatchStatusRepository>().AsSelf().InstancePerLifetimeScope(); | ||||||
|  | 			builder.RegisterType<SqlVariableContext>().InstancePerLifetimeScope(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/// <inheritdoc /> | 		/// <inheritdoc /> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user