From f2064a6bf8388e7c1437ee2a57205e9c0fe16a55 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Sun, 21 Sep 2008 22:38:22 +0000 Subject: [PATCH] added constraint based searches to getAll() methods --- lib/WebGUI/Crud.pm | 79 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/lib/WebGUI/Crud.pm b/lib/WebGUI/Crud.pm index bce1b0fdd..e1cdf69db 100644 --- a/lib/WebGUI/Crud.pm +++ b/lib/WebGUI/Crud.pm @@ -522,13 +522,17 @@ A class method that returns a list of all the ids in this object type. Has the s =cut sub getAllIds { - my ($class, $session, $options) = @_; - my @objects; - my @params; - if ($options->{sequenceKeyValue}) { - push @params, $options->{sequenceKeyValue}; + my ($class, $someObject, $options) = @_; + + # dynamic recognition of object or session + my $session = $someObject; + unless ($session->isa('WebGUI::Session')) { + $session = $someObject->session; } - my $ids = $session->db->read($class->getAllSql($session, $options, @_), \@params); + + # generate the array + my @objects; + my $ids = $session->db->read($class->getAllSql($session, $options, @_)); while (my ($id) = $ids->array) { push @objects, $id; } @@ -544,13 +548,20 @@ A class method that returns an iterator of all the instanciated objects in this =cut sub getAllIterator { - my ($class, $session, $options) = @_; + my ($class, $someObject, $options) = @_; + + # dynamic recognition of object or session + my $session = $someObject; + unless ($session->isa('WebGUI::Session')) { + $session = $someObject->session; + } + my @objects; my $ids = $class->getAllIds($session, $options, @_); my $sub = sub { my ($id) = shift @{$ids}; return if !$id; - my $object = $class->new($session, $id); + my $object = $class->new($someObject, $id); if (!$object) { WebGUI::Error::ObjectNotFound->throw(error=>'no such '.$class->getTableKey, id => $id); } @@ -563,16 +574,27 @@ sub getAllIterator { =head2 getAllSql ( session, [ options ] ) -A class method that returns the SQL necessary to retrieve all of the records for this object. +A class method that returns two values. The first is the SQL necessary to retrieve all of the records for this object. The second is an array reference with the placeholder parameters needed to execute the SQL. =head3 session -A reference to a WebGUI::Session. +A reference to a WebGUI::Session or an object that has a session method. If it's an object that has a session method, then this object will be passed to new() instead of session as well. This is useful when you are creating WebGUI::Crud subclasses that require another object to function. =head3 options A hash reference of optional rules to modify the returned results. +=head4 constraints + +An array reference of hash references. Each hash reference should contain a where clause as the key complete with place holders (?) and a scalar or an array reference as it's value or values. Each where clause should be written using ANSI SQL. Each where clause will be anded together with any other where clauses that are generated by this API, and the "where" statement will be prepended to that. + +Here's an example of this structure: + + [ + { "price <= ?" => 44 }, + { "color=? or color=?" => ['blue','black'] }, + ] + =head4 limit Either an integer representing the number of records to return, or an array reference of an integer of the starting record position and another integer representing the number of records to return. @@ -588,27 +610,49 @@ If specified will limit the query to a specific sequence identified by this sequ =cut sub getAllSql { - my ($class, $session, $options) = @_; + my ($class, $someObject, $options) = @_; + + # dynamic recognition of object or session + my $session = $someObject; + unless ($session->isa('WebGUI::Session')) { + $session = $someObject->session; + } my $dbh = $session->db->dbh; - my @where; - my $limit; - my $order = " order by sequenceNumber"; # the base query my $sql = "select ".$dbh->quote_identifier($class->crud_getTableKey($session))." from ".$dbh->quote_identifier($class->crud_getTableName($session)); + # process constraints + my @params; + my @where; + if (exists $options->{constraints}) { + foreach my $constraint (@{$options->{constraints}}) { + my ($clause) = keys %{$constraint}; + push @where, "(".$clause.")"; + my $value = $constraint->{$clause}; + if (ref $value eq 'ARRAY') { + @params = (@params, @{$value}); + } + else { + push @params, $value; + } + } + } + # limit to our sequence my $sequenceKey = $class->crud_getSequenceKey($session); - if ($options->{sequenceKeyValue} && $sequenceKey) { + if (exists $options->{sequenceKeyValue} && $sequenceKey) { + push @params, $options->{sequenceKeyValue}; push @where, $dbh->quote_identifier($sequenceKey)."=?"; } # merge all clauses with the main query if (scalar(@where)) { - $sql .= join(" AND ", @where); + $sql .= " where ".join(" AND ", @where); } # construct a record limit + my $limit; if ( exists $options->{limit}) { if (ref $options->{limit} eq "ARRAY") { $limit = " limit ".$options->{limit}[0].",".$options->{limit}[1]; @@ -619,11 +663,12 @@ sub getAllSql { } # custom order by field + my $order = " order by sequenceNumber"; if (exists $options->{orderBy}) { $order = " order by ".$dbh->quote_identifier($options->{orderBy}); } - return $sql . $order . $limit; + return $sql . $order . $limit, \ @params; } #-------------------------------------------------------------------