diff options
author | Perl Tidy <perltidy@bugzilla.org> | 2018-12-05 21:38:52 +0100 |
---|---|---|
committer | Dylan William Hardison <dylan@hardison.net> | 2018-12-05 23:49:08 +0100 |
commit | 8ec8da0491ad89604700b3e29a227966f6d84ba1 (patch) | |
tree | 9d270f173330ca19700e0ba9f2ee931300646de1 /Bugzilla/Elastic | |
parent | a7bb5a65b71644d9efce5fed783ed545b9336548 (diff) | |
download | bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.gz bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.xz |
no bug - reformat all the code using the new perltidy rules
Diffstat (limited to 'Bugzilla/Elastic')
-rw-r--r-- | Bugzilla/Elastic/Indexer.pm | 277 | ||||
-rw-r--r-- | Bugzilla/Elastic/Role/HasClient.pm | 12 | ||||
-rw-r--r-- | Bugzilla/Elastic/Role/Object.pm | 39 | ||||
-rw-r--r-- | Bugzilla/Elastic/Search.pm | 541 | ||||
-rw-r--r-- | Bugzilla/Elastic/Search/FakeCGI.pm | 33 |
5 files changed, 438 insertions, 464 deletions
diff --git a/Bugzilla/Elastic/Indexer.pm b/Bugzilla/Elastic/Indexer.pm index a9d796ae7..579829014 100644 --- a/Bugzilla/Elastic/Indexer.pm +++ b/Bugzilla/Elastic/Indexer.pm @@ -16,206 +16,197 @@ use namespace::clean; with 'Bugzilla::Elastic::Role::HasClient'; -has 'shadow_dbh' => ( is => 'lazy' ); +has 'shadow_dbh' => (is => 'lazy'); -has 'debug_sql' => ( - is => 'ro', - default => 0, -); +has 'debug_sql' => (is => 'ro', default => 0,); -has 'progress_bar' => ( - is => 'ro', - predicate => 'has_progress_bar', -); +has 'progress_bar' => (is => 'ro', predicate => 'has_progress_bar',); sub _create_index { - my ($self, $class) = @_; - my $indices = $self->client->indices; - my $index_name = $class->ES_INDEX; - - unless ($indices->exists(index => $index_name)) { - $indices->create( - index => $index_name, - body => { settings => $class->ES_SETTINGS }, - ); - } + my ($self, $class) = @_; + my $indices = $self->client->indices; + my $index_name = $class->ES_INDEX; + + unless ($indices->exists(index => $index_name)) { + $indices->create( + index => $index_name, + body => {settings => $class->ES_SETTINGS}, + ); + } } sub _bulk_helper { - my ($self, $class) = @_; + my ($self, $class) = @_; - return $self->client->bulk_helper( - index => $class->ES_INDEX, - type => $class->ES_TYPE, - ); + return $self->client->bulk_helper( + index => $class->ES_INDEX, + type => $class->ES_TYPE, + ); } sub _find_largest { - my ($self, $class, $field) = @_; - - my $result = $self->client->search( - index => $class->ES_INDEX, - type => $class->ES_TYPE, - body => { - aggs => { $field => { extended_stats => { field => $field } } }, - size => 0 - } - ); - - my $max = $result->{aggregations}{$field}{max}; - if (not defined $max) { - return 0; - } - elsif (looks_like_number($max)) { - return $max; - } - else { - die "largest value for '$field' is not a number: $max"; - } + my ($self, $class, $field) = @_; + + my $result = $self->client->search( + index => $class->ES_INDEX, + type => $class->ES_TYPE, + body => {aggs => {$field => {extended_stats => {field => $field}}}, size => 0} + ); + + my $max = $result->{aggregations}{$field}{max}; + if (not defined $max) { + return 0; + } + elsif (looks_like_number($max)) { + return $max; + } + else { + die "largest value for '$field' is not a number: $max"; + } } sub _find_largest_mtime { - my ($self, $class) = @_; + my ($self, $class) = @_; - return $self->_find_largest($class, 'es_mtime'); + return $self->_find_largest($class, 'es_mtime'); } sub _find_largest_id { - my ($self, $class) = @_; + my ($self, $class) = @_; - return $self->_find_largest($class, $class->ID_FIELD); + return $self->_find_largest($class, $class->ID_FIELD); } sub _put_mapping { - my ($self, $class) = @_; - - my %body = ( properties => scalar $class->ES_PROPERTIES ); - if ($class->does('Bugzilla::Elastic::Role::ChildObject')) { - $body{_parent} = { type => $class->ES_PARENT_TYPE }; - } - - $self->client->indices->put_mapping( - index => $class->ES_INDEX, - type => $class->ES_TYPE, - body => \%body, - ); + my ($self, $class) = @_; + + my %body = (properties => scalar $class->ES_PROPERTIES); + if ($class->does('Bugzilla::Elastic::Role::ChildObject')) { + $body{_parent} = {type => $class->ES_PARENT_TYPE}; + } + + $self->client->indices->put_mapping( + index => $class->ES_INDEX, + type => $class->ES_TYPE, + body => \%body, + ); } sub _debug_sql { - my ($self, $sql, $params) = @_; - if ($self->debug_sql) { - my ($out, @args) = ($sql, $params ? (@$params) : ()); - $out =~ s/^\n//gs; - $out =~ s/^\s{8}//gm; - $out =~ s/\?/Bugzilla->dbh->quote(shift @args)/ge; - warn $out, "\n"; - } - - return ($sql, $params) + my ($self, $sql, $params) = @_; + if ($self->debug_sql) { + my ($out, @args) = ($sql, $params ? (@$params) : ()); + $out =~ s/^\n//gs; + $out =~ s/^\s{8}//gm; + $out =~ s/\?/Bugzilla->dbh->quote(shift @args)/ge; + warn $out, "\n"; + } + + return ($sql, $params); } sub bulk_load { - my ( $self, $class ) = @_; + my ($self, $class) = @_; - $self->_create_index($class); + $self->_create_index($class); - my $bulk = $self->_bulk_helper($class); - my $last_mtime = $self->_find_largest_mtime($class); - my $last_id = $self->_find_largest_id($class); - my $new_ids = $self->_select_all_ids($class, $last_id); - my $updated_ids = $self->_select_updated_ids($class, $last_mtime); + my $bulk = $self->_bulk_helper($class); + my $last_mtime = $self->_find_largest_mtime($class); + my $last_id = $self->_find_largest_id($class); + my $new_ids = $self->_select_all_ids($class, $last_id); + my $updated_ids = $self->_select_updated_ids($class, $last_mtime); - $self->_put_mapping($class); - $self->_bulk_load_ids($bulk, $class, $new_ids) if @$new_ids; - $self->_bulk_load_ids($bulk, $class, $updated_ids) if @$updated_ids; + $self->_put_mapping($class); + $self->_bulk_load_ids($bulk, $class, $new_ids) if @$new_ids; + $self->_bulk_load_ids($bulk, $class, $updated_ids) if @$updated_ids; - return { - new => scalar @$new_ids, - updated => scalar @$updated_ids, - }; + return {new => scalar @$new_ids, updated => scalar @$updated_ids,}; } sub _select_all_ids { - my ($self, $class, $last_id) = @_; + my ($self, $class, $last_id) = @_; - my $dbh = Bugzilla->dbh; - my ($sql, $params) = $self->_debug_sql($class->ES_SELECT_ALL_SQL($last_id)); - return $dbh->selectcol_arrayref($sql, undef, @$params); + my $dbh = Bugzilla->dbh; + my ($sql, $params) = $self->_debug_sql($class->ES_SELECT_ALL_SQL($last_id)); + return $dbh->selectcol_arrayref($sql, undef, @$params); } sub _select_updated_ids { - my ($self, $class, $last_mtime) = @_; + my ($self, $class, $last_mtime) = @_; - my $dbh = Bugzilla->dbh; - my ($updated_sql, $updated_params) = $self->_debug_sql($class->ES_SELECT_UPDATED_SQL($last_mtime)); - return $dbh->selectcol_arrayref($updated_sql, undef, @$updated_params); + my $dbh = Bugzilla->dbh; + my ($updated_sql, $updated_params) + = $self->_debug_sql($class->ES_SELECT_UPDATED_SQL($last_mtime)); + return $dbh->selectcol_arrayref($updated_sql, undef, @$updated_params); } sub bulk_load_ids { - my ($self, $class, $ids) = @_; + my ($self, $class, $ids) = @_; - $self->_create_index($class); - $self->_put_mapping($class); - $self->_bulk_load_ids($self->_bulk_helper($class), $class, $ids); + $self->_create_index($class); + $self->_put_mapping($class); + $self->_bulk_load_ids($self->_bulk_helper($class), $class, $ids); } sub _bulk_load_ids { - my ($self, $bulk, $class, $all_ids) = @_; - - my $iter = natatime $class->ES_OBJECTS_AT_ONCE, @$all_ids; - my $mtime = $self->_current_mtime; - my $progress_bar; - my $next_update; - - if ($self->has_progress_bar) { - my $name = (split(/::/, $class))[-1]; - $progress_bar = $self->progress_bar->new({ - name => $name, - count => scalar @$all_ids, - ETA => 'linear' - }); - $progress_bar->message(sprintf "loading %d $class objects, %d at a time", scalar @$all_ids, $class->ES_OBJECTS_AT_ONCE); - $next_update = $progress_bar->update(0); - $progress_bar->max_update_rate(1); + my ($self, $bulk, $class, $all_ids) = @_; + + my $iter = natatime $class->ES_OBJECTS_AT_ONCE, @$all_ids; + my $mtime = $self->_current_mtime; + my $progress_bar; + my $next_update; + + if ($self->has_progress_bar) { + my $name = (split(/::/, $class))[-1]; + $progress_bar + = $self->progress_bar->new({ + name => $name, count => scalar @$all_ids, ETA => 'linear' + }); + $progress_bar->message( + sprintf "loading %d $class objects, %d at a time", + scalar @$all_ids, + $class->ES_OBJECTS_AT_ONCE + ); + $next_update = $progress_bar->update(0); + $progress_bar->max_update_rate(1); + } + + my $total = 0; + my $start = time; + while (my @ids = $iter->()) { + if ($progress_bar) { + $total += @ids; + if ($total >= $next_update) { + $next_update = $progress_bar->update($total); + my $duration = time - $start || 1; + } } - my $total = 0; - my $start = time; - while (my @ids = $iter->()) { - if ($progress_bar) { - $total += @ids; - if ($total >= $next_update) { - $next_update = $progress_bar->update($total); - my $duration = time - $start || 1; - } - } - - my $objects = $class->new_from_list(\@ids); - foreach my $object (@$objects) { - my %doc = ( - id => $object->es_id, - source => scalar $object->es_document($mtime), - ); - - if ($class->does('Bugzilla::Elastic::Role::ChildObject')) { - $doc{parent} = $object->es_parent_id; - } - - $bulk->index(\%doc); - } - Bugzilla->_cleanup(); + my $objects = $class->new_from_list(\@ids); + foreach my $object (@$objects) { + my %doc + = (id => $object->es_id, source => scalar $object->es_document($mtime),); + + if ($class->does('Bugzilla::Elastic::Role::ChildObject')) { + $doc{parent} = $object->es_parent_id; + } + + $bulk->index(\%doc); } + Bugzilla->_cleanup(); + } - $bulk->flush; + $bulk->flush; } sub _build_shadow_dbh { Bugzilla->switch_to_shadow_db } sub _current_mtime { - my ($self) = @_; - my ($mtime) = $self->shadow_dbh->selectrow_array("SELECT UNIX_TIMESTAMP(NOW())"); - return $mtime; + my ($self) = @_; + my ($mtime) + = $self->shadow_dbh->selectrow_array("SELECT UNIX_TIMESTAMP(NOW())"); + return $mtime; } 1; diff --git a/Bugzilla/Elastic/Role/HasClient.pm b/Bugzilla/Elastic/Role/HasClient.pm index a971392e0..41d8e7647 100644 --- a/Bugzilla/Elastic/Role/HasClient.pm +++ b/Bugzilla/Elastic/Role/HasClient.pm @@ -13,13 +13,13 @@ use Moo::Role; has 'client' => (is => 'lazy'); sub _build_client { - my ($self) = @_; + my ($self) = @_; - require Search::Elasticsearch; - return Search::Elasticsearch->new( - nodes => [ split(/\s+/, Bugzilla->params->{elasticsearch_nodes}) ], - cxn_pool => 'Sniff', - ); + require Search::Elasticsearch; + return Search::Elasticsearch->new( + nodes => [split(/\s+/, Bugzilla->params->{elasticsearch_nodes})], + cxn_pool => 'Sniff', + ); } 1; diff --git a/Bugzilla/Elastic/Role/Object.pm b/Bugzilla/Elastic/Role/Object.pm index 674545d04..6974d9087 100644 --- a/Bugzilla/Elastic/Role/Object.pm +++ b/Bugzilla/Elastic/Role/Object.pm @@ -12,45 +12,44 @@ use Role::Tiny; requires qw(ES_TYPE ES_INDEX ES_SETTINGS ES_PROPERTIES es_document); requires qw(ID_FIELD DB_TABLE); -sub ES_OBJECTS_AT_ONCE { 100 } +sub ES_OBJECTS_AT_ONCE {100} sub ES_SELECT_ALL_SQL { - my ($class, $last_id) = @_; + my ($class, $last_id) = @_; - my $id = $class->ID_FIELD; - my $table = $class->DB_TABLE; + my $id = $class->ID_FIELD; + my $table = $class->DB_TABLE; - return ("SELECT $id FROM $table WHERE $id > ? ORDER BY $id", [$last_id // 0]); + return ("SELECT $id FROM $table WHERE $id > ? ORDER BY $id", [$last_id // 0]); } requires qw(ES_SELECT_UPDATED_SQL); sub es_id { - my ($self) = @_; - return join('_', $self->ES_TYPE, $self->id); + my ($self) = @_; + return join('_', $self->ES_TYPE, $self->id); } around 'ES_PROPERTIES' => sub { - my $orig = shift; - my $self = shift; - my $properties = $orig->($self, @_); - $properties->{es_mtime} = { type => 'long' }; - $properties->{$self->ID_FIELD} = { type => 'long', analyzer => 'keyword' }; + my $orig = shift; + my $self = shift; + my $properties = $orig->($self, @_); + $properties->{es_mtime} = {type => 'long'}; + $properties->{$self->ID_FIELD} = {type => 'long', analyzer => 'keyword'}; - return $properties; + return $properties; }; around 'es_document' => sub { - my ($orig, $self, $mtime) = @_; - my $doc = $orig->($self); + my ($orig, $self, $mtime) = @_; + my $doc = $orig->($self); - $doc->{es_mtime} = $mtime; - $doc->{$self->ID_FIELD} = $self->id; - $doc->{_id} = $self->es_id; + $doc->{es_mtime} = $mtime; + $doc->{$self->ID_FIELD} = $self->id; + $doc->{_id} = $self->es_id; - return $doc; + return $doc; }; - 1; diff --git a/Bugzilla/Elastic/Search.pm b/Bugzilla/Elastic/Search.pm index 26ab71bec..032f9b03a 100644 --- a/Bugzilla/Elastic/Search.pm +++ b/Bugzilla/Elastic/Search.pm @@ -16,63 +16,62 @@ use namespace::clean; use Bugzilla::Elastic::Search::FakeCGI; -has 'quicksearch' => ( is => 'ro' ); -has 'limit' => ( is => 'ro', predicate => 'has_limit' ); -has 'offset' => ( is => 'ro', predicate => 'has_offset' ); -has 'fields' => ( is => 'ro', isa => \&_arrayref_of_fields, default => sub { [] } ); -has 'params' => ( is => 'lazy' ); -has 'clause' => ( is => 'lazy' ); -has 'es_query' => ( is => 'lazy' ); +has 'quicksearch' => (is => 'ro'); +has 'limit' => (is => 'ro', predicate => 'has_limit'); +has 'offset' => (is => 'ro', predicate => 'has_offset'); +has 'fields' => + (is => 'ro', isa => \&_arrayref_of_fields, default => sub { [] }); +has 'params' => (is => 'lazy'); +has 'clause' => (is => 'lazy'); +has 'es_query' => (is => 'lazy'); has 'search_description' => (is => 'lazy'); -has 'query_time' => ( is => 'rwp' ); +has 'query_time' => (is => 'rwp'); -has '_input_order' => ( is => 'ro', init_arg => 'order', required => 1); -has '_order' => ( is => 'lazy', init_arg => undef ); -has 'invalid_order_columns' => ( is => 'lazy' ); +has '_input_order' => (is => 'ro', init_arg => 'order', required => 1); +has '_order' => (is => 'lazy', init_arg => undef); +has 'invalid_order_columns' => (is => 'lazy'); with 'Bugzilla::Elastic::Role::HasClient'; with 'Bugzilla::Elastic::Role::Search'; my @SUPPORTED_FIELDS = qw( - bug_id product component short_desc - priority status_whiteboard bug_status resolution - keywords alias assigned_to reporter delta_ts - longdesc cf_crash_signature classification bug_severity - commenter + bug_id product component short_desc + priority status_whiteboard bug_status resolution + keywords alias assigned_to reporter delta_ts + longdesc cf_crash_signature classification bug_severity + commenter ); my %IS_SUPPORTED_FIELD = map { $_ => 1 } @SUPPORTED_FIELDS; $IS_SUPPORTED_FIELD{relevance} = 1; my @NORMAL_FIELDS = qw( - priority - bug_severity - bug_status - resolution - product - component - classification - short_desc - assigned_to - reporter + priority + bug_severity + bug_status + resolution + product + component + classification + short_desc + assigned_to + reporter ); my %SORT_MAP = ( - bug_id => '_id', - relevance => '_score', - map { $_ => "$_.eq" } @NORMAL_FIELDS, + bug_id => '_id', + relevance => '_score', + map { $_ => "$_.eq" } @NORMAL_FIELDS, ); -my %EQUALS_MAP = ( - map { $_ => "$_.eq" } @NORMAL_FIELDS, -); +my %EQUALS_MAP = (map { $_ => "$_.eq" } @NORMAL_FIELDS,); sub _arrayref_of_fields { - my $f = $_; - foreach my $field (@$f) { - Bugzilla::Elastic::Search::UnsupportedField->throw(field => $field) - unless $IS_SUPPORTED_FIELD{$field}; - } + my $f = $_; + foreach my $field (@$f) { + Bugzilla::Elastic::Search::UnsupportedField->throw(field => $field) + unless $IS_SUPPORTED_FIELD{$field}; + } } @@ -82,360 +81,342 @@ sub _arrayref_of_fields { # But the DB column stayed the same... and elasticsearch uses the db name # However search likes to use the "new" name. # for now we hack a fix in here. -my %REMAP_NAME = ( - changeddate => 'delta_ts', -); +my %REMAP_NAME = (changeddate => 'delta_ts',); sub data { - my ($self) = @_; - my $body = $self->es_query; - my $result = eval { - $self->client->search( - index => Bugzilla::Bug->ES_INDEX, - type => Bugzilla::Bug->ES_TYPE, - body => $body, - ); - }; - die $@ unless $result; - $self->_set_query_time($result->{took} / 1000); - - my @fields = map { $REMAP_NAME{$_} // $_ } @{ $self->fields }; - my (@ids, %hits); - foreach my $hit (@{ $result->{hits}{hits} }) { - push @ids, $hit->{_id}; - my $source = $hit->{_source}; - $source->{relevance} = $hit->{_score}; - foreach my $val (values %$source) { - next unless defined $val; - trick_taint($val); - } - trick_taint($hit->{_id}); - if ($source) { - $hits{$hit->{_id}} = [ @$source{@fields} ]; - } - else { - $hits{$hit->{_id}} = $hit->{_id}; - } + my ($self) = @_; + my $body = $self->es_query; + my $result = eval { + $self->client->search( + index => Bugzilla::Bug->ES_INDEX, + type => Bugzilla::Bug->ES_TYPE, + body => $body, + ); + }; + die $@ unless $result; + $self->_set_query_time($result->{took} / 1000); + + my @fields = map { $REMAP_NAME{$_} // $_ } @{$self->fields}; + my (@ids, %hits); + foreach my $hit (@{$result->{hits}{hits}}) { + push @ids, $hit->{_id}; + my $source = $hit->{_source}; + $source->{relevance} = $hit->{_score}; + foreach my $val (values %$source) { + next unless defined $val; + trick_taint($val); + } + trick_taint($hit->{_id}); + if ($source) { + $hits{$hit->{_id}} = [@$source{@fields}]; + } + else { + $hits{$hit->{_id}} = $hit->{_id}; } - my $visible_ids = Bugzilla->user->visible_bugs(\@ids); + } + my $visible_ids = Bugzilla->user->visible_bugs(\@ids); - return [ map { $hits{$_} } @$visible_ids ]; + return [map { $hits{$_} } @$visible_ids]; } sub _valid_order { - my ($self) = @_; + my ($self) = @_; - return grep { $IS_SUPPORTED_FIELD{$_->[0]} } @{$self->_order}; + return grep { $IS_SUPPORTED_FIELD{$_->[0]} } @{$self->_order}; } sub order { - my ($self) = @_; + my ($self) = @_; - return map { $_->[0] } $self->_valid_order; + return map { $_->[0] } $self->_valid_order; } sub _quicksearch_to_params { - my ($quicksearch) = @_; - no warnings 'redefine'; - my $cgi = Bugzilla::Elastic::Search::FakeCGI->new; - local *Bugzilla::cgi = sub { $cgi }; - local $Bugzilla::Search::Quicksearch::ELASTIC = 1; - quicksearch($quicksearch); - - return $cgi->params; + my ($quicksearch) = @_; + no warnings 'redefine'; + my $cgi = Bugzilla::Elastic::Search::FakeCGI->new; + local *Bugzilla::cgi = sub {$cgi}; + local $Bugzilla::Search::Quicksearch::ELASTIC = 1; + quicksearch($quicksearch); + + return $cgi->params; } sub _build_fields { return \@SUPPORTED_FIELDS } sub _build__order { - my ($self) = @_; - - my @order; - foreach my $order (@{$self->_input_order}) { - if ($order =~ /^(.+)\s+(asc|desc)$/i) { - push @order, [ $1, lc $2 ]; - } - else { - push @order, [ $order ]; - } + my ($self) = @_; + + my @order; + foreach my $order (@{$self->_input_order}) { + if ($order =~ /^(.+)\s+(asc|desc)$/i) { + push @order, [$1, lc $2]; + } + else { + push @order, [$order]; } - return \@order; + } + return \@order; } sub _build_invalid_order_columns { - my ($self) = @_; + my ($self) = @_; - return [ map { $_->[0] } grep { !$IS_SUPPORTED_FIELD{$_->[0]} } @{ $self->_order } ]; + return [map { $_->[0] } + grep { !$IS_SUPPORTED_FIELD{$_->[0]} } @{$self->_order}]; } sub _build_params { - my ($self) = @_; + my ($self) = @_; - return _quicksearch_to_params($self->quicksearch); + return _quicksearch_to_params($self->quicksearch); } sub _build_clause { - my ($self) = @_; - my $search = Bugzilla::Search->new(params => $self->params); + my ($self) = @_; + my $search = Bugzilla::Search->new(params => $self->params); - return $search->_params_to_data_structure; + return $search->_params_to_data_structure; } sub _build_search_description { - my ($self) = @_; + my ($self) = @_; - return [_describe($self->clause)]; + return [_describe($self->clause)]; } sub _describe { - my ($thing) = @_; + my ($thing) = @_; - state $class_to_func = { - 'Bugzilla::Search::Condition' => \&_describe_condition, - 'Bugzilla::Search::Clause' => \&_describe_clause - }; + state $class_to_func = { + 'Bugzilla::Search::Condition' => \&_describe_condition, + 'Bugzilla::Search::Clause' => \&_describe_clause + }; - my $func = $class_to_func->{ref $thing} or die "nothing for $thing\n"; + my $func = $class_to_func->{ref $thing} or die "nothing for $thing\n"; - return $func->($thing); + return $func->($thing); } sub _describe_clause { - my ($clause) = @_; + my ($clause) = @_; - return map { _describe($_) } @{$clause->children}; + return map { _describe($_) } @{$clause->children}; } sub _describe_condition { - my ($cond) = @_; + my ($cond) = @_; - return { field => $cond->field, type => $cond->operator, value => _describe_value($cond->value) }; + return { + field => $cond->field, + type => $cond->operator, + value => _describe_value($cond->value) + }; } sub _describe_value { - my ($val) = @_; + my ($val) = @_; - return ref($val) ? join(", ", @$val) : $val; + return ref($val) ? join(", ", @$val) : $val; } sub _build_es_query { - my ($self) = @_; - my @extra; - - if ($self->_valid_order) { - my @sort = map { - my $f = $SORT_MAP{$_->[0]} // $_->[0]; - @$_ > 1 ? { $f => lc $_[1] } : $f; - } $self->_valid_order; - push @extra, sort => \@sort; - } - if ($self->has_offset) { - push @extra, from => $self->offset; + my ($self) = @_; + my @extra; + + if ($self->_valid_order) { + my @sort = map { + my $f = $SORT_MAP{$_->[0]} // $_->[0]; + @$_ > 1 ? {$f => lc $_[1]} : $f; + } $self->_valid_order; + push @extra, sort => \@sort; + } + if ($self->has_offset) { + push @extra, from => $self->offset; + } + my $max_limit = Bugzilla->params->{max_search_results}; + my $limit = Bugzilla->params->{default_search_limit}; + if ($self->has_limit) { + if ($self->limit) { + my $l = $self->limit; + $limit = $l < $max_limit ? $l : $max_limit; } - my $max_limit = Bugzilla->params->{max_search_results}; - my $limit = Bugzilla->params->{default_search_limit}; - if ($self->has_limit) { - if ($self->limit) { - my $l = $self->limit; - $limit = $l < $max_limit ? $l : $max_limit; - } - else { - $limit = $max_limit; - } + else { + $limit = $max_limit; } - push @extra, size => $limit; - return { - _source => @{$self->fields} ? \1 : \0, - query => _query($self->clause), - @extra, - }; + } + push @extra, size => $limit; + return { + _source => @{$self->fields} ? \1 : \0, + query => _query($self->clause), + @extra, + }; } sub _query { - my ($thing) = @_; - state $class_to_func = { - 'Bugzilla::Search::Condition' => \&_query_condition, - 'Bugzilla::Search::Clause' => \&_query_clause, - }; + my ($thing) = @_; + state $class_to_func = { + 'Bugzilla::Search::Condition' => \&_query_condition, + 'Bugzilla::Search::Clause' => \&_query_clause, + }; - my $func = $class_to_func->{ref $thing} or die "nothing for $thing\n"; + my $func = $class_to_func->{ref $thing} or die "nothing for $thing\n"; - return $func->($thing); + return $func->($thing); } sub _query_condition { - my ($cond) = @_; - state $operator_to_es = { - equals => \&_operator_equals, - substring => \&_operator_substring, - anyexact => \&_operator_anyexact, - anywords => \&_operator_anywords, - allwords => \&_operator_allwords, - }; - - my $field = $cond->field; - my $operator = $cond->operator; - my $value = $cond->value; - - if ($field eq 'resolution') { - $value = [ map { $_ eq '---' ? '' : $_ } ref $value ? @$value : $value ]; - } - - unless ($IS_SUPPORTED_FIELD{$field}) { - Bugzilla::Elastic::Search::UnsupportedField->throw(field => $field); - } - - my $op = $operator_to_es->{$operator} - or Bugzilla::Elastic::Search::UnsupportedOperator->throw(operator => $operator); - - my $result; - if (ref $op) { - $result = $op->($field, $value); - } else { - $result = { $op => { $field => $value } }; - } - - return $result; + my ($cond) = @_; + state $operator_to_es = { + equals => \&_operator_equals, + substring => \&_operator_substring, + anyexact => \&_operator_anyexact, + anywords => \&_operator_anywords, + allwords => \&_operator_allwords, + }; + + my $field = $cond->field; + my $operator = $cond->operator; + my $value = $cond->value; + + if ($field eq 'resolution') { + $value = [map { $_ eq '---' ? '' : $_ } ref $value ? @$value : $value]; + } + + unless ($IS_SUPPORTED_FIELD{$field}) { + Bugzilla::Elastic::Search::UnsupportedField->throw(field => $field); + } + + my $op = $operator_to_es->{$operator} + or + Bugzilla::Elastic::Search::UnsupportedOperator->throw(operator => $operator); + + my $result; + if (ref $op) { + $result = $op->($field, $value); + } + else { + $result = {$op => {$field => $value}}; + } + + return $result; } # is equal to any of the strings sub _operator_anyexact { - my ($field, $value) = @_; - my @values = ref $value ? @$value : split(/\s*,\s*/, $value); - if (@values == 1) { - return _operator_equals($field, $values[0]); - } - else { - return { - terms => { - $EQUALS_MAP{$field} // $field => [map { lc } @values], - minimum_should_match => 1, - }, - }; - } + my ($field, $value) = @_; + my @values = ref $value ? @$value : split(/\s*,\s*/, $value); + if (@values == 1) { + return _operator_equals($field, $values[0]); + } + else { + return { + terms => { + $EQUALS_MAP{$field} // $field => [map {lc} @values], + minimum_should_match => 1, + }, + }; + } } # contains any of the words sub _operator_anywords { - my ($field, $value) = @_; - return { - match => { - $field => { query => $value, operator => "or" } - }, - }; + my ($field, $value) = @_; + return {match => {$field => {query => $value, operator => "or"}},}; } # contains all of the words sub _operator_allwords { - my ($field, $value) = @_; - return { - match => { - $field => { query => $value, operator => "and" } - }, - }; + my ($field, $value) = @_; + return {match => {$field => {query => $value, operator => "and"}},}; } sub _operator_equals { - my ($field, $value) = @_; - return { - match => { - $EQUALS_MAP{$field} // $field => $value, - }, - }; + my ($field, $value) = @_; + return {match => {$EQUALS_MAP{$field} // $field => $value,},}; } sub _operator_substring { - my ($field, $value) = @_; - my $is_insider = Bugzilla->user->is_insider; - - if ($field eq 'longdesc') { - return { - has_child => { - type => 'comment', - query => { - bool => { - must => [ - { match => { body => { query => $value, operator => "and" } } }, - $is_insider ? () : { term => { is_private => \0 } }, - ], - }, - }, - }, - } - } - elsif ($field eq 'reporter' or $field eq 'assigned_to') { - return { - prefix => { - $EQUALS_MAP{$field} // $field => lc $value, - } - } - } - elsif ($field eq 'status_whiteboard' && $value =~ /[\[\]]/) { - return { - match => { - $EQUALS_MAP{$field} // $field => $value, - } - }; - } - else { - return { - wildcard => { - $EQUALS_MAP{$field} // $field => lc "*$value*", - } - }; - } + my ($field, $value) = @_; + my $is_insider = Bugzilla->user->is_insider; + + if ($field eq 'longdesc') { + return { + has_child => { + type => 'comment', + query => { + bool => { + must => [ + {match => {body => {query => $value, operator => "and"}}}, + $is_insider ? () : {term => {is_private => \0}}, + ], + }, + }, + }, + }; + } + elsif ($field eq 'reporter' or $field eq 'assigned_to') { + return {prefix => {$EQUALS_MAP{$field} // $field => lc $value,}}; + } + elsif ($field eq 'status_whiteboard' && $value =~ /[\[\]]/) { + return {match => {$EQUALS_MAP{$field} // $field => $value,}}; + } + else { + return {wildcard => {$EQUALS_MAP{$field} // $field => lc "*$value*",}}; + } } sub _query_clause { - my ($clause) = @_; + my ($clause) = @_; - state $joiner_to_func = { - AND => \&_join_and, - OR => \&_join_or, - }; + state $joiner_to_func = {AND => \&_join_and, OR => \&_join_or,}; - my @children = grep { !$_->isa('Bugzilla::Search::Clause') || @{$_->children} } @{$clause->children}; - if (@children == 1) { - return _query($children[0]); - } + my @children = grep { !$_->isa('Bugzilla::Search::Clause') || @{$_->children} } + @{$clause->children}; + if (@children == 1) { + return _query($children[0]); + } - return $joiner_to_func->{$clause->joiner}->([ map { _query($_) } @children ]); + return $joiner_to_func->{$clause->joiner}->([map { _query($_) } @children]); } sub _join_and { - my ($children) = @_; - return { bool => { must => $children } }, + my ($children) = @_; + return {bool => {must => $children}},; } sub _join_or { - my ($children) = @_; - return { bool => { should => $children } }; + my ($children) = @_; + return {bool => {should => $children}}; } # Exceptions BEGIN { - package Bugzilla::Elastic::Search::Redirect; - use Moo; - with 'Throwable'; + package Bugzilla::Elastic::Search::Redirect; + use Moo; + + with 'Throwable'; - has 'redirect_args' => (is => 'ro', required => 1); + has 'redirect_args' => (is => 'ro', required => 1); - package Bugzilla::Elastic::Search::UnsupportedField; - use Moo; - use overload q{""} => sub { "Unsupported field: ", $_[0]->field }, fallback => 1; + package Bugzilla::Elastic::Search::UnsupportedField; + use Moo; + use overload + q{""} => sub { "Unsupported field: ", $_[0]->field }, + fallback => 1; - with 'Throwable'; + with 'Throwable'; - has 'field' => (is => 'ro', required => 1); + has 'field' => (is => 'ro', required => 1); - package Bugzilla::Elastic::Search::UnsupportedOperator; - use Moo; + package Bugzilla::Elastic::Search::UnsupportedOperator; + use Moo; - with 'Throwable'; + with 'Throwable'; - has 'operator' => (is => 'ro', required => 1); + has 'operator' => (is => 'ro', required => 1); } 1; diff --git a/Bugzilla/Elastic/Search/FakeCGI.pm b/Bugzilla/Elastic/Search/FakeCGI.pm index 827c96c52..9772d798c 100644 --- a/Bugzilla/Elastic/Search/FakeCGI.pm +++ b/Bugzilla/Elastic/Search/FakeCGI.pm @@ -13,31 +13,34 @@ has 'params' => (is => 'ro', default => sub { {} }); # we pretend to be Bugzilla::CGI at times. sub canonicalise_query { - return Bugzilla::CGI::canonicalise_query(@_); + return Bugzilla::CGI::canonicalise_query(@_); } sub delete { - my ($self, $key) = @_; - delete $self->params->{$key}; + my ($self, $key) = @_; + delete $self->params->{$key}; } sub redirect { - my ($self, @args) = @_; + my ($self, @args) = @_; - Bugzilla::Elastic::Search::Redirect->throw(redirect_args => \@args); + Bugzilla::Elastic::Search::Redirect->throw(redirect_args => \@args); } sub param { - my ($self, $key, $val, @rest) = @_; - if (@_ > 3) { - $self->params->{$key} = [$val, @rest]; - } elsif (@_ == 3) { - $self->params->{$key} = $val; - } elsif (@_ == 2) { - return $self->params->{$key}; - } else { - return $self->params - } + my ($self, $key, $val, @rest) = @_; + if (@_ > 3) { + $self->params->{$key} = [$val, @rest]; + } + elsif (@_ == 3) { + $self->params->{$key} = $val; + } + elsif (@_ == 2) { + return $self->params->{$key}; + } + else { + return $self->params; + } } 1; |