Merge pull request #2622 from froog/patch-1

Created LessThanOrEqualFilter and GreaterThanEqualFilter
This commit is contained in:
Ingo Schommer 2013-12-13 03:34:45 -08:00
commit ab91a5a80b
7 changed files with 168 additions and 69 deletions

View File

@ -272,7 +272,7 @@ This would be equivalent to a SQL query of
The where clauses showcased in the previous two sections (filter and exclude)
specify exact matches by default. However, there are a number of suffixes that
you can put on field names to change this behavior such as `":StartsWith"`,
`":EndsWith"`, `":PartialMatch"`, `":GreaterThan"`, `":LessThan"`,
`":EndsWith"`, `":PartialMatch"`, `":GreaterThan"`, `":GreaterThanOrEqual"`, `":LessThan"`, `":LessThanOrEqual"`,
`":Negation"`.
Each of these suffixes is represented in the ORM as a subclass of

View File

@ -0,0 +1,79 @@
<?php
/**
* Base class for creating comparison filters, eg; greater than, less than, greater than or equal, etc
*
* If you extend this abstract class, you must implement getOperator() and and getInverseOperator
*
* getOperator() should return a string operator that will be applied to the filter,
* eg; if getOperator() returns "<" then this will be a LessThan filter
*
* getInverseOperator() should return a string operator that evaluates the inverse of getOperator(),
* eg; if getOperator() returns "<", then the inverse should be ">=
*
* @package framework
* @subpackage search
*/
abstract class ComparisonFilter extends SearchFilter {
/**
* Should return an operator to be used for comparisons
*
* @return string Operator
*/
abstract protected function getOperator();
/**
* Should return an inverse operator to be used for comparisons
*
* @return string Inverse operator
*/
abstract protected function getInverseOperator();
/**
* Applies a comparison filter to the query
* Handles SQL escaping for both numeric and string values
*
* @param DataQuery $query
* @return $this|DataQuery
*/
protected function applyOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
if(is_numeric($value)) {
$filter = sprintf("%s %s %s",
$this->getDbName(), $this->getOperator(), Convert::raw2sql($value));
} else {
$filter = sprintf("%s %s '%s'",
$this->getDbName(), $this->getOperator(), Convert::raw2sql($value));
}
return $query->where($filter);
}
/**
* Applies a exclusion(inverse) filter to the query
* Handles SQL escaping for both numeric and string values
*
* @param DataQuery $query
* @return $this|DataQuery
*/
protected function excludeOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
if(is_numeric($value)) {
$filter = sprintf("%s %s %s",
$this->getDbName(), $this->getInverseOperator(), Convert::raw2sql($value));
} else {
$filter = sprintf("%s %s '%s'",
$this->getDbName(), $this->getInverseOperator(), Convert::raw2sql($value));
}
return $query->where($filter);
}
public function isEmpty() {
return $this->getValue() === array() || $this->getValue() === null || $this->getValue() === '';
}
}

38
search/filters/GreaterThanFilter.php Normal file → Executable file
View File

