Skip to content

Commit

Permalink
Remove MySQL and Sqlite deps
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasDorier committed Apr 15, 2024
1 parent 893b924 commit 032997e
Show file tree
Hide file tree
Showing 86 changed files with 821 additions and 1,732 deletions.
2 changes: 0 additions & 2 deletions BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
<ItemGroup>
<PackageReference Include="HtmlSanitizer" Version="8.0.838" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.0-beta.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
Expand Down
51 changes: 12 additions & 39 deletions BTCPayServer.Abstractions/Contracts/BaseDbContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ namespace BTCPayServer.Abstractions.Contracts
public abstract class BaseDbContextFactory<T> where T : DbContext
{
private readonly IOptions<DatabaseOptions> _options;
private readonly string _schemaPrefix;
private readonly string _migrationTableName;

public BaseDbContextFactory(IOptions<DatabaseOptions> options, string schemaPrefix)
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string migrationTableName)
{
_options = options;
_schemaPrefix = schemaPrefix;
_migrationTableName = migrationTableName;
}

public abstract T CreateContext();
Expand Down Expand Up @@ -68,43 +68,16 @@ protected override void Generate(NpgsqlCreateDatabaseOperation operation, IModel

public void ConfigureBuilder(DbContextOptionsBuilder builder)
{
switch (_options.Value.DatabaseType)
builder
.UseNpgsql(_options.Value.ConnectionString, o =>
{
case DatabaseType.Sqlite:
builder.UseSqlite(_options.Value.ConnectionString, o =>
{
if (!string.IsNullOrEmpty(_schemaPrefix))
{
o.MigrationsHistoryTable(_schemaPrefix);
}
});
break;
case DatabaseType.Postgres:
builder
.UseNpgsql(_options.Value.ConnectionString, o =>
{
o.EnableRetryOnFailure(10);
o.SetPostgresVersion(12, 0);
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
var schemaPrefix = string.IsNullOrEmpty(_schemaPrefix) ? "__EFMigrationsHistory" : _schemaPrefix;
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
})
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
break;
case DatabaseType.MySQL:
builder.UseMySql(_options.Value.ConnectionString, ServerVersion.AutoDetect(_options.Value.ConnectionString), o =>
{
o.EnableRetryOnFailure(10);
if (!string.IsNullOrEmpty(_schemaPrefix))
{
o.MigrationsHistoryTable(_schemaPrefix);
}
});
break;
default:
throw new ArgumentOutOfRangeException();
}
o.EnableRetryOnFailure(10);
o.SetPostgresVersion(12, 0);
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
})
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
}

private string GetSearchPath(string connectionString)
Expand Down
1 change: 0 additions & 1 deletion BTCPayServer.Abstractions/Models/DatabaseOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ namespace BTCPayServer.Abstractions.Models
{
public class DatabaseOptions
{
public DatabaseType DatabaseType { get; set; }
public string ConnectionString { get; set; }
}
}
9 changes: 0 additions & 9 deletions BTCPayServer.Abstractions/Models/DatabaseType.cs

This file was deleted.

49 changes: 4 additions & 45 deletions BTCPayServer.Data/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,18 @@ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<Applicatio
{
public ApplicationDbContext CreateDbContext(string[] args)
{

var builder = new DbContextOptionsBuilder<ApplicationDbContext>();

builder.UseSqlite("Data Source=temp.db");

return new ApplicationDbContext(builder.Options, true);
// Same as launchsettings.json, it's connecting to the docker's postgres.
builder.UseNpgsql("User ID=postgres;Include Error Detail=true;Host=127.0.0.1;Port=39372;Database=btcpayserver");
return new ApplicationDbContext(builder.Options);
}
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly bool _designTime;

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, bool designTime = false)
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
_designTime = designTime;
}
#nullable enable
public async Task<string?> GetMigrationState()
{
return (await Settings.FromSqlRaw("SELECT \"Id\", \"Value\" FROM \"Settings\" WHERE \"Id\"='MigrationData'").AsNoTracking().FirstOrDefaultAsync())?.Value;
}
#nullable restore
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
public DbSet<APIKeyData> ApiKeys { get; set; }
public DbSet<AppData> Apps { get; set; }
Expand Down Expand Up @@ -76,13 +64,6 @@ public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, bool
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
public DbSet<FormData> Forms { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var isConfigured = optionsBuilder.Options.Extensions.OfType<RelationalOptionsExtension>().Any();
if (!isConfigured)
optionsBuilder.UseSqlite("Data Source=temp.db");
}

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
Expand Down Expand Up @@ -129,28 +110,6 @@ protected override void OnModelCreating(ModelBuilder builder)
WebhookData.OnModelCreating(builder, Database);
FormData.OnModelCreating(builder, Database);
StoreRole.OnModelCreating(builder, Database);


if (Database.IsSqlite() && !_designTime)
{
// SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
// here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
// To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
// use the DateTimeOffsetToBinaryConverter
// Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
// This only supports millisecond precision, but should be sufficient for most use cases.
foreach (var entityType in builder.Model.GetEntityTypes())
{
var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset));
foreach (var property in properties)
{
builder
.Entity(entityType.Name)
.Property(property.Name)
.HasConversion(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.DateTimeOffsetToBinaryConverter());
}
}
}
}
}

