MySQL Support (#345)

* MySQL EF support added using Pomelo MySQL provider.

* MySQL EF support added using Pomelo MySQL provider.
This commit is contained in:
Aaron Clauson
2018-10-27 16:15:21 +02:00
committed by Nicolas Dorier
parent 9cde4dc7e2
commit ce94c05fd3
8 changed files with 58 additions and 8 deletions

View File

@@ -35,6 +35,12 @@ using Xunit;
namespace BTCPayServer.Tests namespace BTCPayServer.Tests
{ {
public enum TestDatabases
{
Postgres,
MySQL,
}
public class BTCPayServerTester : IDisposable public class BTCPayServerTester : IDisposable
{ {
private string _Directory; private string _Directory;
@@ -57,6 +63,11 @@ namespace BTCPayServer.Tests
set; set;
} }
public string MySQL
{
get; set;
}
public string Postgres public string Postgres
{ {
get; set; get; set;
@@ -68,6 +79,10 @@ namespace BTCPayServer.Tests
get; set; get; set;
} }
public TestDatabases TestDatabase
{
get; set;
}
public bool MockRates { get; set; } = true; public bool MockRates { get; set; } = true;
@@ -94,7 +109,9 @@ namespace BTCPayServer.Tests
config.AppendLine($"btc.lightning={IntegratedLightning.AbsoluteUri}"); 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); config.AppendLine($"postgres=" + Postgres);
var confPath = Path.Combine(chainDirectory, "settings.config"); var confPath = Path.Combine(chainDirectory, "settings.config");
File.WriteAllText(confPath, config.ToString()); File.WriteAllText(confPath, config.ToString());

View File

@@ -60,7 +60,9 @@ namespace BTCPayServer.Tests
{ {
NBXplorerUri = ExplorerClient.Address, NBXplorerUri = ExplorerClient.Address,
LTCNBXplorerUri = LTCExplorerClient.Address, LTCNBXplorerUri = LTCExplorerClient.Address,
TestDatabase = Enum.Parse<TestDatabases>(GetEnvironment("TESTS_DB", TestDatabases.Postgres.ToString()), true),
Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"), 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 IntegratedLightning = MerchantCharge.Client.Uri
}; };
PayTester.Port = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture); PayTester.Port = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture);

View File

@@ -14,7 +14,9 @@ services:
TESTS_LTCRPCCONNECTION: server=http://litecoind:43782;ceiwHEbqWI83:DwubwWsoo3 TESTS_LTCRPCCONNECTION: server=http://litecoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_BTCNBXPLORERURL: http://nbxplorer:32838/ TESTS_BTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_LTCNBXPLORERURL: http://nbxplorer:32838/ TESTS_LTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_DB: "Postgres"
TESTS_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserver 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_PORT: 80
TESTS_HOSTNAME: tests TESTS_HOSTNAME: tests
TEST_MERCHANTLIGHTNINGD: "type=clightning;server=/etc/merchant_lightningd_datadir/lightning-rpc" TEST_MERCHANTLIGHTNINGD: "type=clightning;server=/etc/merchant_lightningd_datadir/lightning-rpc"
@@ -43,6 +45,7 @@ services:
links: links:
- nbxplorer - nbxplorer
- postgres - postgres
- mysql
- customer_lightningd - customer_lightningd
- merchant_lightningd - merchant_lightningd
- lightning-charged - lightning-charged
@@ -59,6 +62,7 @@ services:
links: links:
- nbxplorer - nbxplorer
- postgres - postgres
- mysql
- customer_lnd - customer_lnd
- merchant_lnd - merchant_lnd
@@ -204,6 +208,15 @@ services:
- "39372:5432" - "39372:5432"
expose: expose:
- "5432" - "5432"
mysql:
image: mysql:8.0.12
expose:
- "3306"
ports:
- "33036:3306"
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
merchant_lnd: merchant_lnd:
image: btcpayserver/lnd:0.5-beta image: btcpayserver/lnd:0.5-beta

View File

@@ -53,6 +53,7 @@
<PackageReference Include="NicolasDorier.RateLimits" Version="1.0.0.3" /> <PackageReference Include="NicolasDorier.RateLimits" Version="1.0.0.3" />
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" /> <PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.0" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
<PackageReference Include="Serilog" Version="2.7.1" /> <PackageReference Include="Serilog" Version="2.7.1" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />

View File

@@ -125,6 +125,7 @@ namespace BTCPayServer.Configuration
Logs.Configuration.LogInformation("Supported chains: " + String.Join(',', supportedChains.ToArray())); Logs.Configuration.LogInformation("Supported chains: " + String.Join(',', supportedChains.ToArray()));
PostgresConnectionString = conf.GetOrDefault<string>("postgres", null); PostgresConnectionString = conf.GetOrDefault<string>("postgres", null);
MySQLConnectionString = conf.GetOrDefault<string>("mysql", null);
BundleJsCss = conf.GetOrDefault<bool>("bundlejscss", true); BundleJsCss = conf.GetOrDefault<bool>("bundlejscss", true);
ExternalUrl = conf.GetOrDefault<Uri>("externalurl", null); ExternalUrl = conf.GetOrDefault<Uri>("externalurl", null);
@@ -231,6 +232,11 @@ namespace BTCPayServer.Configuration
get; get;
set; set;
} }
public string MySQLConnectionString
{
get;
set;
}
public Uri ExternalUrl public Uri ExternalUrl
{ {
get; get;

View File

@@ -31,6 +31,7 @@ namespace BTCPayServer.Configuration
app.Option("--regtest | -regtest", $"Use regtest (deprecated, use --network instead)", CommandOptionType.BoolValue); 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("--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("--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("--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("--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); 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();
builder.AppendLine("### Database ###"); builder.AppendLine("### Database ###");
builder.AppendLine("#postgres=User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;"); 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();
builder.AppendLine("### NBXplorer settings ###"); builder.AppendLine("### NBXplorer settings ###");
foreach (var n in new BTCPayNetworkProvider(networkType).GetAll()) foreach (var n in new BTCPayNetworkProvider(networkType).GetAll())

View File

@@ -17,7 +17,8 @@ namespace BTCPayServer.Data
public enum DatabaseType public enum DatabaseType
{ {
Sqlite, Sqlite,
Postgres Postgres,
MySQL,
} }
public class ApplicationDbContextFactory public class ApplicationDbContextFactory
{ {
@@ -95,6 +96,8 @@ namespace BTCPayServer.Data
builder builder
.UseNpgsql(_ConnectionString) .UseNpgsql(_ConnectionString)
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>(); .ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
else if (_Type == DatabaseType.MySQL)
builder.UseMySql(_ConnectionString);
} }
public void ConfigureHangfireBuilder(IGlobalConfiguration builder) public void ConfigureHangfireBuilder(IGlobalConfiguration builder)

View File

@@ -76,17 +76,23 @@ namespace BTCPayServer.Hosting
{ {
var opts = o.GetRequiredService<BTCPayServerOptions>(); var opts = o.GetRequiredService<BTCPayServerOptions>();
ApplicationDbContextFactory dbContext = null; 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"); var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db");
Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); Logs.Configuration.LogInformation($"SQLite DB used ({connStr})");
dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, 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; return dbContext;
}); });