mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 18:47:11 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // 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 System.Collections.Generic;
 | |
| using System.Data.Common;
 | |
| using System.Text.RegularExpressions;
 | |
| using Dapper;
 | |
| using InterpolatedSql.SqlBuilders;
 | |
| using Kyoo.Abstractions.Controllers;
 | |
| using Kyoo.Abstractions.Models;
 | |
| using Kyoo.Postgresql.Utils;
 | |
| using Kyoo.Utils;
 | |
| using Microsoft.AspNetCore.Hosting;
 | |
| using Microsoft.EntityFrameworkCore;
 | |
| using Microsoft.Extensions.Configuration;
 | |
| using Microsoft.Extensions.DependencyInjection;
 | |
| using Microsoft.Extensions.Hosting;
 | |
| using Npgsql;
 | |
| 
 | |
| namespace Kyoo.Postgresql
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// A module to add postgresql capacity to the app.
 | |
| 	/// </summary>
 | |
| 	public class PostgresModule : IPlugin
 | |
| 	{
 | |
| 		/// <inheritdoc />
 | |
| 		public string Name => "Postgresql";
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// The configuration to use. The database connection string is pulled from it.
 | |
| 		/// </summary>
 | |
| 		private readonly IConfiguration _configuration;
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// The host environment to check if the app is in debug mode.
 | |
| 		/// </summary>
 | |
| 		private readonly IWebHostEnvironment _environment;
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Create a new postgres module instance and use the given configuration and environment.
 | |
| 		/// </summary>
 | |
| 		/// <param name="configuration">The configuration to use</param>
 | |
| 		/// <param name="env">The environment that will be used (if the env is in development mode, more information will be displayed on errors.</param>
 | |
| 		public PostgresModule(IConfiguration configuration, IWebHostEnvironment env)
 | |
| 		{
 | |
| 			_configuration = configuration;
 | |
| 			_environment = env;
 | |
| 		}
 | |
| 
 | |
| 		/// <summary>
 | |
| 		/// Migrate the database.
 | |
| 		/// </summary>
 | |
| 		/// <param name="provider">The service list to retrieve the database context</param>
 | |
| 		public static void Initialize(IServiceProvider provider)
 | |
| 		{
 | |
| 			DatabaseContext context = provider.GetRequiredService<DatabaseContext>();
 | |
| 			context.Database.Migrate();
 | |
| 
 | |
| 			using NpgsqlConnection conn = (NpgsqlConnection)context.Database.GetDbConnection();
 | |
| 			conn.Open();
 | |
| 			conn.ReloadTypes();
 | |
| 
 | |
| 			SqlMapper.TypeMapProvider = (type) =>
 | |
| 			{
 | |
| 				return new CustomPropertyTypeMap(
 | |
| 					type,
 | |
| 					(type, name) =>
 | |
| 					{
 | |
| 						string newName = Regex.Replace(
 | |
| 							name,
 | |
| 							"(^|_)([a-z])",
 | |
| 							(match) => match.Groups[2].Value.ToUpperInvariant()
 | |
| 						);
 | |
| 						// TODO: Add images handling here (name: poster_source, newName: PosterSource) should set Poster.Source
 | |
| 						return type.GetProperty(newName)!;
 | |
| 					}
 | |
| 				);
 | |
| 			};
 | |
| 			SqlMapper.AddTypeHandler(
 | |
| 				typeof(Dictionary<string, MetadataId>),
 | |
| 				new JsonTypeHandler<Dictionary<string, MetadataId>>()
 | |
| 			);
 | |
| 			SqlMapper.AddTypeHandler(typeof(List<string>), new ListTypeHandler<string>());
 | |
| 			SqlMapper.AddTypeHandler(typeof(List<Genre>), new ListTypeHandler<Genre>());
 | |
| 			SqlMapper.AddTypeHandler(typeof(Wrapper), new Wrapper.Handler());
 | |
| 			InterpolatedSqlBuilderOptions.DefaultOptions.ReuseIdenticalParameters = true;
 | |
| 			InterpolatedSqlBuilderOptions.DefaultOptions.AutoFixSingleQuotes = false;
 | |
| 		}
 | |
| 
 | |
| 		/// <inheritdoc />
 | |
| 		public void Configure(IServiceCollection services)
 | |
| 		{
 | |
| 			DbConnectionStringBuilder builder =
 | |
| 				new()
 | |
| 				{
 | |
| 					["USER ID"] = _configuration.GetValue("POSTGRES_USER", "KyooUser"),
 | |
| 					["PASSWORD"] = _configuration.GetValue("POSTGRES_PASSWORD", "KyooPassword"),
 | |
| 					["SERVER"] = _configuration.GetValue("POSTGRES_SERVER", "db"),
 | |
| 					["PORT"] = _configuration.GetValue("POSTGRES_PORT", "5432"),
 | |
| 					["DATABASE"] = _configuration.GetValue("POSTGRES_DB", "kyooDB"),
 | |
| 					["POOLING"] = "true",
 | |
| 					["MAXPOOLSIZE"] = "95",
 | |
| 					["TIMEOUT"] = "30"
 | |
| 				};
 | |
| 
 | |
| 			services.AddDbContext<DatabaseContext, PostgresContext>(
 | |
| 				x =>
 | |
| 				{
 | |
| 					x.UseNpgsql(builder.ConnectionString).UseProjectables();
 | |
| 					if (_environment.IsDevelopment())
 | |
| 						x.EnableDetailedErrors().EnableSensitiveDataLogging();
 | |
| 				},
 | |
| 				ServiceLifetime.Transient
 | |
| 			);
 | |
| 			services.AddTransient<DbConnection>(
 | |
| 				(_) => new NpgsqlConnection(builder.ConnectionString)
 | |
| 			);
 | |
| 
 | |
| 			services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
 | |
| 		}
 | |
| 	}
 | |
| }
 |