mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-10 17:26:05 +01:00
Better handle postgres requests for wallet objects (#4985)
This commit is contained in:
parent
c3f412e3bb
commit
9b721fae27
1 changed files with 61 additions and 34 deletions
|
@ -7,10 +7,12 @@ using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
|
using Dapper;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
namespace BTCPayServer.Services
|
namespace BTCPayServer.Services
|
||||||
{
|
{
|
||||||
|
@ -365,6 +367,11 @@ namespace BTCPayServer.Services
|
||||||
{
|
{
|
||||||
SortWalletObjectLinks(ref a, ref b);
|
SortWalletObjectLinks(ref a, ref b);
|
||||||
await using var ctx = _ContextFactory.CreateContext();
|
await using var ctx = _ContextFactory.CreateContext();
|
||||||
|
await UpdateWalletObjectLink(a, b, data, ctx, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task UpdateWalletObjectLink(WalletObjectId a, WalletObjectId b, JObject? data, ApplicationDbContext ctx, bool doNothingIfExists)
|
||||||
|
{
|
||||||
var l = new WalletObjectLinkData()
|
var l = new WalletObjectLinkData()
|
||||||
{
|
{
|
||||||
WalletId = a.WalletId.ToString(),
|
WalletId = a.WalletId.ToString(),
|
||||||
|
@ -374,13 +381,34 @@ namespace BTCPayServer.Services
|
||||||
BId = b.Id,
|
BId = b.Id,
|
||||||
Data = data?.ToString(Formatting.None)
|
Data = data?.ToString(Formatting.None)
|
||||||
};
|
};
|
||||||
ctx.WalletObjectLinks.Add(l);
|
if (!ctx.Database.IsNpgsql())
|
||||||
|
{
|
||||||
|
var e = ctx.WalletObjectLinks.Add(l);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
catch (DbUpdateException) // already exists
|
catch (DbUpdateException) // already exists
|
||||||
{
|
{
|
||||||
|
if (!doNothingIfExists)
|
||||||
|
{
|
||||||
|
e.State = EntityState.Modified;
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var connection = ctx.Database.GetDbConnection();
|
||||||
|
var conflict = doNothingIfExists ? "ON CONFLICT DO NOTHING" : "ON CONFLICT ON CONSTRAINT \"PK_WalletObjectLinks\" DO UPDATE SET \"Data\"=EXCLUDED.\"Data\"";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await connection.ExecuteAsync("INSERT INTO \"WalletObjectLinks\" VALUES (@WalletId, @AType, @AId, @BType, @BId, @Data::JSONB) " + conflict, l);
|
||||||
|
}
|
||||||
|
catch (PostgresException ex) when (ex.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
||||||
|
{
|
||||||
|
throw new DbUpdateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,25 +439,7 @@ namespace BTCPayServer.Services
|
||||||
|
|
||||||
|
|
||||||
await using var ctx = _ContextFactory.CreateContext();
|
await using var ctx = _ContextFactory.CreateContext();
|
||||||
var l = new WalletObjectLinkData()
|
await UpdateWalletObjectLink(a, b, data, ctx, false);
|
||||||
{
|
|
||||||
WalletId = a.WalletId.ToString(),
|
|
||||||
AType = a.Type,
|
|
||||||
AId = a.Id,
|
|
||||||
BType = b.Type,
|
|
||||||
BId = b.Id,
|
|
||||||
Data = data?.ToString(Formatting.None)
|
|
||||||
};
|
|
||||||
var e = ctx.WalletObjectLinks.Add(l);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
catch (DbUpdateException) // already exists
|
|
||||||
{
|
|
||||||
e.State = EntityState.Modified;
|
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int MaxCommentSize = 200;
|
public static int MaxCommentSize = 200;
|
||||||
|
@ -558,24 +568,35 @@ namespace BTCPayServer.Services
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(id);
|
ArgumentNullException.ThrowIfNull(id);
|
||||||
await using var ctx = _ContextFactory.CreateContext();
|
await using var ctx = _ContextFactory.CreateContext();
|
||||||
var o = NewWalletObjectData(id, data);
|
var wo = NewWalletObjectData(id, data);
|
||||||
ctx.WalletObjects.Add(o);
|
if (!ctx.Database.IsNpgsql())
|
||||||
|
{
|
||||||
|
ctx.WalletObjects.Add(wo);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
catch (DbUpdateException) // already exists
|
catch (DbUpdateException) // already exists
|
||||||
{
|
{
|
||||||
ctx.Entry(o).State = EntityState.Modified;
|
ctx.Entry(wo).State = EntityState.Modified;
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var connection = ctx.Database.GetDbConnection();
|
||||||
|
await connection.ExecuteAsync("INSERT INTO \"WalletObjects\" VALUES (@WalletId, @Type, @Id, @Data::JSONB) ON CONFLICT ON CONSTRAINT \"PK_WalletObjects\" DO UPDATE SET \"Data\"=EXCLUDED.\"Data\"", wo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task EnsureWalletObject(WalletObjectId id, JObject? data = null)
|
public async Task EnsureWalletObject(WalletObjectId id, JObject? data = null)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(id);
|
ArgumentNullException.ThrowIfNull(id);
|
||||||
|
var wo = NewWalletObjectData(id, data);
|
||||||
await using var ctx = _ContextFactory.CreateContext();
|
await using var ctx = _ContextFactory.CreateContext();
|
||||||
ctx.WalletObjects.Add(NewWalletObjectData(id, data));
|
if (!ctx.Database.IsNpgsql())
|
||||||
|
{
|
||||||
|
ctx.WalletObjects.Add(wo);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
@ -584,6 +605,12 @@ namespace BTCPayServer.Services
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var connection = ctx.Database.GetDbConnection();
|
||||||
|
await connection.ExecuteAsync("INSERT INTO \"WalletObjects\" VALUES (@WalletId, @Type, @Id, @Data::JSONB) ON CONFLICT DO NOTHING", wo);
|
||||||
|
}
|
||||||
|
}
|
||||||
#nullable restore
|
#nullable restore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue