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@codeweavers.com --- This fixes issue 9 "No Itemref support for multiple key fields" except where filters are concerned. Most of the other 18 known issues still need fixing. --- 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 41d1e14aa..49bf85658 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 62332c1f6..f4d16836b 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 39c80cc89..593b039ff 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}; }