Rename walletobjects Parent/Child to A/B (#4347)

This commit is contained in:
Nicolas Dorier 2022-11-25 12:06:57 +09:00 committed by GitHub
parent 2f5f3e1b51
commit 39328c7368
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 97 deletions

View file

@ -27,36 +27,36 @@ namespace BTCPayServer.Data
public string Id { get; set; } public string Id { get; set; }
public string Data { get; set; } public string Data { get; set; }
public List<WalletObjectLinkData> ChildLinks { get; set; } public List<WalletObjectLinkData> Bs { get; set; }
public List<WalletObjectLinkData> ParentLinks { get; set; } public List<WalletObjectLinkData> As { get; set; }
public IEnumerable<(string type, string id, string linkdata, string objectdata)> GetLinks() public IEnumerable<(string type, string id, string linkdata, string objectdata)> GetLinks()
{ {
if (ChildLinks is not null) if (Bs is not null)
foreach (var c in ChildLinks) foreach (var c in Bs)
{ {
yield return (c.ChildType, c.ChildId, c.Data, c.Child?.Data); yield return (c.BType, c.BId, c.Data, c.B?.Data);
} }
if (ParentLinks is not null) if (As is not null)
foreach (var c in ParentLinks) foreach (var c in As)
{ {
yield return (c.ParentType, c.ParentId, c.Data, c.Parent?.Data); yield return (c.AType, c.AId, c.Data, c.A?.Data);
} }
} }
public IEnumerable<WalletObjectData> GetNeighbours() public IEnumerable<WalletObjectData> GetNeighbours()
{ {
if (ChildLinks != null) if (Bs != null)
foreach (var c in ChildLinks) foreach (var c in Bs)
{ {
if (c.Child != null) if (c.B != null)
yield return c.Child; yield return c.B;
} }
if (ParentLinks != null) if (As != null)
foreach (var c in ParentLinks) foreach (var c in As)
{ {
if (c.Parent != null) if (c.A != null)
yield return c.Parent; yield return c.A;
} }
} }

View file

@ -11,14 +11,14 @@ namespace BTCPayServer.Data
public class WalletObjectLinkData public class WalletObjectLinkData
{ {
public string WalletId { get; set; } public string WalletId { get; set; }
public string ParentType { get; set; } public string AType { get; set; }
public string ParentId { get; set; } public string AId { get; set; }
public string ChildType { get; set; } public string BType { get; set; }
public string ChildId { get; set; } public string BId { get; set; }
public string Data { get; set; } public string Data { get; set; }
public WalletObjectData Parent { get; set; } public WalletObjectData A { get; set; }
public WalletObjectData Child { get; set; } public WalletObjectData B { get; set; }
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
{ {
@ -26,28 +26,28 @@ namespace BTCPayServer.Data
new new
{ {
o.WalletId, o.WalletId,
o.ParentType, o.AType,
o.ParentId, o.AId,
o.ChildType, o.BType,
o.ChildId, o.BId,
}); });
builder.Entity<WalletObjectLinkData>().HasIndex(o => new builder.Entity<WalletObjectLinkData>().HasIndex(o => new
{ {
o.WalletId, o.WalletId,
o.ChildType, o.BType,
o.ChildId, o.BId,
}); });
builder.Entity<WalletObjectLinkData>() builder.Entity<WalletObjectLinkData>()
.HasOne(o => o.Parent) .HasOne(o => o.A)
.WithMany(o => o.ChildLinks) .WithMany(o => o.Bs)
.HasForeignKey(o => new { o.WalletId, o.ParentType, o.ParentId }) .HasForeignKey(o => new { o.WalletId, o.AType, o.AId })
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
builder.Entity<WalletObjectLinkData>() builder.Entity<WalletObjectLinkData>()
.HasOne(o => o.Child) .HasOne(o => o.B)
.WithMany(o => o.ParentLinks) .WithMany(o => o.As)
.HasForeignKey(o => new { o.WalletId, o.ChildType, o.ChildId }) .HasForeignKey(o => new { o.WalletId, o.BType, o.BId })
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql()) if (databaseFacade.IsNpgsql())

View file

@ -40,33 +40,33 @@ namespace BTCPayServer.Migrations
columns: table => new columns: table => new
{ {
WalletId = table.Column<string>(type: "TEXT", nullable: false), WalletId = table.Column<string>(type: "TEXT", nullable: false),
ParentType = table.Column<string>(type: "TEXT", nullable: false), AType = table.Column<string>(type: "TEXT", nullable: false),
ParentId = table.Column<string>(type: "TEXT", nullable: false), AId = table.Column<string>(type: "TEXT", nullable: false),
ChildType = table.Column<string>(type: "TEXT", nullable: false), BType = table.Column<string>(type: "TEXT", nullable: false),
ChildId = table.Column<string>(type: "TEXT", nullable: false), BId = table.Column<string>(type: "TEXT", nullable: false),
Data = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true) Data = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_WalletObjectLinks", x => new { x.WalletId, x.ParentType, x.ParentId, x.ChildType, x.ChildId }); table.PrimaryKey("PK_WalletObjectLinks", x => new { x.WalletId, x.AType, x.AId, x.BType, x.BId });
table.ForeignKey( table.ForeignKey(
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ChildType_ChildId", name: "FK_WalletObjectLinks_WalletObjects_WalletId_BType_BId",
columns: x => new { x.WalletId, x.ChildType, x.ChildId }, columns: x => new { x.WalletId, x.BType, x.BId },
principalTable: "WalletObjects", principalTable: "WalletObjects",
principalColumns: new[] { "WalletId", "Type", "Id" }, principalColumns: new[] { "WalletId", "Type", "Id" },
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ParentType_ParentId", name: "FK_WalletObjectLinks_WalletObjects_WalletId_AType_AId",
columns: x => new { x.WalletId, x.ParentType, x.ParentId }, columns: x => new { x.WalletId, x.AType, x.AId },
principalTable: "WalletObjects", principalTable: "WalletObjects",
principalColumns: new[] { "WalletId", "Type", "Id" }, principalColumns: new[] { "WalletId", "Type", "Id" },
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_WalletObjectLinks_WalletId_ChildType_ChildId", name: "IX_WalletObjectLinks_WalletId_BType_BId",
table: "WalletObjectLinks", table: "WalletObjectLinks",
columns: new[] { "WalletId", "ChildType", "ChildId" }); columns: new[] { "WalletId", "BType", "BId" });
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)

View file

@ -872,24 +872,24 @@ namespace BTCPayServer.Migrations
b.Property<string>("WalletId") b.Property<string>("WalletId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("ParentType") b.Property<string>("AType")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("ParentId") b.Property<string>("AId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("ChildType") b.Property<string>("BType")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("ChildId") b.Property<string>("BId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Data") b.Property<string>("Data")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.HasKey("WalletId", "ParentType", "ParentId", "ChildType", "ChildId"); b.HasKey("WalletId", "AType", "AId", "BType", "BId");
b.HasIndex("WalletId", "ChildType", "ChildId"); b.HasIndex("WalletId", "BType", "BId");
b.ToTable("WalletObjectLinks"); b.ToTable("WalletObjectLinks");
}); });
@ -1384,21 +1384,21 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.WalletObjectLinkData", b => modelBuilder.Entity("BTCPayServer.Data.WalletObjectLinkData", b =>
{ {
b.HasOne("BTCPayServer.Data.WalletObjectData", "Child") b.HasOne("BTCPayServer.Data.WalletObjectData", "A")
.WithMany("ParentLinks") .WithMany("Bs")
.HasForeignKey("WalletId", "ChildType", "ChildId") .HasForeignKey("WalletId", "AType", "AId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("BTCPayServer.Data.WalletObjectData", "Parent") b.HasOne("BTCPayServer.Data.WalletObjectData", "B")
.WithMany("ChildLinks") .WithMany("As")
.HasForeignKey("WalletId", "ParentType", "ParentId") .HasForeignKey("WalletId", "BType", "BId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("Child"); b.Navigation("A");
b.Navigation("Parent"); b.Navigation("B");
}); });
modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b => modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b =>
@ -1545,9 +1545,9 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.WalletObjectData", b => modelBuilder.Entity("BTCPayServer.Data.WalletObjectData", b =>
{ {
b.Navigation("ChildLinks"); b.Navigation("As");
b.Navigation("ParentLinks"); b.Navigation("Bs");
}); });
modelBuilder.Entity("BTCPayServer.Data.WebhookData", b => modelBuilder.Entity("BTCPayServer.Data.WebhookData", b =>

View file

@ -173,10 +173,10 @@ next:
db.WalletObjectLinks.Add(new WalletObjectLinkData() db.WalletObjectLinks.Add(new WalletObjectLinkData()
{ {
WalletId = tx.WalletDataId, WalletId = tx.WalletDataId,
ChildType = Data.WalletObjectData.Types.Tx, BType = Data.WalletObjectData.Types.Tx,
ChildId = tx.TransactionId, BId = tx.TransactionId,
ParentType = Data.WalletObjectData.Types.Label, AType = Data.WalletObjectData.Types.Label,
ParentId = labelId AId = labelId
}); });
if (label.Value is ReferenceLabel reflabel) if (label.Value is ReferenceLabel reflabel)
@ -195,10 +195,10 @@ next:
db.WalletObjectLinks.Add(new WalletObjectLinkData() db.WalletObjectLinks.Add(new WalletObjectLinkData()
{ {
WalletId = tx.WalletDataId, WalletId = tx.WalletDataId,
ChildType = Data.WalletObjectData.Types.Tx, BType = Data.WalletObjectData.Types.Tx,
ChildId = tx.TransactionId, BId = tx.TransactionId,
ParentType = reflabel.Type, AType = reflabel.Type,
ParentId = reflabel.Reference ?? String.Empty AId = reflabel.Reference ?? String.Empty
}); });
} }
} }
@ -224,10 +224,10 @@ next:
db.WalletObjectLinks.Add(new WalletObjectLinkData() db.WalletObjectLinks.Add(new WalletObjectLinkData()
{ {
WalletId = tx.WalletDataId, WalletId = tx.WalletDataId,
ChildType = Data.WalletObjectData.Types.Tx, BType = Data.WalletObjectData.Types.Tx,
ChildId = tx.TransactionId, BId = tx.TransactionId,
ParentType = "payout", AType = "payout",
ParentId = payout AId = payout
}); });
} }
} }

