1
+ using System ;
2
+ using System . Text ;
3
+ using Microsoft . EntityFrameworkCore ;
4
+ using Microsoft . EntityFrameworkCore . Storage ;
5
+ using Npgsql . EntityFrameworkCore . PostgreSQL . Storage . Internal ;
6
+ using Ombi . Core . Models ;
7
+ using Polly ;
8
+ using Pomelo . EntityFrameworkCore . MySql . Storage . Internal ;
9
+
10
+ namespace Ombi . Core . Helpers ;
11
+
12
+ public static class DatabaseConfigurationSetup
13
+ {
14
+ public static void ConfigurePostgres ( DbContextOptionsBuilder options , PerDatabaseConfiguration config )
15
+ {
16
+ options . UseNpgsql ( config . ConnectionString , b =>
17
+ {
18
+ b . EnableRetryOnFailure ( ) ;
19
+ } ) . ReplaceService < ISqlGenerationHelper , NpgsqlCaseInsensitiveSqlGenerationHelper > ( ) ;
20
+ }
21
+
22
+ public static void ConfigureMySql ( DbContextOptionsBuilder options , PerDatabaseConfiguration config )
23
+ {
24
+ if ( string . IsNullOrEmpty ( config . ConnectionString ) )
25
+ {
26
+ throw new ArgumentNullException ( "ConnectionString for the MySql/Mariadb database is empty" ) ;
27
+ }
28
+
29
+ options . UseMySql ( config . ConnectionString , GetServerVersion ( config . ConnectionString ) , b =>
30
+ {
31
+ //b.CharSetBehavior(Pomelo.EntityFrameworkCore.MySql.Infrastructure.CharSetBehavior.NeverAppend); // ##ISSUE, link to migrations?
32
+ b . EnableRetryOnFailure ( ) ;
33
+ } ) ;
34
+ }
35
+
36
+ private static ServerVersion GetServerVersion ( string connectionString )
37
+ {
38
+ // Workaround Windows bug, that can lead to the following exception:
39
+ //
40
+ // MySqlConnector.MySqlException (0x80004005): SSL Authentication Error
41
+ // ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
42
+ // ---> System.ComponentModel.Win32Exception (0x8009030F): The message or signature supplied for verification has been altered
43
+ //
44
+ // See https://github.com/dotnet/runtime/issues/17005#issuecomment-305848835
45
+ //
46
+ // Also workaround for the fact, that ServerVersion.AutoDetect() does not use any retrying strategy.
47
+ ServerVersion serverVersion = null ;
48
+ #pragma warning disable EF1001
49
+ var retryPolicy = Policy . Handle < Exception > ( exception => MySqlTransientExceptionDetector . ShouldRetryOn ( exception ) )
50
+ #pragma warning restore EF1001
51
+ . WaitAndRetry ( 3 , ( count , context ) => TimeSpan . FromMilliseconds ( count * 250 ) ) ;
52
+
53
+ serverVersion = retryPolicy . Execute ( ( ) => serverVersion = ServerVersion . AutoDetect ( connectionString ) ) ;
54
+
55
+ return serverVersion ;
56
+ }
57
+ public class NpgsqlCaseInsensitiveSqlGenerationHelper : NpgsqlSqlGenerationHelper
58
+ {
59
+ const string EFMigrationsHisory = "__EFMigrationsHistory" ;
60
+ public NpgsqlCaseInsensitiveSqlGenerationHelper ( RelationalSqlGenerationHelperDependencies dependencies )
61
+ : base ( dependencies ) { }
62
+ public override string DelimitIdentifier ( string identifier ) =>
63
+ base . DelimitIdentifier ( identifier == EFMigrationsHisory ? identifier : identifier . ToLower ( ) ) ;
64
+ public override void DelimitIdentifier ( StringBuilder builder , string identifier )
65
+ => base . DelimitIdentifier ( builder , identifier == EFMigrationsHisory ? identifier : identifier . ToLower ( ) ) ;
66
+ }
67
+ }
0 commit comments