silverstripe-framework/tests/model/DataQueryTest.php
torleif 75ec0c4791 Added tests that check comparisonClause()
AS requested by tractorcow: https://github.com/silverstripe/silverstripe-postgresql/pull/26

Tested on MySQL (succeeds as expected)  Tested on PostgreSQL (and fails as expected, but passes with patch). The fixes test only DataQueryTest related items for consistency, e.g. by avoiding DataObject calls.
2014-09-26 12:11:33 +12:00

294 lines
9.1 KiB
PHP

<?php
class DataQueryTest extends SapphireTest {
protected static $fixture_file = 'DataQueryTest.yml';
protected $extraDataObjects = array(
'DataQueryTest_A',
'DataQueryTest_B',
'DataQueryTest_C',
'DataQueryTest_D',
'DataQueryTest_E',
'DataQueryTest_F',
);
public function testSortByJoinedFieldRetainsSourceInformation() {
$bar = new DataQueryTest_C();
$bar->Title = "Bar";
$bar->write();
$foo = new DataQueryTest_B();
$foo->Title = "Foo";
$foo->TestC = $bar->ID;
$foo->write();
$query = new DataQuery('DataQueryTest_B');
$result = $query->leftJoin(
'DataQueryTest_C',
"\"DataQueryTest_B\".\"TestCID\" = \"DataQueryTest_B\".\"ID\""
)->sort('"DataQueryTest_B"."Title"', 'ASC');
$result = $result->execute()->record();
$this->assertEquals('Foo', $result['Title']);
}
/**
* Test the leftJoin() and innerJoin method of the DataQuery object
*/
public function testJoins() {
$dq = new DataQuery('Member');
$dq->innerJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
$this->assertContains("INNER JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"",
$dq->sql());
$dq = new DataQuery('Member');
$dq->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
$this->assertContains("LEFT JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"",
$dq->sql());
}
public function testRelationReturn() {
$dq = new DataQuery('DataQueryTest_C');
$this->assertEquals('DataQueryTest_A', $dq->applyRelation('TestA'),
'DataQuery::applyRelation should return the name of the related object.');
$this->assertEquals('DataQueryTest_A', $dq->applyRelation('TestAs'),
'DataQuery::applyRelation should return the name of the related object.');
$this->assertEquals('DataQueryTest_A', $dq->applyRelation('ManyTestAs'),
'DataQuery::applyRelation should return the name of the related object.');
$this->assertEquals('DataQueryTest_B', $dq->applyRelation('TestB'),
'DataQuery::applyRelation should return the name of the related object.');
$this->assertEquals('DataQueryTest_B', $dq->applyRelation('TestBs'),
'DataQuery::applyRelation should return the name of the related object.');
$this->assertEquals('DataQueryTest_B', $dq->applyRelation('ManyTestBs'),
'DataQuery::applyRelation should return the name of the related object.');
}
public function testRelationOrderWithCustomJoin() {
$dataQuery = new DataQuery('DataQueryTest_B');
$dataQuery->innerJoin('DataQueryTest_D', '"DataQueryTest_D"."RelationID" = "DataQueryTest_B"."ID"');
$dataQuery->execute();
}
public function testDisjunctiveGroup() {
$dq = new DataQuery('DataQueryTest_A');
$dq->where('DataQueryTest_A.ID = 2');
$subDq = $dq->disjunctiveGroup();
$subDq->where('DataQueryTest_A.Name = \'John\'');
$subDq->where('DataQueryTest_A.Name = \'Bob\'');
$this->assertContains(
"WHERE (DataQueryTest_A.ID = 2) AND ((DataQueryTest_A.Name = 'John') OR (DataQueryTest_A.Name = 'Bob'))",
$dq->sql()
);
}
public function testConjunctiveGroup() {
$dq = new DataQuery('DataQueryTest_A');
$dq->where('DataQueryTest_A.ID = 2');
$subDq = $dq->conjunctiveGroup();
$subDq->where('DataQueryTest_A.Name = \'John\'');
$subDq->where('DataQueryTest_A.Name = \'Bob\'');
$this->assertContains(
"WHERE (DataQueryTest_A.ID = 2) AND ((DataQueryTest_A.Name = 'John') AND (DataQueryTest_A.Name = 'Bob'))",
$dq->sql()
);
}
public function testNestedGroups() {
$dq = new DataQuery('DataQueryTest_A');
$dq->where('DataQueryTest_A.ID = 2');
$subDq = $dq->disjunctiveGroup();
$subDq->where('DataQueryTest_A.Name = \'John\'');
$subSubDq = $subDq->conjunctiveGroup();
$subSubDq->where('DataQueryTest_A.Age = 18');
$subSubDq->where('DataQueryTest_A.Age = 50');
$subDq->where('DataQueryTest_A.Name = \'Bob\'');
$this->assertContains(
"WHERE (DataQueryTest_A.ID = 2) AND ((DataQueryTest_A.Name = 'John') OR ((DataQueryTest_A.Age = 18) "
. "AND (DataQueryTest_A.Age = 50)) OR (DataQueryTest_A.Name = 'Bob'))",
$dq->sql()
);
}
public function testEmptySubgroup() {
$dq = new DataQuery('DataQueryTest_A');
$dq->conjunctiveGroup();
$this->assertContains('WHERE (1=1)', $dq->sql());
}
public function testSubgroupHandoff() {
$dq = new DataQuery('DataQueryTest_A');
$subDq = $dq->disjunctiveGroup();
$orgDq = clone $dq;
$subDq->sort('"DataQueryTest_A"."Name"');
$orgDq->sort('"DataQueryTest_A"."Name"');
$this->assertEquals($dq->sql(), $orgDq->sql());
$subDq->limit(5, 7);
$orgDq->limit(5, 7);
$this->assertEquals($dq->sql(), $orgDq->sql());
}
public function testOrderByMultiple() {
$dq = new DataQuery('SQLQueryTest_DO');
$dq = $dq->sort('"Name" ASC, MID("Name", 8, 1) DESC');
$this->assertContains(
'ORDER BY "Name" ASC, "_SortColumn0" DESC',
$dq->sql()
);
}
public function testDefaultSort() {
$query = new DataQuery('DataQueryTest_E');
$result = $query->column('Title');
$this->assertEquals(array('First', 'Second', 'Last'), $result);
}
public function testDistinct() {
$query = new DataQuery('DataQueryTest_E');
$this->assertContains('SELECT DISTINCT', $query->sql(), 'Query is set as distinct by default');
$query = $query->distinct(false);
$this->assertNotContains('SELECT DISTINCT', $query->sql(), 'Query does not contain distinct');
$query = $query->distinct(true);
$this->assertContains('SELECT DISTINCT', $query->sql(), 'Query contains distinct');
}
public function testComparisonClauseInt() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"SortOrder\") VALUES (2)");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"SortOrder"', '2'));
$this->assertGreaterThan(0, $query->count(), "Couldn't find SortOrder");
$this->resetDBSchema(true);
}
public function testComparisonClauseDateFull() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"MyDate\") VALUES ('1988-03-04 06:30')");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"MyDate"', '1988-03-04%'));
$this->assertGreaterThan(0, $query->count(), "Couldn't find MyDate");
$this->resetDBSchema(true);
}
public function testComparisonClauseDateStartsWith() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"MyDate\") VALUES ('1988-03-04 06:30')");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"MyDate"', '1988%'));
$this->assertGreaterThan(0, $query->count(), "Couldn't find MyDate");
$this->resetDBSchema(true);
}
public function testComparisonClauseDateStartsPartial() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"MyDate\") VALUES ('1988-03-04 06:30')");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"MyDate"', '%03-04%'));
$this->assertGreaterThan(0, $query->count(), "Couldn't find MyDate");
$this->resetDBSchema(true);
}
public function testComparisonClauseTextCaseInsensitive() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"MyString\") VALUES ('HelloWorld')");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"MyString"', 'helloworld'));
$this->assertGreaterThan(0, $query->count(), "Couldn't find MyString");
$this->resetDBSchema(true);
}
public function testComparisonClauseTextCaseSensitive() {
DB::query("INSERT INTO \"DataQueryTest_F\" (\"MyString\") VALUES ('HelloWorld')");
$query = new DataQuery('DataQueryTest_F');
$query->where(DB::getConn()->comparisonClause('"MyString"', 'HelloWorld', false, false, true));
$this->assertGreaterThan(0, $query->count(), "Couldn't find MyString");
$query2 = new DataQuery('DataQueryTest_F');
$query2->where(DB::getConn()->comparisonClause('"MyString"', 'helloworld', false, false, true));
$this->assertEquals(0, $query2->count(), "Found mystring. Shouldn't be able too.");
$this->resetDBSchema(true);
}
}
class DataQueryTest_A extends DataObject implements TestOnly {
private static $db = array(
'Name' => 'Varchar',
);
private static $has_one = array(
'TestC' => 'DataQueryTest_C',
);
}
class DataQueryTest_B extends DataObject implements TestOnly {
private static $db = array(
'Title' => 'Varchar',
);
private static $has_one = array(
'TestC' => 'DataQueryTest_C',
);
}
class DataQueryTest_C extends DataObject implements TestOnly {
private static $db = array(
'Title' => 'Varchar'
);
private static $has_one = array(
'TestA' => 'DataQueryTest_A',
'TestB' => 'DataQueryTest_B',
);
private static $has_many = array(
'TestAs' => 'DataQueryTest_A',
'TestBs' => 'DataQueryTest_B',
);
private static $many_many = array(
'ManyTestAs' => 'DataQueryTest_A',
'ManyTestBs' => 'DataQueryTest_B',
);
}
class DataQueryTest_D extends DataObject implements TestOnly {
private static $has_one = array(
'Relation' => 'DataQueryTest_B',
);
}
class DataQueryTest_E extends DataQueryTest_C implements TestOnly {
private static $db = array(
'SortOrder' => 'Int'
);
private static $default_sort = '"DataQueryTest_E"."SortOrder" ASC';
}
class DataQueryTest_F extends DataObject implements TestOnly {
private static $db = array(
'SortOrder' => 'Int',
'MyDate' => 'SS_Datetime',
'MyString' => 'Text'
);
}