Fix: Migrating from SQLite was crashing in some conditions (Close #4623)

This commit is contained in:
nicolas.dorier 2023-02-15 15:59:45 +09:00
parent 8b80910d70
commit 5121d64022
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
2 changed files with 19 additions and 2 deletions

View file

@ -31,12 +31,12 @@ namespace BTCPayServer.Data
{
_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; }

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@ -213,12 +214,28 @@ namespace BTCPayServer.Hosting
var typeMapping = t.EntityTypeMappings.Single();
var query = (IQueryable<object>)otherContext.GetType().GetMethod("Set", new Type[0])!.MakeGenericMethod(typeMapping.EntityType.ClrType).Invoke(otherContext, null)!;
Logger.LogInformation($"Migrating table: " + t.Name);
List<PropertyInfo> datetimeProperties = new List<PropertyInfo>();
foreach (var col in t.Columns)
if (col.PropertyMappings.Single().Property.ClrType == typeof(DateTime))
{
datetimeProperties.Add(col.PropertyMappings.Single().Property.PropertyInfo!);
}
var rows = await query.ToListAsync();
foreach (var row in rows)
{
// There is as circular deps between invoice and refund.
if (row is InvoiceData id)
id.CurrentRefundId = null;
foreach (var prop in datetimeProperties)
{
var v = (DateTime)prop.GetValue(row)!;
if (v.Kind == DateTimeKind.Unspecified)
{
v = new DateTime(v.Ticks, DateTimeKind.Utc);
prop.SetValue(row, v);
}
}
postgresContext.Entry(row).State = EntityState.Added;
}
await postgresContext.SaveChangesAsync();