diff --git a/BTCPayServer.Data/ApplicationDbContext.cs b/BTCPayServer.Data/ApplicationDbContext.cs index 128d9b04f..b11d9c789 100644 --- a/BTCPayServer.Data/ApplicationDbContext.cs +++ b/BTCPayServer.Data/ApplicationDbContext.cs @@ -105,10 +105,10 @@ namespace BTCPayServer.Data //PlannedTransaction.OnModelCreating(builder); PullPaymentData.OnModelCreating(builder); RefundData.OnModelCreating(builder); - //SettingData.OnModelCreating(builder); + SettingData.OnModelCreating(builder, Database); StoreSettingData.OnModelCreating(builder, Database); StoreWebhookData.OnModelCreating(builder); - //StoreData.OnModelCreating(builder); + StoreData.OnModelCreating(builder, Database); U2FDevice.OnModelCreating(builder); Fido2Credential.OnModelCreating(builder); BTCPayServer.Data.UserStore.OnModelCreating(builder); diff --git a/BTCPayServer.Data/Data/SettingData.cs b/BTCPayServer.Data/Data/SettingData.cs index a6407721f..fefec2f65 100644 --- a/BTCPayServer.Data/Data/SettingData.cs +++ b/BTCPayServer.Data/Data/SettingData.cs @@ -1,3 +1,6 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; + namespace BTCPayServer.Data { public class SettingData @@ -5,5 +8,15 @@ namespace BTCPayServer.Data public string Id { get; set; } public string Value { get; set; } + + public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) + { + if (databaseFacade.IsNpgsql()) + { + builder.Entity() + .Property(o => o.Value) + .HasColumnType("JSONB"); + } + } } } diff --git a/BTCPayServer.Data/Data/StoreData.cs b/BTCPayServer.Data/Data/StoreData.cs index ef910d99f..9903f3564 100644 --- a/BTCPayServer.Data/Data/StoreData.cs +++ b/BTCPayServer.Data/Data/StoreData.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using BTCPayServer.Client.Models; using BTCPayServer.Data.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using PayoutProcessorData = BTCPayServer.Data.Data.PayoutProcessorData; namespace BTCPayServer.Data @@ -36,7 +38,7 @@ namespace BTCPayServer.Data [NotMapped] public string Role { get; set; } - public byte[] StoreBlob { get; set; } + public string StoreBlob { get; set; } [Obsolete("Use GetDefaultPaymentId instead")] public string DefaultCrypto { get; set; } @@ -48,5 +50,15 @@ namespace BTCPayServer.Data public IEnumerable Payouts { get; set; } public IEnumerable CustodianAccounts { get; set; } public IEnumerable Settings { get; set; } + + internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) + { + if (databaseFacade.IsNpgsql()) + { + builder.Entity() + .Property(o => o.StoreBlob) + .HasColumnType("JSONB"); + } + } } } diff --git a/BTCPayServer.Data/Migrations/20221128062447_jsonb.cs b/BTCPayServer.Data/Migrations/20221128062447_jsonb.cs new file mode 100644 index 000000000..1ad733a49 --- /dev/null +++ b/BTCPayServer.Data/Migrations/20221128062447_jsonb.cs @@ -0,0 +1,31 @@ +using System; +using BTCPayServer.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BTCPayServer.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20221128062447_jsonb")] + public partial class jsonb : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder.IsNpgsql()) + { + migrationBuilder.Sql("ALTER TABLE \"Settings\" ALTER COLUMN \"Value\" TYPE JSONB USING \"Value\"::JSONB"); + migrationBuilder.Sql("ALTER TABLE \"Stores\" ALTER COLUMN \"StoreBlob\" TYPE JSONB USING regexp_replace(convert_from(\"StoreBlob\",'UTF8'), '\\u0000', '', 'g')::JSONB"); + } + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + // Not supported + } + } +} diff --git a/BTCPayServer.Tests/FastTests.cs b/BTCPayServer.Tests/FastTests.cs index 91dc08538..3452cc065 100644 --- a/BTCPayServer.Tests/FastTests.cs +++ b/BTCPayServer.Tests/FastTests.cs @@ -1749,8 +1749,7 @@ namespace BTCPayServer.Tests PaymentMethod = new PaymentMethodId("BTC", PaymentTypes.BTCLike) } }; - var newBlob = Encoding.UTF8.GetBytes( - new Serializer(null).ToString(blob).Replace( "paymentMethod\":\"BTC\"","paymentMethod\":\"ETH_ZYC\"")); + var newBlob = new Serializer(null).ToString(blob).Replace( "paymentMethod\":\"BTC\"","paymentMethod\":\"ETH_ZYC\""); Assert.Empty(StoreDataExtensions.GetStoreBlob(new StoreData() {StoreBlob = newBlob}).PaymentMethodCriteria); } } diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs index 0ebdeae0e..cc0b0b6cf 100644 --- a/BTCPayServer/Configuration/BTCPayServerOptions.cs +++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs @@ -65,6 +65,10 @@ namespace BTCPayServer.Configuration if (conf.GetOrDefault("launchsettings", false) && NetworkType != ChainName.Regtest) throw new ConfigException($"You need to run BTCPayServer with the run.sh or run.ps1 script"); + if (conf.GetOrDefault("SQLITEFILE", null) != null) + Logs.Configuration.LogWarning("SQLITE backend support is deprecated and will be soon out of support"); + if (conf.GetOrDefault("MYSQL", null) != null) + Logs.Configuration.LogWarning("MYSQL backend support is deprecated and will be soon out of support"); DockerDeployment = conf.GetOrDefault("dockerdeployment", true); TorrcFile = conf.GetOrDefault("torrcfile", null); TorServices = conf.GetOrDefault("torservices", null) diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index c9bae9170..c79b3ec95 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -27,9 +27,9 @@ namespace BTCPayServer.Configuration app.Option("--signet | -signet", $"Use signet (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", CommandOptionType.SingleValue); - app.Option("--mysql", $"Connection string to a MySQL database", CommandOptionType.SingleValue); + app.Option("--mysql", $"DEPRECATED: Connection string to a MySQL database", CommandOptionType.SingleValue); app.Option("--nocsp", $"Disable CSP (default false)", CommandOptionType.BoolValue); - app.Option("--sqlitefile", $"File name to an SQLite database file inside the data directory", CommandOptionType.SingleValue); + app.Option("--sqlitefile", $"DEPRECATED: File name to an SQLite database file inside the data directory", CommandOptionType.SingleValue); app.Option("--externalservices", $"Links added to external services inside Server Settings / Services under the format service1:path2;service2:path2.(default: empty)", CommandOptionType.SingleValue); app.Option("--rootpath", "The root path in the URL to access BTCPay (default: /)", CommandOptionType.SingleValue); app.Option("--sshconnection", "SSH server to manage BTCPay under the form user@server:port (default: root@externalhost or empty)", CommandOptionType.SingleValue); diff --git a/BTCPayServer/Data/StoreDataExtensions.cs b/BTCPayServer/Data/StoreDataExtensions.cs index 137ee15ed..96276af3c 100644 --- a/BTCPayServer/Data/StoreDataExtensions.cs +++ b/BTCPayServer/Data/StoreDataExtensions.cs @@ -47,7 +47,7 @@ namespace BTCPayServer.Data public static StoreBlob GetStoreBlob(this StoreData storeData) { - var result = storeData.StoreBlob == null ? new StoreBlob() : new Serializer(null).ToObject(Encoding.UTF8.GetString(storeData.StoreBlob)); + var result = storeData.StoreBlob == null ? new StoreBlob() : new Serializer(null).ToObject(storeData.StoreBlob); if (result.PreferredExchange == null) result.PreferredExchange = CoinGeckoRateProvider.CoinGeckoName; if (result.PaymentMethodCriteria is null) @@ -62,7 +62,7 @@ namespace BTCPayServer.Data var newBlob = new Serializer(null).ToString(storeBlob); if (original == newBlob) return false; - storeData.StoreBlob = Encoding.UTF8.GetBytes(newBlob); + storeData.StoreBlob = newBlob; return true; }