@ -2,40 +2,20 @@
/**
* Selects numerical/date content greater than the input
*
* @todo documentation
*
* Can be used by SearchContext and DataList->filter, eg;
* Model::get()->filter("Field1:GreaterThan", $value);
*
* @package framework
* @subpackage search
*/
class GreaterThanFilter extends SearchFilter {
/**
* @return DataQuery
*/
protected function applyOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
class GreaterThanFilter extends ComparisonFilter {
if(is_numeric($value)) $filter = sprintf("%s > %s", $this->getDbName(), Convert::raw2sql($value));
else $filter = sprintf("%s > '%s'", $this->getDbName(), Convert::raw2sql($value));
return $query->where($filter);
protected function getOperator() {
return ">";
}
/**
* @return DataQuery
*/
protected function excludeOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
protected function getInverseOperator() {
return "<=";
}
if(is_numeric($value)) $filter = sprintf("%s <= %s", $this->getDbName(), Convert::raw2sql($value));
else $filter = sprintf("%s <= '%s'", $this->getDbName(), Convert::raw2sql($value));
return $query->where($filter);
}
public function isEmpty() {
return $this->getValue() === array() || $this->getValue() === null || $this->getValue() === '';
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* Selects numerical/date content greater than or equal to the input
*
* Can be used by SearchContext and DataList->filter, eg;
* Model::get()->filter("Field1:GreaterThanOrEqual", $value);
*
* @package framework
* @subpackage search
*/
class GreaterThanOrEqualFilter extends ComparisonFilter {
protected function getOperator() {
return ">=";
}
protected function getInverseOperator() {
return "<";
}
}

40
search/filters/LessThanFilter.php Normal file → Executable file
View File

@ -1,41 +1,21 @@
<?php
/**
* Selects numerical/date content smaller than the input
* Selects numerical/date content less than the input
*
* Can be used by SearchContext and DataList->filter, eg;
* Model::get()->filter("Field1:LessThan", $value);
*
* @todo documentation
*
* @package framework
* @subpackage search
*/
class LessThanFilter extends SearchFilter {
/**
* @return DataQuery
*/
protected function applyOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
class LessThanFilter extends ComparisonFilter {
if(is_numeric($value)) $filter = sprintf("%s < %s", $this->getDbName(), Convert::raw2sql($value));
else $filter = sprintf("%s < '%s'", $this->getDbName(), Convert::raw2sql($value));
return $query->where($filter);
protected function getOperator() {
return "<";
}
/**
* @return DataQuery
*/
protected function excludeOne(DataQuery $query) {
$this->model = $query->applyRelation($this->relation);
$value = $this->getDbFormattedValue();
protected function getInverseOperator() {
return ">=";
}
if(is_numeric($value)) $filter = sprintf("%s >= %s", $this->getDbName(), Convert::raw2sql($value));
else $filter = sprintf("%s >= '%s'", $this->getDbName(), Convert::raw2sql($value));
return $query->where($filter);
}
public function isEmpty() {
return $this->getValue() === array() || $this->getValue() === null || $this->getValue() === '';
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* Selects numerical/date content less than or equal to the input
*
* Can be used by SearchContext and DataList->filter, eg;
* Model::get()->filter("Field1:LessThanOrEqual", $value);
*
* @package framework
* @subpackage search
*/
class LessThanOrEqualFilter extends ComparisonFilter {
protected function getOperator() {
return "<=";
}
protected function getInverseOperator() {
return ">";
}
}

36
tests/model/DataListTest.php Normal file → Executable file
View File

@ -445,17 +445,35 @@ class DataListTest extends SapphireTest {
$list = DataObjectTest_TeamComment::get();
$list = $list->filter('TeamID:GreaterThan', $this->idFromFixture('DataObjectTest_Team', 'team1'));
$this->assertEquals(1, $list->count());
$this->assertEquals('Phil', $list->first()->Name, 'First comment should be from Bob');
$this->assertEquals('Phil', $list->first()->Name, 'First comment should be from Phil');
}
// public function testSimpleFilterLessThanFilter() {
// $list = DataObjectTest_TeamComment::get();
// $list = $list->filter('TeamID:LessThan',
// $this->idFromFixture('DataObjectTest_TeamComment', 'comment2'))->sort('Name');
// $this->assertEquals(2, $list->count());
// $this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
// $this->assertEquals('Joe', $list->Last()->Name, 'Last comment should be from Joe');
// }
public function testSimpleFilterGreaterThanOrEqualFilter() {
$list = DataObjectTest_TeamComment::get();
$list = $list->filter('TeamID:GreaterThanOrEqual',
$this->idFromFixture('DataObjectTest_Team', 'team1'))->sort("ID");
$this->assertEquals(3, $list->count());
$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
}
public function testSimpleFilterLessThanFilter() {
$list = DataObjectTest_TeamComment::get();
$list = $list->filter('TeamID:LessThan',
$this->idFromFixture('DataObjectTest_Team', 'team2'))->sort('Name');
$this->assertEquals(2, $list->count());
$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
$this->assertEquals('Joe', $list->Last()->Name, 'Last comment should be from Joe');
}
public function testSimpleFilterLessThanOrEqualFilter() {
$list = DataObjectTest_TeamComment::get();
$list = $list->filter('TeamID:LessThanOrEqual',
$this->idFromFixture('DataObjectTest_Team', 'team1'))->sort('ID');
$this->assertEquals(2, $list->count());
$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
$this->assertEquals('Bob', $list->Last()->Name, 'Last comment should be from Bob');
}
public function testSimplePartialMatchFilter() {
$list = DataObjectTest_TeamComment::get();