View file

@ -78,7 +78,7 @@ namespace BTCPayServer.Services
using var ctx = _ContextFactory.CreateContext(); using var ctx = _ContextFactory.CreateContext();
// If we are using postgres, the `transactionIds.Contains(w.ChildId)` result in a long query like `ANY(@txId1, @txId2, @txId3, @txId4)` // If we are using postgres, the `transactionIds.Contains(w.BId)` result in a long query like `ANY(@txId1, @txId2, @txId3, @txId4)`
// Such request isn't well optimized by postgres, and create different requests clogging up // Such request isn't well optimized by postgres, and create different requests clogging up
// pg_stat_statements output, making it impossible to analyze the performance impact of this query. // pg_stat_statements output, making it impossible to analyze the performance impact of this query.
// On top of this, the entity version is doing 2 left join to satisfy the Include queries, resulting in n*m row returned for each transaction. // On top of this, the entity version is doing 2 left join to satisfy the Include queries, resulting in n*m row returned for each transaction.
@ -106,9 +106,9 @@ namespace BTCPayServer.Services
var query = var query =
$"SELECT wos.\"WalletId\", wos.\"Id\", wos.\"Type\", wos.\"Data\", wol.\"LinkData\", wol.\"Type2\", wol.\"Id2\"{includeNeighbourSelect} FROM ({selectWalletObjects}) wos " + $"SELECT wos.\"WalletId\", wos.\"Id\", wos.\"Type\", wos.\"Data\", wol.\"LinkData\", wol.\"Type2\", wol.\"Id2\"{includeNeighbourSelect} FROM ({selectWalletObjects}) wos " +
$"LEFT JOIN LATERAL ( " + $"LEFT JOIN LATERAL ( " +
"SELECT \"ParentType\" AS \"Type2\", \"ParentId\" AS \"Id2\", \"Data\" AS \"LinkData\" FROM \"WalletObjectLinks\" WHERE \"WalletId\"=wos.\"WalletId\" AND \"ChildType\"=wos.\"Type\" AND \"ChildId\"=wos.\"Id\" " + "SELECT \"AType\" AS \"Type2\", \"AId\" AS \"Id2\", \"Data\" AS \"LinkData\" FROM \"WalletObjectLinks\" WHERE \"WalletId\"=wos.\"WalletId\" AND \"BType\"=wos.\"Type\" AND \"BId\"=wos.\"Id\" " +
"UNION " + "UNION " +
"SELECT \"ChildType\" AS \"Type2\", \"ChildId\" AS \"Id2\", \"Data\" AS \"LinkData\" FROM \"WalletObjectLinks\" WHERE \"WalletId\"=wos.\"WalletId\" AND \"ParentType\"=wos.\"Type\" AND \"ParentId\"=wos.\"Id\"" + "SELECT \"BType\" AS \"Type2\", \"BId\" AS \"Id2\", \"Data\" AS \"LinkData\" FROM \"WalletObjectLinks\" WHERE \"WalletId\"=wos.\"WalletId\" AND \"AType\"=wos.\"Type\" AND \"AId\"=wos.\"Id\"" +
$" ) wol ON true " + includeNeighbourJoin; $" ) wol ON true " + includeNeighbourJoin;
cmd.CommandText = query; cmd.CommandText = query;
if (queryObject.WalletId is not null) if (queryObject.WalletId is not null)
@ -177,21 +177,21 @@ namespace BTCPayServer.Services
else else
{ {
wosById.Add(id, wo); wosById.Add(id, wo);
wo.ChildLinks = new List<WalletObjectLinkData>(); wo.Bs = new List<WalletObjectLinkData>();
} }
if (reader["Type2"] is not DBNull) if (reader["Type2"] is not DBNull)
{ {
var l = new WalletObjectLinkData() var l = new WalletObjectLinkData()
{ {
ChildType = (string)reader["Type2"], BType = (string)reader["Type2"],
ChildId = (string)reader["Id2"], BId = (string)reader["Id2"],
Data = reader["LinkData"] is DBNull ? null : (string)reader["LinkData"] Data = reader["LinkData"] is DBNull ? null : (string)reader["LinkData"]
}; };
wo.ChildLinks.Add(l); wo.Bs.Add(l);
l.Child = new WalletObjectData() l.B = new WalletObjectData()
{ {
Type = l.ChildType, Type = l.BType,
Id = l.ChildId, Id = l.BId,
Data = (!queryObject.IncludeNeighbours || reader["Data2"] is DBNull) ? null : (string)reader["Data2"] Data = (!queryObject.IncludeNeighbours || reader["Data2"] is DBNull) ? null : (string)reader["Data2"]
}; };
} }
@ -215,8 +215,8 @@ namespace BTCPayServer.Services
} }
if (queryObject.IncludeNeighbours) if (queryObject.IncludeNeighbours)
{ {
q = q.Include(o => o.ChildLinks).ThenInclude(o => o.Child) q = q.Include(o => o.Bs).ThenInclude(o => o.B)
.Include(o => o.ParentLinks).ThenInclude(o => o.Parent); .Include(o => o.As).ThenInclude(o => o.A);
} }
q = q.AsNoTracking(); q = q.AsNoTracking();
@ -299,10 +299,10 @@ namespace BTCPayServer.Services
var l = new WalletObjectLinkData() var l = new WalletObjectLinkData()
{ {
WalletId = a.WalletId.ToString(), WalletId = a.WalletId.ToString(),
ParentType = a.Type, AType = a.Type,
ParentId = a.Id, AId = a.Id,
ChildType = b.Type, BType = b.Type,
ChildId = b.Id, BId = b.Id,
Data = data?.ToString(Formatting.None) Data = data?.ToString(Formatting.None)
}; };
ctx.WalletObjectLinks.Add(l); ctx.WalletObjectLinks.Add(l);
@ -345,10 +345,10 @@ namespace BTCPayServer.Services
var l = new WalletObjectLinkData() var l = new WalletObjectLinkData()
{ {
WalletId = a.WalletId.ToString(), WalletId = a.WalletId.ToString(),
ParentType = a.Type, AType = a.Type,
ParentId = a.Id, AId = a.Id,
ChildType = b.Type, BType = b.Type,
ChildId = b.Id, BId = b.Id,
Data = data?.ToString(Formatting.None) Data = data?.ToString(Formatting.None)
}; };
var e = ctx.WalletObjectLinks.Add(l); var e = ctx.WalletObjectLinks.Add(l);
@ -453,10 +453,10 @@ namespace BTCPayServer.Services
ctx.WalletObjectLinks.Remove(new WalletObjectLinkData() ctx.WalletObjectLinks.Remove(new WalletObjectLinkData()
{ {
WalletId = a.WalletId.ToString(), WalletId = a.WalletId.ToString(),
ParentId = a.Id, AId = a.Id,
ParentType = a.Type, AType = a.Type,
ChildId = b.Id, BId = b.Id,
ChildType = b.Type BType = b.Type
}); });
try try
{ {