using System; using System.Linq.Expressions; using System.Reflection; using Kyoo.Models; using Microsoft.EntityFrameworkCore; using Npgsql; namespace Kyoo.Postgresql { /// /// A postgresql implementation of . /// public class PostgresContext : DatabaseContext { /// /// The connection string to use. /// private readonly string _connection; /// /// Is this instance in debug mode? /// private readonly bool _debugMode; /// /// Should the configure step be skipped? This is used when the database is created via DbContextOptions. /// private readonly bool _skipConfigure; static PostgresContext() { NpgsqlConnection.GlobalTypeMapper.MapEnum(); NpgsqlConnection.GlobalTypeMapper.MapEnum(); NpgsqlConnection.GlobalTypeMapper.MapEnum(); } /// /// A basic constructor that set default values (query tracker behaviors, mapping enums...) /// public PostgresContext() { } /// /// Create a new using specific options /// /// The options to use. public PostgresContext(DbContextOptions options) : base(options) { _skipConfigure = true; } /// /// A basic constructor that set default values (query tracker behaviors, mapping enums...) /// /// The connection string to use /// Is this instance in debug mode? public PostgresContext(string connection, bool debugMode) { _connection = connection; _debugMode = debugMode; } /// /// Set connection information for this database context /// /// An option builder to fill. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!_skipConfigure) { if (_connection != null) optionsBuilder.UseNpgsql(_connection); else optionsBuilder.UseNpgsql(); if (_debugMode) optionsBuilder.EnableDetailedErrors().EnableSensitiveDataLogging(); } base.OnConfiguring(optionsBuilder); } /// /// Set database parameters to support every types of Kyoo. /// /// The database's model builder. protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasPostgresEnum(); modelBuilder.HasPostgresEnum(); modelBuilder.HasPostgresEnum(); modelBuilder.Entity() .Property(x => x.ExtraData) .HasColumnType("jsonb"); base.OnModelCreating(modelBuilder); } /// protected override bool IsDuplicateException(Exception ex) { return ex.InnerException is PostgresException {SqlState: PostgresErrorCodes.UniqueViolation}; } /// public override Expression> Like(Expression> query, string format) { MethodInfo iLike = MethodOfUtils.MethodOf(EF.Functions.ILike); MethodCallExpression call = Expression.Call(iLike, Expression.Constant(EF.Functions), query.Body, Expression.Constant(format)); return Expression.Lambda>(call, query.Parameters); } } }