2019-08-29 17:24:42 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
2017-09-13 08:47:34 +02:00
|
|
|
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2017-09-27 15:09:59 +02:00
|
|
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
2019-05-24 08:17:02 +02:00
|
|
|
|
using OpenIddict.EntityFrameworkCore.Models;
|
2017-09-13 08:47:34 +02:00
|
|
|
|
|
|
|
|
|
namespace BTCPayServer.Data
|
|
|
|
|
{
|
2017-10-27 10:53:04 +02:00
|
|
|
|
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
|
|
|
|
{
|
2019-12-15 13:58:16 +01:00
|
|
|
|
//public ApplicationDbContext(): base(CreateMySql())
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//private static DbContextOptions CreateMySql()
|
|
|
|
|
//{
|
|
|
|
|
// return new DbContextOptionsBuilder<ApplicationDbContext>()
|
|
|
|
|
// .UseMySql("Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;")
|
|
|
|
|
// .Options;
|
|
|
|
|
//}
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
public ApplicationDbContext()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
2019-12-15 13:58:16 +01:00
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
|
|
|
|
: base(options)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<InvoiceData> Invoices
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-03 04:50:41 +02:00
|
|
|
|
public DbSet<AppData> Apps
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-14 13:48:23 +01:00
|
|
|
|
public DbSet<InvoiceEventData> InvoiceEvents
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<PendingInvoiceData> PendingInvoices
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
public DbSet<RefundAddressesData> RefundAddresses
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<PaymentData> Payments
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
2019-01-14 22:43:29 +01:00
|
|
|
|
|
|
|
|
|
public DbSet<PaymentRequestData> PaymentRequests
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
2017-10-27 10:53:04 +02:00
|
|
|
|
|
2019-08-02 17:42:30 +02:00
|
|
|
|
public DbSet<WalletData> Wallets { get; set; }
|
|
|
|
|
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
public DbSet<StoreData> Stores
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<UserStore> UserStore
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<AddressInvoiceData> AddressInvoices
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<SettingData> Settings
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DbSet<PairingCodeData> PairingCodes
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<PairedSINData> PairedSINData
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-29 11:28:04 +02:00
|
|
|
|
public DbSet<APIKeyData> ApiKeys
|
2019-04-22 09:41:20 +02:00
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DbSet<StoredFile> Files
|
2018-04-29 11:28:04 +02:00
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
2019-05-02 14:01:08 +02:00
|
|
|
|
|
2018-04-29 11:28:04 +02:00
|
|
|
|
|
2019-05-02 14:01:08 +02:00
|
|
|
|
public DbSet<U2FDevice> U2FDevices { get; set; }
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
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);
|
|
|
|
|
builder.Entity<InvoiceData>()
|
2018-07-19 12:31:17 +02:00
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(a => a.Invoices).OnDelete(DeleteBehavior.Cascade);
|
|
|
|
|
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
|
|
|
|
|
builder.Entity<PaymentData>()
|
2018-07-19 12:31:17 +02:00
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
|
|
|
|
|
builder.Entity<PaymentData>()
|
|
|
|
|
.HasIndex(o => o.InvoiceDataId);
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<RefundAddressesData>()
|
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(i => i.RefundAddresses).OnDelete(DeleteBehavior.Cascade);
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<RefundAddressesData>()
|
|
|
|
|
.HasIndex(o => o.InvoiceDataId);
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<UserStore>()
|
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(i => i.UserStores).OnDelete(DeleteBehavior.Cascade);
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<UserStore>()
|
|
|
|
|
.HasKey(t => new
|
|
|
|
|
{
|
|
|
|
|
t.ApplicationUserId,
|
|
|
|
|
t.StoreDataId
|
|
|
|
|
});
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<APIKeyData>()
|
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(i => i.APIKeys)
|
|
|
|
|
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
2018-04-29 11:28:04 +02:00
|
|
|
|
builder.Entity<APIKeyData>()
|
|
|
|
|
.HasIndex(o => o.StoreId);
|
2018-04-03 04:50:41 +02:00
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<AppData>()
|
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(i => i.Apps).OnDelete(DeleteBehavior.Cascade);
|
2018-04-03 04:50:41 +02:00
|
|
|
|
builder.Entity<AppData>()
|
|
|
|
|
.HasOne(a => a.StoreData);
|
|
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<UserStore>()
|
|
|
|
|
.HasOne(pt => pt.ApplicationUser)
|
|
|
|
|
.WithMany(p => p.UserStores)
|
|
|
|
|
.HasForeignKey(pt => pt.ApplicationUserId);
|
|
|
|
|
|
|
|
|
|
builder.Entity<UserStore>()
|
|
|
|
|
.HasOne(pt => pt.StoreData)
|
|
|
|
|
.WithMany(t => t.UserStores)
|
|
|
|
|
.HasForeignKey(pt => pt.StoreDataId);
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
|
|
|
|
|
builder.Entity<AddressInvoiceData>()
|
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(i => i.AddressInvoices).OnDelete(DeleteBehavior.Cascade);
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<AddressInvoiceData>()
|
2018-01-08 17:56:37 +01:00
|
|
|
|
#pragma warning disable CS0618
|
2017-10-27 10:53:04 +02:00
|
|
|
|
.HasKey(o => o.Address);
|
2018-01-08 17:56:37 +01:00
|
|
|
|
#pragma warning restore CS0618
|
2017-10-27 10:53:04 +02:00
|
|
|
|
|
|
|
|
|
builder.Entity<PairingCodeData>()
|
|
|
|
|
.HasKey(o => o.Id);
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<PendingInvoiceData>()
|
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(o => o.PendingInvoices)
|
|
|
|
|
.HasForeignKey(o => o.Id).OnDelete(DeleteBehavior.Cascade);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
builder.Entity<PairedSINData>()
|
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(i => i.PairedSINs).OnDelete(DeleteBehavior.Cascade);
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<PairedSINData>(b =>
|
|
|
|
|
{
|
|
|
|
|
b.HasIndex(o => o.SIN);
|
|
|
|
|
b.HasIndex(o => o.StoreDataId);
|
|
|
|
|
});
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
builder.Entity<HistoricalAddressInvoiceData>()
|
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
|
2017-10-27 10:53:04 +02:00
|
|
|
|
builder.Entity<HistoricalAddressInvoiceData>()
|
|
|
|
|
.HasKey(o => new
|
|
|
|
|
{
|
|
|
|
|
o.InvoiceDataId,
|
2018-01-08 17:56:37 +01:00
|
|
|
|
#pragma warning disable CS0618
|
2017-10-27 10:53:04 +02:00
|
|
|
|
o.Address
|
2018-01-14 13:48:23 +01:00
|
|
|
|
#pragma warning restore CS0618
|
|
|
|
|
});
|
|
|
|
|
|
2018-07-19 12:31:17 +02:00
|
|
|
|
|
|
|
|
|
builder.Entity<InvoiceEventData>()
|
|
|
|
|
.HasOne(o => o.InvoiceData)
|
|
|
|
|
.WithMany(i => i.Events).OnDelete(DeleteBehavior.Cascade);
|
2018-01-14 13:48:23 +01:00
|
|
|
|
builder.Entity<InvoiceEventData>()
|
|
|
|
|
.HasKey(o => new
|
|
|
|
|
{
|
|
|
|
|
o.InvoiceDataId,
|
|
|
|
|
#pragma warning disable CS0618
|
|
|
|
|
o.UniqueId
|
2018-01-08 17:56:37 +01:00
|
|
|
|
#pragma warning restore CS0618
|
2017-10-27 10:53:04 +02:00
|
|
|
|
});
|
2019-01-14 22:43:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
builder.Entity<PaymentRequestData>()
|
|
|
|
|
.HasOne(o => o.StoreData)
|
|
|
|
|
.WithMany(i => i.PaymentRequests)
|
|
|
|
|
.OnDelete(DeleteBehavior.Cascade);
|
2019-07-01 10:22:54 +02:00
|
|
|
|
builder.Entity<PaymentRequestData>()
|
|
|
|
|
.Property(e => e.Created)
|
2019-08-29 17:24:42 +02:00
|
|
|
|
.HasDefaultValue(new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
2019-01-14 22:43:29 +01:00
|
|
|
|
|
|
|
|
|
builder.Entity<PaymentRequestData>()
|
|
|
|
|
.HasIndex(o => o.Status);
|
2019-05-24 08:17:02 +02:00
|
|
|
|
|
2019-08-02 17:42:30 +02:00
|
|
|
|
builder.Entity<WalletTransactionData>()
|
|
|
|
|
.HasKey(o => new
|
|
|
|
|
{
|
|
|
|
|
o.WalletDataId,
|
|
|
|
|
#pragma warning disable CS0618
|
|
|
|
|
o.TransactionId
|
|
|
|
|
#pragma warning restore CS0618
|
|
|
|
|
});
|
|
|
|
|
builder.Entity<WalletTransactionData>()
|
|
|
|
|
.HasOne(o => o.WalletData)
|
|
|
|
|
.WithMany(w => w.WalletTransactions).OnDelete(DeleteBehavior.Cascade);
|
|
|
|
|
|
2019-05-24 08:17:02 +02:00
|
|
|
|
builder.UseOpenIddict<BTCPayOpenIdClient, BTCPayOpenIdAuthorization, OpenIddictScope<string>, BTCPayOpenIdToken, string>();
|
|
|
|
|
|
2020-01-17 13:45:20 +01:00
|
|
|
|
if (Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite")
|
|
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-27 10:53:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-02 14:01:08 +02:00
|
|
|
|
|
2017-09-13 08:47:34 +02:00
|
|
|
|
}
|