Francois Gouget : testbot/orm: Add support for multi-column Itemrefs.
Alexandre Julliard
julliard at winehq.org
Tue Jun 7 15:37:01 CDT 2022
Module: tools
Branch: master
Commit: 763995636b6b2fb1e703fbb405b651d057a22ed0
URL: https://source.winehq.org/git/tools.git/?a=commit;h=763995636b6b2fb1e703fbb405b651d057a22ed0
Author: Francois Gouget <fgouget at codeweavers.com>
Date: Tue Jun 7 18:49:35 2022 +0200
testbot/orm: Add support for multi-column Itemrefs.
Also document why they are not supported in filters.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45023
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
testbot/lib/ObjectModel/CGI/ValueFormatter.pm | 6 ++--
testbot/lib/ObjectModel/DBIBackEnd.pm | 7 ++++-
testbot/lib/ObjectModel/Item.pm | 41 ++++++++++++++++++++-------
3 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/testbot/lib/ObjectModel/CGI/ValueFormatter.pm b/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
index 41d1e14..49bf856 100644
--- a/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
+++ b/testbot/lib/ObjectModel/CGI/ValueFormatter.pm
@@ -306,16 +306,18 @@ sub GenerateValueHTML($$$;$)
}
elsif ($PropertyDescriptor->GetClass() eq "Itemref" and defined $Value)
{
- # Note: This only supports single-key Itemrefs
+ my $First = 1;
foreach my $ValuePD (@{$Value->GetPropertyDescriptors()})
{
if ($ValuePD->GetIsKey())
{
+ print "/" if (!$First);
+ $First = 0;
my $PropertyName = $ValuePD->GetName();
GenerateValueHTML($Parent, $ValuePD, $Value->$PropertyName);
- return;
}
}
+ return;
}
print defined $Value ? $Parent->escapeHTML($Value) : " ";
}
diff --git a/testbot/lib/ObjectModel/DBIBackEnd.pm b/testbot/lib/ObjectModel/DBIBackEnd.pm
index 62332c1..f4d1683 100644
--- a/testbot/lib/ObjectModel/DBIBackEnd.pm
+++ b/testbot/lib/ObjectModel/DBIBackEnd.pm
@@ -222,7 +222,12 @@ sub ColNameToDb($)
my $ColNames = $PropertyDescriptor->GetColNames();
if (@$ColNames != 1)
{
- die "cannot filter on Itemref with more than one column name: @$ColNames";
+ # This would require building a more complex where clause, something like
+ # ((col1 = item1.val1 AND col2 = item1.val2...) OR
+ # (col1 = item2.val1 AND col2 = item2.val2...) OR ...)
+ # So it is not supported. Instead one should build the where clause by
+ # hand from the underlying columns.
+ die "cannot filter on the ". $PropertyDescriptor->GetName() ." Itemref because it has a multi-column key: @$ColNames";
}
return $ColNames->[0];
}
diff --git a/testbot/lib/ObjectModel/Item.pm b/testbot/lib/ObjectModel/Item.pm
index 39c80cc..593b039 100644
--- a/testbot/lib/ObjectModel/Item.pm
+++ b/testbot/lib/ObjectModel/Item.pm
@@ -281,26 +281,45 @@ sub AUTOLOAD
}
elsif($PropertyDescriptor->GetClass() eq "Itemref")
{
- my $ColNames = $PropertyDescriptor->GetColNames();
- if (@{$ColNames} != 1)
- {
- die "Multiple key components not supported";
- }
if (@_)
{
- $self->{Itemrefs}{$PropertyName} = shift;
- if ($self->ValuesDiffer($self->{ColValues}{@{$ColNames}[0]},
- $self->{Itemrefs}{$PropertyName}->GetKey()))
+ my $Item = shift;
+ if (!$Item and !$self->{Itemrefs}{$PropertyName})
+ {
+ # No change -> nothing to do
+ }
+ elsif (!$Item)
+ {
+ $self->{IsModified} = 1;
+ $self->{Itemrefs}{$PropertyName} = undef;
+ foreach my $ColName (@{$PropertyDescriptor->GetColNames()})
+ {
+ $self->{ColValues}{$ColName} = undef;
+ }
+ }
+ elsif (!$self->{Itemrefs}{$PropertyName} or
+ $self->{Itemrefs}{$PropertyName} ne $Item)
{
$self->{IsModified} = 1;
- $self->{ColValues}{@{$ColNames}[0]} = $self->{Itemrefs}{$PropertyName}->GetKey();
+ $self->{Itemrefs}{$PropertyName} = $Item;
+ # Note that the foreign key names ($RefColNames) typically don't
+ # match the Item's primary key column names. But their order and
+ # count must match the primary key values.
+ my $RefColNames = $PropertyDescriptor->GetColNames();
+ my ($_ColNames, $ColValues) = $Item->GetMasterKey();
+ foreach my $ColIndex (0..$#{$RefColNames})
+ {
+ $self->{ColValues}{$RefColNames->[$ColIndex]} = $ColValues->[$ColIndex];
+ }
}
}
elsif (! defined($self->{Itemrefs}{$PropertyName}))
{
+ my $ColNames = $PropertyDescriptor->GetColNames();
+ my @KeyComponents = map { $self->{ColValues}{$_} || "" } @$ColNames;
my $Collection = &{$PropertyDescriptor->GetCreator()}($self);
- my $Item = $Collection->GetItem($self->{ColValues}{@{$ColNames}[0]});
- $self->{Itemrefs}{$PropertyName} = $Item;
+ my $Key = $Collection->CombineKey(@KeyComponents);
+ $self->{Itemrefs}{$PropertyName} = $Collection->GetItem($Key);
}
return $self->{Itemrefs}{$PropertyName};
}
More information about the wine-cvs
mailing list