diff options
-rw-r--r-- | Bugzilla/Object.pm | 52 | ||||
-rwxr-xr-x | Bugzilla/WebService/Bug.pm | 32 |
2 files changed, 78 insertions, 6 deletions
diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index 53720327b..75e04f2e7 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -156,9 +156,29 @@ sub match { return [$class->get_all] if !$criteria; - my (@terms, @values); + my (@terms, @values, $postamble); foreach my $field (keys %$criteria) { my $value = $criteria->{$field}; + + # allow for LIMIT and OFFSET expressions via the criteria. + next if $field eq 'OFFSET'; + if ( $field eq 'LIMIT' ) { + next unless defined $value; + $postamble = $dbh->sql_limit( $value, $criteria->{OFFSET} ); + next; + } + elsif ( $field eq 'WHERE' ) { + next unless $value; + # the WHERE value is a hashref where the keys are + # "column_name operator ?" and values are the placeholder's + # value. + foreach my $k (keys( %$value )) { + push( @terms, $k ); + push( @values, $value->{$k} ); + } + next; + } + if (ref $value eq 'ARRAY') { # IN () is invalid SQL, and if we have an empty list # to match against, we're just returning an empty @@ -181,12 +201,12 @@ sub match { } } - my $where = join(' AND ', @terms); - return $class->_do_list_select($where, \@values); + my $where = join(' AND ', @terms) if scalar @terms; + return $class->_do_list_select($where, \@values, $postamble); } sub _do_list_select { - my ($class, $where, $values) = @_; + my ($class, $where, $values, $postamble) = @_; my $table = $class->DB_TABLE; my $cols = join(',', $class->DB_COLUMNS); my $order = $class->LIST_ORDER; @@ -196,7 +216,9 @@ sub _do_list_select { $sql .= " WHERE $where "; } $sql .= " ORDER BY $order"; - + + $sql .= " $postamble" if $postamble; + my $dbh = Bugzilla->dbh; my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @$values); bless ($_, $class) foreach @$objects; @@ -625,6 +647,26 @@ There are two special values, the constants C<NULL> and C<NOT_NULL>, which means "give me objects where this field is NULL or NOT NULL, respectively." +In addition to the column keys, there are a few special keys that +can be used to rig the underlying database queries. These are +C<LIMIT>, C<OFFSET>, and C<WHERE>. + +The value for the C<LIMIT> key is expected to be an integer defining +the number of objects to return, while the value for C<OFFSET> defines +the position, relative to the number of objects the query would normally +return, at which to begin the result set. If C<OFFSET> is defined without +a corresponding C<LIMIT> it is silently ignored. + +The C<WHERE> key provides a mechanism for adding arbitrary WHERE +clauses to the underlying query. Its value is expected to a hash +reference whose keys are the columns, operators and placeholders, and the +values are the placeholders' bind value. For example: + + WHERE => {'some_column >= ?' => $some_value } + +would constrain the query to only those objects in the table whose +'some_column' column has a value greater than or equal to $some_value. + If you don't specify any criteria, calling this function is the same as doing C<[$class-E<gt>get_all]>. diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index 04b18fe7c..31f87ba99 100755 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -50,6 +50,8 @@ use constant FIELD_MAP => { summary => 'short_desc', url => 'bug_file_loc', whiteboard => 'status_whiteboard', + limit => 'LIMIT', + offset => 'OFFSET', }; use constant PRODUCT_SPECIFIC_FIELDS => qw(version target_milestone component); @@ -218,7 +220,21 @@ sub get_history { sub search { my ($self, $params) = @_; + + if ( $params->{offset} and !$params->{limit} ) { + ThrowCodeError( 'param_required', { param => 'limit', function => 'Bug.search()'}); + } + $params = _map_fields($params); + + # If the user set the 'last_change_time' param (translated into delta_ts + # by the field map), use a custom WHERE to constrain the query to only + # those bugs that have a delta_ts greater than or equal to + # the specified time. + if ( my $bug_when = delete $params->{delta_ts} ) { + $params->{WHERE} = {'delta_ts >= ?' => $bug_when}; + } + my $bugs = Bugzilla::Bug->match($params); my $visible = Bugzilla->user->visible_bugs($bugs); my @hashes = map { $self->_bug_to_hash($_) } @$visible; @@ -960,7 +976,21 @@ C<int> The numeric id of the bug. =item C<last_change_time> -C<dateTime> The last time the bug was updated. +C<dateTime> Limit the search to only those bugs which have changed +in some way since the specified time. It includes all bugs changed +between the specified time and the present. Note: only a single +C<dateTime> will accepted, not an array. + +=item C<limit> + +C<int> Limit the number of results returned to C<int> records. + +=item C<offset> + +C<int> Used in conjunction with the C<limit> argument, C<offset> defines +the starting position for the search. For example, given a search that +would return 100 bugs, setting C<limit> to 10 and C<offset> to 10 would return +bugs 11 through 20 from the set of 100. =item C<op_sys> |