Expand Down
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/APIKeyData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,9 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<APIKeyData>()
.HasIndex(o => o.StoreId);

if (databaseFacade.IsNpgsql())
{
builder.Entity<APIKeyData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
builder.Entity<APIKeyData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
}

Expand Down
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/AppData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,9 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<AppData>()
.HasOne(a => a.StoreData);

if (databaseFacade.IsNpgsql())
{
builder.Entity<AppData>()
.Property(o => o.Settings)
.HasColumnType("JSONB");
}
builder.Entity<AppData>()
.Property(o => o.Settings)
.HasColumnType("JSONB");
}

// utility methods
Expand Down
10 changes: 4 additions & 6 deletions BTCPayServer.Data/Data/ApplicationUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ public static void OnModelCreating(ModelBuilder builder, DatabaseFacade database
builder.Entity<ApplicationUser>()
.HasMany<IdentityUserRole<string>>(user => user.UserRoles)
.WithOne().HasForeignKey(role => role.UserId);
if (databaseFacade.IsNpgsql())
{
builder.Entity<ApplicationUser>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}

builder.Entity<ApplicationUser>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
}

Expand Down
10 changes: 4 additions & 6 deletions BTCPayServer.Data/Data/Fido2Credential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ public static void OnModelCreating(ModelBuilder builder, DatabaseFacade database
.HasOne(o => o.ApplicationUser)
.WithMany(i => i.Fido2Credentials)
.HasForeignKey(i => i.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql())
{
builder.Entity<Fido2Credential>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}

builder.Entity<Fido2Credential>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}

public ApplicationUser ApplicationUser { get; set; }
Expand Down
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/FormData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
.WithMany(o => o.Forms).OnDelete(DeleteBehavior.Cascade);
builder.Entity<FormData>().HasIndex(o => o.StoreId);

if (databaseFacade.IsNpgsql())
{
builder.Entity<FormData>()
.Property(o => o.Config)
.HasColumnType("JSONB");
}
builder.Entity<FormData>()
.Property(o => o.Config)
.HasColumnType("JSONB");
}
}
15 changes: 6 additions & 9 deletions BTCPayServer.Data/Data/InvoiceData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,12 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
builder.Entity<InvoiceData>().HasIndex(o => o.OrderId);
builder.Entity<InvoiceData>().HasIndex(o => o.Created);
if (databaseFacade.IsNpgsql())
{
builder.Entity<InvoiceData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
builder.Entity<InvoiceData>()
.Property(o => o.Amount)
.HasColumnType("NUMERIC");
}
builder.Entity<InvoiceData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
builder.Entity<InvoiceData>()
.Property(o => o.Amount)
.HasColumnType("NUMERIC");
}
}
}
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/LightingAddressData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<LightningAddressData>().HasKey(o => o.Username);
if (databaseFacade.IsNpgsql())
{
builder.Entity<LightningAddressData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
builder.Entity<LightningAddressData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
}

Expand Down
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/NotificationData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,9 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
.HasOne(o => o.ApplicationUser)
.WithMany(n => n.Notifications)
.HasForeignKey(k => k.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql())
{
builder.Entity<NotificationData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
builder.Entity<NotificationData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
}
}
15 changes: 6 additions & 9 deletions BTCPayServer.Data/Data/PaymentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,12 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<PaymentData>()
.Property(o => o.Status)
.HasConversion<string>();
if (databaseFacade.IsNpgsql())
{
builder.Entity<PaymentData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
builder.Entity<PaymentData>()
.Property(o => o.Amount)
.HasColumnType("NUMERIC");
}
builder.Entity<PaymentData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
builder.Entity<PaymentData>()
.Property(o => o.Amount)
.HasColumnType("NUMERIC");
}
}
}
9 changes: 3 additions & 6 deletions BTCPayServer.Data/Data/PaymentRequestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<PaymentRequestData>()
.HasIndex(o => o.Status);

if (databaseFacade.IsNpgsql())
{
builder.Entity<PaymentRequestData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
builder.Entity<PaymentRequestData>()
.Property(o => o.Blob2)
.HasColumnType("JSONB");
}
}
}
32 changes: 6 additions & 26 deletions BTCPayServer.Data/Data/PayoutData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,12 @@ internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databa
builder.Entity<PayoutData>()
.HasIndex(x => new { DestinationId = x.Destination, x.State });

if (databaseFacade.IsNpgsql())
{
builder.Entity<PayoutData>()
.Property(o => o.Blob)
.HasColumnType("JSONB");
builder.Entity<PayoutData>()
.Property(o => o.Proof)
.HasColumnType("JSONB");
}
else if (databaseFacade.IsMySql())
{
builder.Entity<PayoutData>()
.Property(o => o.Blob)
.HasConversion(new ValueConverter<string, byte[]>
(
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
));
builder.Entity<PayoutData>()
.Property(o => o.Proof)
.HasConversion(new ValueConverter<string, byte[]>
(
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
));
}
builder.Entity<PayoutData>()
.Property(o => o.Blob)
.HasColumnType("JSONB");
builder.Entity<PayoutData>()
.Property(o => o.Proof)
.HasColumnType("JSONB");
}

// utility methods
Expand Down
Loading

0 comments on commit 032997e

Please sign in to comment.