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 {
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]>.
......
......@@ -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>
......
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