From ce94c05fd3a5f5bf1fc3b5f749f3473f8cfe9c77 Mon Sep 17 00:00:00 2001 From: Aaron Clauson Date: Sat, 27 Oct 2018 16:15:21 +0200 Subject: [PATCH] MySQL Support (#345) * MySQL EF support added using Pomelo MySQL provider. * MySQL EF support added using Pomelo MySQL provider. --- BTCPayServer.Tests/BTCPayServerTester.cs | 19 ++++++++++++++++++- BTCPayServer.Tests/ServerTester.cs | 2 ++ BTCPayServer.Tests/docker-compose.yml | 13 +++++++++++++ BTCPayServer/BTCPayServer.csproj | 1 + .../Configuration/BTCPayServerOptions.cs | 6 ++++++ .../Configuration/DefaultConfiguration.cs | 2 ++ .../Data/ApplicationDbContextFactory.cs | 5 ++++- BTCPayServer/Hosting/BTCPayServerServices.cs | 18 ++++++++++++------ 8 files changed, 58 insertions(+), 8 deletions(-) diff --git a/BTCPayServer.Tests/BTCPayServerTester.cs b/BTCPayServer.Tests/BTCPayServerTester.cs index 1c8d6119e..a881e35fe 100644 --- a/BTCPayServer.Tests/BTCPayServerTester.cs +++ b/BTCPayServer.Tests/BTCPayServerTester.cs @@ -35,6 +35,12 @@ using Xunit; namespace BTCPayServer.Tests { + public enum TestDatabases + { + Postgres, + MySQL, + } + public class BTCPayServerTester : IDisposable { private string _Directory; @@ -57,6 +63,11 @@ namespace BTCPayServer.Tests set; } + public string MySQL + { + get; set; + } + public string Postgres { get; set; @@ -68,6 +79,10 @@ namespace BTCPayServer.Tests get; set; } + public TestDatabases TestDatabase + { + get; set; + } public bool MockRates { get; set; } = true; @@ -94,7 +109,9 @@ namespace BTCPayServer.Tests config.AppendLine($"btc.lightning={IntegratedLightning.AbsoluteUri}"); - if (Postgres != null) + if (TestDatabase == TestDatabases.MySQL && !String.IsNullOrEmpty(MySQL)) + config.AppendLine($"mysql=" + MySQL); + else if (!String.IsNullOrEmpty(Postgres)) config.AppendLine($"postgres=" + Postgres); var confPath = Path.Combine(chainDirectory, "settings.config"); File.WriteAllText(confPath, config.ToString()); diff --git a/BTCPayServer.Tests/ServerTester.cs b/BTCPayServer.Tests/ServerTester.cs index 1de74a055..9772035d9 100644 --- a/BTCPayServer.Tests/ServerTester.cs +++ b/BTCPayServer.Tests/ServerTester.cs @@ -60,7 +60,9 @@ namespace BTCPayServer.Tests { NBXplorerUri = ExplorerClient.Address, LTCNBXplorerUri = LTCExplorerClient.Address, + TestDatabase = Enum.Parse(GetEnvironment("TESTS_DB", TestDatabases.Postgres.ToString()), true), Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"), + MySQL = GetEnvironment("TESTS_MYSQL", "User ID=root;Host=127.0.0.1;Port=33036;Database=btcpayserver"), IntegratedLightning = MerchantCharge.Client.Uri }; PayTester.Port = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture); diff --git a/BTCPayServer.Tests/docker-compose.yml b/BTCPayServer.Tests/docker-compose.yml index 991288688..9085736c8 100644 --- a/BTCPayServer.Tests/docker-compose.yml +++ b/BTCPayServer.Tests/docker-compose.yml @@ -14,7 +14,9 @@ services: TESTS_LTCRPCCONNECTION: server=http://litecoind:43782;ceiwHEbqWI83:DwubwWsoo3 TESTS_BTCNBXPLORERURL: http://nbxplorer:32838/ TESTS_LTCNBXPLORERURL: http://nbxplorer:32838/ + TESTS_DB: "Postgres" TESTS_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver + TESTS_MYSQL: User ID=root;Host=mysql;Port=3306;Database=btcpayserver TESTS_PORT: 80 TESTS_HOSTNAME: tests TEST_MERCHANTLIGHTNINGD: "type=clightning;server=/etc/merchant_lightningd_datadir/lightning-rpc" @@ -43,6 +45,7 @@ services: links: - nbxplorer - postgres + - mysql - customer_lightningd - merchant_lightningd - lightning-charged @@ -59,6 +62,7 @@ services: links: - nbxplorer - postgres + - mysql - customer_lnd - merchant_lnd @@ -204,6 +208,15 @@ services: - "39372:5432" expose: - "5432" + + mysql: + image: mysql:8.0.12 + expose: + - "3306" + ports: + - "33036:3306" + environment: + - MYSQL_ALLOW_EMPTY_PASSWORD=yes merchant_lnd: image: btcpayserver/lnd:0.5-beta diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj index 8a891cac5..dbbe3084c 100644 --- a/BTCPayServer/BTCPayServer.csproj +++ b/BTCPayServer/BTCPayServer.csproj @@ -53,6 +53,7 @@ + diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs index c000e83e2..51febf179 100644 --- a/BTCPayServer/Configuration/BTCPayServerOptions.cs +++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs @@ -125,6 +125,7 @@ namespace BTCPayServer.Configuration Logs.Configuration.LogInformation("Supported chains: " + String.Join(',', supportedChains.ToArray())); PostgresConnectionString = conf.GetOrDefault("postgres", null); + MySQLConnectionString = conf.GetOrDefault("mysql", null); BundleJsCss = conf.GetOrDefault("bundlejscss", true); ExternalUrl = conf.GetOrDefault("externalurl", null); @@ -231,6 +232,11 @@ namespace BTCPayServer.Configuration get; set; } + public string MySQLConnectionString + { + get; + set; + } public Uri ExternalUrl { get; diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index 2cd86285a..05de6d0d3 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -31,6 +31,7 @@ namespace BTCPayServer.Configuration app.Option("--regtest | -regtest", $"Use regtest (deprecated, use --network instead)", CommandOptionType.BoolValue); app.Option("--chains | -c", $"Chains to support as a comma separated (default: btc; available: {chains})", CommandOptionType.SingleValue); app.Option("--postgres", $"Connection string to a PostgreSQL database (default: SQLite)", CommandOptionType.SingleValue); + app.Option("--mysql", $"Connection string to a MySQL database (default: SQLite)", CommandOptionType.SingleValue); app.Option("--externalurl", $"The expected external URL of this service, to use if BTCPay is behind a reverse proxy (default: empty, use the incoming HTTP request to figure out)", CommandOptionType.SingleValue); app.Option("--bundlejscss", $"Bundle JavaScript and CSS files for better performance (default: true)", CommandOptionType.SingleValue); app.Option("--rootpath", "The root path in the URL to access BTCPay (default: /)", CommandOptionType.SingleValue); @@ -108,6 +109,7 @@ namespace BTCPayServer.Configuration builder.AppendLine(); builder.AppendLine("### Database ###"); builder.AppendLine("#postgres=User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;"); + builder.AppendLine("#mysql=User ID=root;Password=myPassword;Host=localhost;Port=3306;Database=myDataBase;"); builder.AppendLine(); builder.AppendLine("### NBXplorer settings ###"); foreach (var n in new BTCPayNetworkProvider(networkType).GetAll()) diff --git a/BTCPayServer/Data/ApplicationDbContextFactory.cs b/BTCPayServer/Data/ApplicationDbContextFactory.cs index 3d1bb2ce0..58e8fee5d 100644 --- a/BTCPayServer/Data/ApplicationDbContextFactory.cs +++ b/BTCPayServer/Data/ApplicationDbContextFactory.cs @@ -17,7 +17,8 @@ namespace BTCPayServer.Data public enum DatabaseType { Sqlite, - Postgres + Postgres, + MySQL, } public class ApplicationDbContextFactory { @@ -95,6 +96,8 @@ namespace BTCPayServer.Data builder .UseNpgsql(_ConnectionString) .ReplaceService(); + else if (_Type == DatabaseType.MySQL) + builder.UseMySql(_ConnectionString); } public void ConfigureHangfireBuilder(IGlobalConfiguration builder) diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index ba0294710..c8b246cb4 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -76,17 +76,23 @@ namespace BTCPayServer.Hosting { var opts = o.GetRequiredService(); ApplicationDbContextFactory dbContext = null; - if (opts.PostgresConnectionString == null) + if (!String.IsNullOrEmpty(opts.PostgresConnectionString)) + { + Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); + dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); + } + else if(!String.IsNullOrEmpty(opts.MySQLConnectionString)) + { + Logs.Configuration.LogInformation($"MySQL DB used ({opts.MySQLConnectionString})"); + dbContext = new ApplicationDbContextFactory(DatabaseType.MySQL, opts.MySQLConnectionString); + } + else { var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); } - else - { - Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); - dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); - } + return dbContext; });