diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj
index e1dcfb2c5..fb9c22f3d 100644
--- a/BTCPayServer/BTCPayServer.csproj
+++ b/BTCPayServer/BTCPayServer.csproj
@@ -12,6 +12,7 @@
+
@@ -20,6 +21,7 @@
+
@@ -36,10 +38,6 @@
-
-
-
-
diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs
index ab7c0b717..2e0eb5e65 100644
--- a/BTCPayServer/Configuration/BTCPayServerOptions.cs
+++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs
@@ -56,11 +56,17 @@ namespace BTCPayServer.Configuration
Explorer = conf.GetOrDefault("explorer.url", networkInfo.DefaultExplorerUrl);
CookieFile = conf.GetOrDefault("explorer.cookiefile", networkInfo.DefaultExplorerCookieFile);
RequireHttps = conf.GetOrDefault("requirehttps", false);
+ PostgresConnectionString = conf.GetOrDefault("postgres", null);
}
public bool RequireHttps
{
get; set;
}
+ public string PostgresConnectionString
+ {
+ get;
+ set;
+ }
}
}
diff --git a/BTCPayServer/Configuration/BTCPayServerRuntime.cs b/BTCPayServer/Configuration/BTCPayServerRuntime.cs
index 293e36a36..f0da1c293 100644
--- a/BTCPayServer/Configuration/BTCPayServerRuntime.cs
+++ b/BTCPayServer/Configuration/BTCPayServerRuntime.cs
@@ -56,7 +56,11 @@ namespace BTCPayServer.Configuration
db = new DBreezeEngine(CreateDBPath(opts, "InvoiceDB"));
_Resources.Add(db);
- var dbContext = new ApplicationDbContextFactory(Path.Combine(opts.DataDir, "sqllite.db"));
+ ApplicationDbContextFactory dbContext = null;
+ if(opts.PostgresConnectionString == null)
+ dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"));
+ else
+ dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString);
DBFactory = dbContext;
InvoiceRepository = new InvoiceRepository(dbContext, db, Network);
diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs
index 76d5e6f40..53f362e8f 100644
--- a/BTCPayServer/Configuration/DefaultConfiguration.cs
+++ b/BTCPayServer/Configuration/DefaultConfiguration.cs
@@ -27,6 +27,7 @@ namespace BTCPayServer.Configuration
app.Option("--testnet | -testnet", $"Use testnet", CommandOptionType.BoolValue);
app.Option("--regtest | -regtest", $"Use regtest", CommandOptionType.BoolValue);
app.Option("--requirehttps", $"Will redirect to https version of the website (default: false)", CommandOptionType.BoolValue);
+ app.Option("--postgres", $"Connection string to postgres database (default: sqlite is used)", CommandOptionType.SingleValue);
app.Option("--explorerurl", $"Url of the NBxplorer (default: : Default setting of NBXplorer for the network)", CommandOptionType.SingleValue);
app.Option("--explorercookiefile", $"Path to the cookie file (default: Default setting of NBXplorer for the network)", CommandOptionType.SingleValue);
@@ -78,6 +79,9 @@ namespace BTCPayServer.Configuration
builder.AppendLine("#port=" + network.DefaultPort);
builder.AppendLine("#bind=127.0.0.1");
builder.AppendLine();
+ builder.AppendLine("### Database ###");
+ builder.AppendLine("#postgres=User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;");
+ builder.AppendLine();
builder.AppendLine("### NBXplorer settings ###");
builder.AppendLine("#explorer.url=" + network.DefaultExplorerUrl.AbsoluteUri);
builder.AppendLine("#explorer.cookiefile=" + network.DefaultExplorerCookieFile);
diff --git a/BTCPayServer/Data/ApplicationDbContext.cs b/BTCPayServer/Data/ApplicationDbContext.cs
index f97122d93..3ad386d14 100644
--- a/BTCPayServer/Data/ApplicationDbContext.cs
+++ b/BTCPayServer/Data/ApplicationDbContext.cs
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using BTCPayServer.Models;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
+using Microsoft.EntityFrameworkCore.Infrastructure;
namespace BTCPayServer.Data
{
@@ -52,8 +53,8 @@ namespace BTCPayServer.Data
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
- var options = optionsBuilder.Options.FindExtension();
- if(options?.ConnectionString == null)
+ var isConfigured = optionsBuilder.Options.Extensions.OfType().Any();
+ if(!isConfigured)
optionsBuilder.UseSqlite("Data Source=temp.db");
}
@@ -70,7 +71,8 @@ namespace BTCPayServer.Data
.HasIndex(o => o.InvoiceDataId);
builder.Entity()
- .HasKey(t => new {
+ .HasKey(t => new
+ {
t.ApplicationUserId,
t.StoreDataId
});
diff --git a/BTCPayServer/Data/ApplicationDbContextFactory.cs b/BTCPayServer/Data/ApplicationDbContextFactory.cs
index 3e8f70f85..d6368313f 100644
--- a/BTCPayServer/Data/ApplicationDbContextFactory.cs
+++ b/BTCPayServer/Data/ApplicationDbContextFactory.cs
@@ -3,22 +3,48 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Hangfire;
+using Hangfire.MemoryStorage;
+using Hangfire.PostgreSql;
namespace BTCPayServer.Data
{
+ public enum DatabaseType
+ {
+ Sqlite,
+ Postgres
+ }
public class ApplicationDbContextFactory
{
- string _Path;
- public ApplicationDbContextFactory(string path)
+ string _ConnectionString;
+ DatabaseType _Type;
+ public ApplicationDbContextFactory(DatabaseType type, string connectionString)
{
- _Path = path ?? throw new ArgumentNullException(nameof(path));
+ _ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
+ _Type = type;
}
public ApplicationDbContext CreateContext()
{
var builder = new DbContextOptionsBuilder();
- builder.UseSqlite("Data Source=" + _Path);
+ ConfigureBuilder(builder);
return new ApplicationDbContext(builder.Options);
}
+
+ public void ConfigureBuilder(DbContextOptionsBuilder builder)
+ {
+ if(_Type == DatabaseType.Sqlite)
+ builder.UseSqlite(_ConnectionString);
+ else if(_Type == DatabaseType.Postgres)
+ builder.UseNpgsql(_ConnectionString);
+ }
+
+ public void ConfigureHangfireBuilder(IGlobalConfiguration builder)
+ {
+ if(_Type == DatabaseType.Sqlite)
+ builder.UseMemoryStorage(); //Sql provider does not support multiple workers
+ else if(_Type == DatabaseType.Postgres)
+ builder.UsePostgreSqlStorage(_ConnectionString);
+ }
}
}
diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs
index 3ed2be04a..2881d58d1 100644
--- a/BTCPayServer/Hosting/BTCPayServerServices.cs
+++ b/BTCPayServer/Hosting/BTCPayServerServices.cs
@@ -92,8 +92,8 @@ namespace BTCPayServer.Hosting
{
services.AddDbContext((provider, o) =>
{
- var path = Path.Combine(provider.GetRequiredService().DataDir, "sqllite.db");
- o.UseSqlite("Data Source=" + path);
+ var factory = provider.GetRequiredService();
+ factory.ConfigureBuilder(o);
});
services.TryAddSingleton();
services.TryAddSingleton();
diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs
index ca4af5872..e8305eb93 100644
--- a/BTCPayServer/Hosting/Startup.cs
+++ b/BTCPayServer/Hosting/Startup.cs
@@ -19,7 +19,6 @@ using Microsoft.AspNetCore.Identity;
using BTCPayServer.Data;
using Microsoft.Extensions.Logging;
using Hangfire;
-using Hangfire.MemoryStorage;
using BTCPayServer.Logging;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
@@ -82,10 +81,9 @@ namespace BTCPayServer.Hosting
Action configuration = o =>
{
var scope = AspNetCoreJobActivator.Current.BeginScope(null);
- var options = (ApplicationDbContext)scope.Resolve(typeof(ApplicationDbContext));
- var path = Path.Combine(((BTCPayServerOptions)scope.Resolve(typeof(BTCPayServerOptions))).DataDir, "hangfire.db");
- o.UseMemoryStorage(); //SQLite provider can work with only one background job :/
- };
+ var options = (ApplicationDbContextFactory)scope.Resolve(typeof(ApplicationDbContextFactory));
+ options.ConfigureHangfireBuilder(o);
+ };
ServiceCollectionDescriptorExtensions.TryAddSingleton>(services, (IServiceProvider serviceProvider) => new Action((config) =>
{
diff --git a/BTCPayServer/Migrations/20170913143004_Init.cs b/BTCPayServer/Migrations/20170913143004_Init.cs
index b82911674..7d58bd4b1 100644
--- a/BTCPayServer/Migrations/20170913143004_Init.cs
+++ b/BTCPayServer/Migrations/20170913143004_Init.cs
@@ -30,16 +30,16 @@ namespace BTCPayServer.Migrations
AccessFailedCount = table.Column(type: "INTEGER", nullable: false),
ConcurrencyStamp = table.Column(type: "TEXT", nullable: true),
Email = table.Column(type: "TEXT", maxLength: 256, nullable: true),
- EmailConfirmed = table.Column(type: "INTEGER", nullable: false),
- LockoutEnabled = table.Column(type: "INTEGER", nullable: false),
- LockoutEnd = table.Column(type: "TEXT", nullable: true),
+ EmailConfirmed = table.Column(nullable: false),
+ LockoutEnabled = table.Column(nullable: false),
+ LockoutEnd = table.Column(nullable: true),
NormalizedEmail = table.Column(type: "TEXT", maxLength: 256, nullable: true),
NormalizedUserName = table.Column(type: "TEXT", maxLength: 256, nullable: true),
PasswordHash = table.Column(type: "TEXT", nullable: true),
PhoneNumber = table.Column(type: "TEXT", nullable: true),
- PhoneNumberConfirmed = table.Column(type: "INTEGER", nullable: false),
+ PhoneNumberConfirmed = table.Column(nullable: false),
SecurityStamp = table.Column(type: "TEXT", nullable: true),
- TwoFactorEnabled = table.Column(type: "INTEGER", nullable: false),
+ TwoFactorEnabled = table.Column(nullable: false),
UserName = table.Column(type: "TEXT", maxLength: 256, nullable: true)
},
constraints: table =>
@@ -54,7 +54,7 @@ namespace BTCPayServer.Migrations
Id = table.Column(type: "TEXT", nullable: false),
DerivationStrategy = table.Column(type: "TEXT", nullable: true),
SpeedPolicy = table.Column(type: "INTEGER", nullable: false),
- StoreCertificate = table.Column(type: "BLOB", nullable: true),
+ StoreCertificate = table.Column(nullable: true),
StoreName = table.Column(type: "TEXT", nullable: true),
StoreWebsite = table.Column(type: "TEXT", nullable: true)
},
@@ -174,8 +174,8 @@ namespace BTCPayServer.Migrations
columns: table => new
{
Id = table.Column(type: "TEXT", nullable: false),
- Blob = table.Column(type: "BLOB", nullable: true),
- Created = table.Column(type: "TEXT", nullable: false),
+ Blob = table.Column(nullable: true),
+ Created = table.Column(nullable: false),
CustomerEmail = table.Column(type: "TEXT", nullable: true),
ExceptionStatus = table.Column(type: "TEXT", nullable: true),
ItemCode = table.Column(type: "TEXT", nullable: true),
@@ -224,7 +224,7 @@ namespace BTCPayServer.Migrations
columns: table => new
{
Id = table.Column(type: "TEXT", nullable: false),
- Blob = table.Column(type: "BLOB", nullable: true),
+ Blob = table.Column(nullable: true),
InvoiceDataId = table.Column(type: "TEXT", nullable: true)
},
constraints: table =>
@@ -243,7 +243,7 @@ namespace BTCPayServer.Migrations
columns: table => new
{
Id = table.Column(type: "TEXT", nullable: false),
- Blob = table.Column(type: "BLOB", nullable: true),
+ Blob = table.Column(nullable: true),
InvoiceDataId = table.Column(type: "TEXT", nullable: true)
},
constraints: table =>
diff --git a/BTCPayServer/Migrations/20170926084408_RequiresEmailConfirmation.cs b/BTCPayServer/Migrations/20170926084408_RequiresEmailConfirmation.cs
index 23592089b..48f2cfe23 100644
--- a/BTCPayServer/Migrations/20170926084408_RequiresEmailConfirmation.cs
+++ b/BTCPayServer/Migrations/20170926084408_RequiresEmailConfirmation.cs
@@ -11,7 +11,6 @@ namespace BTCPayServer.Migrations
migrationBuilder.AddColumn(
name: "RequiresEmailConfirmation",
table: "AspNetUsers",
- type: "INTEGER",
nullable: false,
defaultValue: false);
}