From 9d6b2c7f78cfcdbf7e063e53eac0353ebcb07a72 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 4 Sep 2018 16:59:22 -0400 Subject: [PATCH] Switch to Pomelo MySQL EFCore provider --- README.md | 6 +++++- .../Configuration/DatabaseConfiguration.cs | 5 +++++ .../Configuration/DatabaseType.cs | 8 ++++++-- src/Tgstation.Server.Host/Core/Application.cs | 1 + .../Models/DatabaseContext.cs | 17 ++++++----------- .../Models/MySqlDatabaseContext.cs | 7 ++++++- .../Models/SqlServerDatabaseContext.cs | 2 +- .../Tgstation.Server.Host.csproj | 2 +- src/Tgstation.Server.Host/appsettings.json | 1 + 9 files changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 235c65c0c7..fa8078e467 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,16 @@ Create an `appsettings.Production.json` file next to `appsettings.json`. This wi - `Logging:LogLevel:Default`: Can be one of `Trace`, `Debug`, `Information`, `Warning`, `Error`, or `Critical`. Restricts what is put into the log files. Currently `Debug` is reccommended for help with error reporting. -- `Database:DatabaseType`: Can be one of `SqlServer` or `MySql`. Note that, at the time of this writing, there is a [blocking bug with the MySQL DBAL provider](https://bugs.mysql.com/bug.php?id=89855) which prevents its usage +- `Database:DatabaseType`: Can be one of `SqlServer`, `MariaDB`, or `MySql` + +- `Database:MySqlServerVersion`: The version of MySql/MariaDB the database resides on, can be left as null for attempted auto detection. Used by the MySQL/MariaDB provider for selection of [certain features](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/2.1.1/src/EFCore.MySql/Storage/Internal/ServerVersion.cs) ignore at your own risk. A string in the form `..` - `Database:ConnectionString`: Connection string for your database. Click [here](https://www.developerfusion.com/tools/sql-connection-string/) for an SQL Server generator or see [here](https://www.connectionstrings.com/mysql/) for a MySQL guide. ### Database Configuration +If using MySQL, our provider library [recommends you set 'utf8mb4' as your default charset](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1-recommended-server-charset) disregard at your own risk. + The user created for the application will need the privilege to create databases on the first run. Once the initial set of migrations is run, the create right may be revoked. The user should maintain DDL rights though for applying future migrations ### Starting diff --git a/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs b/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs index f397a2a61a..1bbe9365d7 100644 --- a/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs +++ b/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs @@ -34,5 +34,10 @@ /// If the database should be deleted on application startup. Should not be used in production! /// public bool DropDatabase { get; set; } + + /// + /// The form of the of a target MySQL/MariaDB server + /// + public string MySqlServerVersion { get; set; } } } diff --git a/src/Tgstation.Server.Host/Configuration/DatabaseType.cs b/src/Tgstation.Server.Host/Configuration/DatabaseType.cs index c536486427..2ca7d8fafc 100644 --- a/src/Tgstation.Server.Host/Configuration/DatabaseType.cs +++ b/src/Tgstation.Server.Host/Configuration/DatabaseType.cs @@ -10,8 +10,12 @@ /// SqlServer, /// - /// Use MySQL/MariaDB + /// Use MySQL /// - MySql + MySql, + /// + /// Use MariaDB + /// + MariaDB } } diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index c2bbf8d6c2..a556fcc952 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -153,6 +153,7 @@ namespace Tgstation.Server.Host.Core switch (dbType) { case DatabaseType.MySql: + case DatabaseType.MariaDB: services.AddDbContext(ConfigureDatabase); services.AddScoped(x => x.GetRequiredService()); break; diff --git a/src/Tgstation.Server.Host/Models/DatabaseContext.cs b/src/Tgstation.Server.Host/Models/DatabaseContext.cs index f887c2926b..a3d9817592 100644 --- a/src/Tgstation.Server.Host/Models/DatabaseContext.cs +++ b/src/Tgstation.Server.Host/Models/DatabaseContext.cs @@ -66,15 +66,10 @@ namespace Tgstation.Server.Host.Models /// protected ILogger Logger { get; } - /// - /// The connection string for the - /// - protected string ConnectionString => databaseConfiguration.ConnectionString; - /// /// The for the /// - readonly DatabaseConfiguration databaseConfiguration; + protected DatabaseConfiguration DatabaseConfiguration { get; } /// /// The for the @@ -85,12 +80,12 @@ namespace Tgstation.Server.Host.Models /// Construct a /// /// The for the - /// The containing the value of + /// The containing the value of /// The value of /// The value of public DatabaseContext(DbContextOptions dbContextOptions, IOptions databaseConfigurationOptions, IDatabaseSeeder databaseSeeder, ILogger logger) : base(dbContextOptions) { - databaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions)); + DatabaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions)); this.databaseSeeder = databaseSeeder ?? throw new ArgumentNullException(nameof(databaseSeeder)); Logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -140,14 +135,14 @@ namespace Tgstation.Server.Host.Models { Logger.LogInformation("Migrating database..."); - if (databaseConfiguration.DropDatabase) + if (DatabaseConfiguration.DropDatabase) { Logger.LogCritical("DropDatabase configuration option set! Dropping any existing database..."); await Database.EnsureDeletedAsync(cancellationToken).ConfigureAwait(false); } var wasEmpty = false; - if (databaseConfiguration.NoMigrations) + if (DatabaseConfiguration.NoMigrations) { Logger.LogWarning("Using all or nothing migration strategy!"); await Database.EnsureCreatedAsync(cancellationToken).ConfigureAwait(false); @@ -169,7 +164,7 @@ namespace Tgstation.Server.Host.Models else { Logger.LogDebug("No migrations applied!"); - if (databaseConfiguration.ResetAdminPassword) + if (DatabaseConfiguration.ResetAdminPassword) { Logger.LogWarning("Enabling and resetting admin password due to configuration!"); await databaseSeeder.ResetAdminPassword(this, cancellationToken).ConfigureAwait(false); diff --git a/src/Tgstation.Server.Host/Models/MySqlDatabaseContext.cs b/src/Tgstation.Server.Host/Models/MySqlDatabaseContext.cs index eb6f0c81cd..d95fce3224 100644 --- a/src/Tgstation.Server.Host/Models/MySqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Models/MySqlDatabaseContext.cs @@ -1,6 +1,8 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Pomelo.EntityFrameworkCore.MySql.Infrastructure; +using System; using Tgstation.Server.Host.Configuration; namespace Tgstation.Server.Host.Models @@ -24,7 +26,10 @@ namespace Tgstation.Server.Host.Models protected override void OnConfiguring(DbContextOptionsBuilder options) { base.OnConfiguring(options); - options.UseMySQL(ConnectionString); + if (DatabaseConfiguration.MySqlServerVersion != null) + options.UseMySql(DatabaseConfiguration.ConnectionString, mySqlOptions => mySqlOptions.ServerVersion(Version.Parse(DatabaseConfiguration.MySqlServerVersion), DatabaseConfiguration.DatabaseType == DatabaseType.MariaDB ? ServerType.MariaDb : ServerType.MySql)); + else + options.UseMySql(DatabaseConfiguration.ConnectionString); } } } diff --git a/src/Tgstation.Server.Host/Models/SqlServerDatabaseContext.cs b/src/Tgstation.Server.Host/Models/SqlServerDatabaseContext.cs index b0f7ae1372..d3d5aa8260 100644 --- a/src/Tgstation.Server.Host/Models/SqlServerDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Models/SqlServerDatabaseContext.cs @@ -24,7 +24,7 @@ namespace Tgstation.Server.Host.Models protected override void OnConfiguring(DbContextOptionsBuilder options) { base.OnConfiguring(options); - options.UseSqlServer(ConnectionString); + options.UseSqlServer(DatabaseConfiguration.ConnectionString); } } } diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index af69de349b..e18c381e94 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -39,8 +39,8 @@ - + diff --git a/src/Tgstation.Server.Host/appsettings.json b/src/Tgstation.Server.Host/appsettings.json index e975062243..7ea6760060 100644 --- a/src/Tgstation.Server.Host/appsettings.json +++ b/src/Tgstation.Server.Host/appsettings.json @@ -33,6 +33,7 @@ "DropDatabase": false, "DatabaseType": "SqlServer", "ResetAdminPassword": false, + "MySqlServerVersion": null, "ConnectionString": "Data Source=(local);Initial Catalog=TGS;Integrated Security=True" } }