Commit db7cfa42 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 474715: Add 'limit', 'offset' and 'changed_since' arguments to WebService::Bug.search()

Patch By Kip Hampton <khampton@totalcinema.com> r=mkanat, a=mkanat
parent 4c70e508
...@@ -156,9 +156,29 @@ sub match { ...@@ -156,9 +156,29 @@ sub match {
return [$class->get_all] if !$criteria; return [$class->get_all] if !$criteria;
my (@terms, @values); my (@terms, @values, $postamble);
foreach my $field (keys %$criteria) { foreach my $field (keys %$criteria) {
my $value = $criteria->{$field}; 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') { if (ref $value eq 'ARRAY') {
# IN () is invalid SQL, and if we have an empty list # IN () is invalid SQL, and if we have an empty list
# to match against, we're just returning an empty # to match against, we're just returning an empty
...@@ -181,12 +201,12 @@ sub match { ...@@ -181,12 +201,12 @@ sub match {
} }
} }
my $where = join(' AND ', @terms); my $where = join(' AND ', @terms) if scalar @terms;
return $class->_do_list_select($where, \@values); return $class->_do_list_select($where, \@values, $postamble);
} }
sub _do_list_select { sub _do_list_select {
my ($class, $where, $values) = @_; my ($class, $where, $values, $postamble) = @_;
my $table = $class->DB_TABLE; my $table = $class->DB_TABLE;
my $cols = join(',', $class->DB_COLUMNS); my $cols = join(',', $class->DB_COLUMNS);
my $order = $class->LIST_ORDER; my $order = $class->LIST_ORDER;
...@@ -196,7 +216,9 @@ sub _do_list_select { ...@@ -196,7 +216,9 @@ sub _do_list_select {
$sql .= " WHERE $where "; $sql .= " WHERE $where ";
} }
$sql .= " ORDER BY $order"; $sql .= " ORDER BY $order";
$sql .= " $postamble" if $postamble;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @$values); my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @$values);
bless ($_, $class) foreach @$objects; bless ($_, $class) foreach @$objects;
...@@ -625,6 +647,26 @@ There are two special values, the constants C<NULL> and C<NOT_NULL>, ...@@ -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, which means "give me objects where this field is NULL or NOT NULL,
respectively." 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 If you don't specify any criteria, calling this function is the same
as doing C<[$class-E<gt>get_all]>. as doing C<[$class-E<gt>get_all]>.
......
...@@ -50,6 +50,8 @@ use constant FIELD_MAP => { ...@@ -50,6 +50,8 @@ use constant FIELD_MAP => {
summary => 'short_desc', summary => 'short_desc',
url => 'bug_file_loc', url => 'bug_file_loc',
whiteboard => 'status_whiteboard', whiteboard => 'status_whiteboard',
limit => 'LIMIT',
offset => 'OFFSET',
}; };
use constant PRODUCT_SPECIFIC_FIELDS => qw(version target_milestone component); use constant PRODUCT_SPECIFIC_FIELDS => qw(version target_milestone component);
...@@ -218,7 +220,21 @@ sub get_history { ...@@ -218,7 +220,21 @@ sub get_history {
sub search { sub search {
my ($self, $params) = @_; my ($self, $params) = @_;
if ( $params->{offset} and !$params->{limit} ) {
ThrowCodeError( 'param_required', { param => 'limit', function => 'Bug.search()'});
}
$params = _map_fields($params); $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 $bugs = Bugzilla::Bug->match($params);
my $visible = Bugzilla->user->visible_bugs($bugs); my $visible = Bugzilla->user->visible_bugs($bugs);
my @hashes = map { $self->_bug_to_hash($_) } @$visible; my @hashes = map { $self->_bug_to_hash($_) } @$visible;
...@@ -960,7 +976,21 @@ C<int> The numeric id of the bug. ...@@ -960,7 +976,21 @@ C<int> The numeric id of the bug.
=item C<last_change_time> =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> =item C<op_sys>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment