From d5c5177f2ef698aefa8aeffaa458016583c20f79 Mon Sep 17 00:00:00 2001 From: Max Kanat-Alexander Date: Sat, 2 Apr 2011 09:49:04 -0700 Subject: Bug 640045: Convert Search.pm to use the new AND/OR system internally. This includes creating new Search::Clause and Search::Condition objects. r=mkanat, a=mkanat (module owner) --- Bugzilla/Search/Clause.pm | 113 +++++++++++++++++++++++++++++++++++++++++++ Bugzilla/Search/Condition.pm | 66 +++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 Bugzilla/Search/Clause.pm create mode 100644 Bugzilla/Search/Condition.pm (limited to 'Bugzilla/Search') diff --git a/Bugzilla/Search/Clause.pm b/Bugzilla/Search/Clause.pm new file mode 100644 index 000000000..e31bfdd40 --- /dev/null +++ b/Bugzilla/Search/Clause.pm @@ -0,0 +1,113 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is BugzillaSource, Inc. +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Max Kanat-Alexander + +package Bugzilla::Search::Clause; +use strict; +use Bugzilla::Search::Condition qw(condition); + +sub new { + my ($class, $joiner) = @_; + bless { joiner => $joiner || 'AND' }, $class; +} + +sub children { + my ($self) = @_; + $self->{children} ||= []; + return $self->{children}; +} + +sub joiner { return $_[0]->{joiner} } + +sub has_children { + my ($self) = @_; + return scalar(@{ $self->children }) > 0 ? 1 : 0; +} + +sub has_conditions { + my ($self) = @_; + my $children = $self->children; + return 1 if grep { $_->isa('Bugzilla::Search::Condition') } @$children; + foreach my $child (@$children) { + return 1 if $child->has_conditions; + } + return 0; +} + +sub add { + my $self = shift; + my $children = $self->children; + if (@_ == 3) { + push(@$children, condition(@_)); + return; + } + + my ($child) = @_; + return if !defined $child; + $child->isa(__PACKAGE__) || $child->isa('Bugzilla::Search::Condition') + || die 'child not the right type: ' . $child; + push(@{ $self->children }, $child); +} + +sub negate { + my ($self, $value) = @_; + if (@_ == 2) { + $self->{negate} = $value; + } + return $self->{negate}; +} + +sub walk_conditions { + my ($self, $callback) = @_; + foreach my $child (@{ $self->children }) { + if ($child->isa('Bugzilla::Search::Condition')) { + $callback->($child); + } + else { + $child->walk_conditions($callback); + } + } +} + +sub as_string { + my ($self) = @_; + my @strings; + foreach my $child (@{ $self->children }) { + next if $child->isa(__PACKAGE__) && !$child->has_conditions; + next if $child->isa('Bugzilla::Search::Condition') + && !$child->translated; + + my $string = $child->as_string; + if ($self->joiner eq 'AND') { + $string = "( $string )" if $string =~ /OR/; + } + else { + $string = "( $string )" if $string =~ /AND/; + } + push(@strings, $string); + } + + my $sql = join(' ' . $self->joiner . ' ', @strings); + $sql = "NOT( $sql )" if $sql && $self->negate; + return $sql; +} + + +1; \ No newline at end of file diff --git a/Bugzilla/Search/Condition.pm b/Bugzilla/Search/Condition.pm new file mode 100644 index 000000000..db20e7f3b --- /dev/null +++ b/Bugzilla/Search/Condition.pm @@ -0,0 +1,66 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is BugzillaSource, Inc. +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Max Kanat-Alexander + +package Bugzilla::Search::Condition; +use strict; +use base qw(Exporter); +our @EXPORT_OK = qw(condition); + +sub new { + my ($class, $params) = @_; + my %self = %$params; + bless \%self, $class; + return \%self; +} + +sub field { return $_[0]->{field} } +sub operator { return $_[0]->{operator} } +sub value { return $_[0]->{value} } + +sub fov { + my ($self) = @_; + return ($self->field, $self->operator, $self->value); +} + +sub translated { + my ($self, $params) = @_; + if (@_ == 2) { + $self->{translated} = $params; + } + return $self->{translated}; +} + +sub as_string { + my ($self) = @_; + return $self->translated->{term}; +} + +########################### +# Convenience Subroutines # +########################### + +sub condition { + my ($field, $operator, $value) = @_; + return __PACKAGE__->new({ field => $field, operator => $operator, + value => $value }); +} + +1; \ No newline at end of file -- cgit v1.2.3-24-g4f1b