2008-08-09 06:38:44 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class SQLQueryTest extends SapphireTest {
|
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
protected static $fixture_file = 'SQLQueryTest.yml';
|
2010-04-12 04:03:16 +02:00
|
|
|
|
|
|
|
protected $extraDataObjects = array(
|
|
|
|
'SQLQueryTest_DO',
|
|
|
|
);
|
2015-05-07 19:55:37 +02:00
|
|
|
|
|
|
|
public function testCount() {
|
|
|
|
|
|
|
|
//basic counting
|
|
|
|
$qry = SQLQueryTest_DO::get()->dataQuery()->getFinalisedQuery();
|
|
|
|
$qry->setGroupBy('Common');
|
|
|
|
$ids = $this->allFixtureIDs('SQLQueryTest_DO');
|
|
|
|
$this->assertEquals(count($ids), $qry->count('"SQLQueryTest_DO"."ID"'));
|
|
|
|
|
|
|
|
//test with `having`
|
|
|
|
if (DB::getConn() instanceof MySQLDatabase) {
|
|
|
|
$qry->setHaving('"Date" > 2012-02-01');
|
|
|
|
$this->assertEquals(1, $qry->count('"SQLQueryTest_DO"."ID"'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testEmptyQueryReturnsNothing() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
|
|
|
$this->assertEquals('', $query->sql());
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectFromBasicTable() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom('MyTable');
|
2008-08-09 06:38:44 +02:00
|
|
|
$this->assertEquals("SELECT * FROM MyTable", $query->sql());
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->addFrom('MyJoin');
|
2008-08-09 06:53:34 +02:00
|
|
|
$this->assertEquals("SELECT * FROM MyTable MyJoin", $query->sql());
|
2008-08-09 06:38:44 +02:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectFromUserSpecifiedFields() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setSelect(array("Name", "Title", "Description"));
|
|
|
|
$query->setFrom("MyTable");
|
2008-08-09 06:38:44 +02:00
|
|
|
$this->assertEquals("SELECT Name, Title, Description FROM MyTable", $query->sql());
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithWhereClauseFilter() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setSelect(array("Name","Meta"));
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setWhere("Name = 'Name'");
|
|
|
|
$query->addWhere("Meta = 'Test'");
|
2008-08-09 06:38:44 +02:00
|
|
|
$this->assertEquals("SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')", $query->sql());
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithConstructorParameters() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery(array("Foo", "Bar"), "FooBarTable");
|
|
|
|
$this->assertEquals("SELECT Foo, Bar FROM FooBarTable", $query->sql());
|
|
|
|
$query = new SQLQuery(array("Foo", "Bar"), "FooBarTable", array("Foo = 'Boo'"));
|
|
|
|
$this->assertEquals("SELECT Foo, Bar FROM FooBarTable WHERE (Foo = 'Boo')", $query->sql());
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithChainedMethods() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'");
|
2008-08-09 06:38:44 +02:00
|
|
|
$this->assertEquals("SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')", $query->sql());
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testCanSortBy() {
|
2010-04-13 04:16:50 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'");
|
2010-04-13 04:16:50 +02:00
|
|
|
$this->assertTrue($query->canSortBy('Name ASC'));
|
|
|
|
$this->assertTrue($query->canSortBy('Name'));
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithChainedFilterParameters() {
|
2008-08-09 06:38:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setSelect(array("Name","Meta"))->setFrom("MyTable");
|
|
|
|
$query->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'")->addWhere("Beta != 'Gamma'");
|
2012-09-26 23:34:00 +02:00
|
|
|
$this->assertEquals(
|
|
|
|
"SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test') AND (Beta != 'Gamma')",
|
|
|
|
$query->sql());
|
2008-08-09 06:38:44 +02:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithLimitClause() {
|
2012-09-26 23:34:00 +02:00
|
|
|
if(!(DB::getConn() instanceof MySQLDatabase || DB::getConn() instanceof SQLite3Database
|
|
|
|
|| DB::getConn() instanceof PostgreSQLDatabase)) {
|
2012-05-03 09:34:16 +02:00
|
|
|
$this->markTestIncomplete();
|
2009-06-16 07:33:03 +02:00
|
|
|
}
|
2012-05-03 09:34:16 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setLimit(99);
|
|
|
|
$this->assertEquals("SELECT * FROM MyTable LIMIT 99", $query->sql());
|
|
|
|
|
|
|
|
// array limit with start (MySQL specific)
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setLimit(99, 97);
|
|
|
|
$this->assertEquals("SELECT * FROM MyTable LIMIT 99 OFFSET 97", $query->sql());
|
2008-08-09 07:57:44 +02:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testSelectWithOrderbyClause() {
|
2008-08-09 07:57:44 +02:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('MyName');
|
2012-05-01 07:09:57 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName ASC', $query->sql());
|
2008-08-09 07:57:44 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('MyName desc');
|
2012-04-15 10:34:10 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql());
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('MyName ASC, Color DESC');
|
2012-04-15 10:34:10 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color DESC', $query->sql());
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('MyName ASC, Color');
|
2012-05-01 07:09:57 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color ASC', $query->sql());
|
2008-08-09 07:57:44 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy(array('MyName' => 'desc'));
|
2012-04-15 10:34:10 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql());
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy(array('MyName' => 'desc', 'Color'));
|
2012-05-01 07:09:57 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY MyName DESC, Color ASC', $query->sql());
|
2012-04-15 10:34:10 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('implode("MyName","Color")');
|
2012-09-26 23:34:00 +02:00
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
|
|
|
|
$query->sql());
|
2012-04-15 10:34:10 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('implode("MyName","Color") DESC');
|
2012-09-26 23:34:00 +02:00
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" DESC',
|
|
|
|
$query->sql());
|
2012-04-15 10:34:10 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setOrderBy('RAND()');
|
2012-09-26 23:34:00 +02:00
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT *, RAND() AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
|
|
|
|
$query->sql());
|
2013-09-17 22:06:39 +02:00
|
|
|
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->addFrom('INNER JOIN SecondTable USING (ID)');
|
|
|
|
$query->addFrom('INNER JOIN ThirdTable USING (ID)');
|
|
|
|
$query->setOrderBy('MyName');
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT * FROM MyTable '
|
|
|
|
. 'INNER JOIN SecondTable USING (ID) '
|
|
|
|
. 'INNER JOIN ThirdTable USING (ID) '
|
|
|
|
. 'ORDER BY MyName ASC',
|
|
|
|
$query->sql());
|
2008-08-09 06:38:44 +02:00
|
|
|
}
|
2012-06-29 09:40:28 +02:00
|
|
|
|
2013-06-06 15:18:01 +02:00
|
|
|
public function testNullLimit() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setLimit(null);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT * FROM MyTable',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testZeroLimit() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setLimit(0);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT * FROM MyTable',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testZeroLimitWithOffset() {
|
2013-09-13 05:50:36 +02:00
|
|
|
if(!(DB::getConn() instanceof MySQLDatabase || DB::getConn() instanceof SQLite3Database
|
|
|
|
|| DB::getConn() instanceof PostgreSQLDatabase)) {
|
|
|
|
$this->markTestIncomplete();
|
|
|
|
}
|
|
|
|
|
2013-06-06 15:18:01 +02:00
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom("MyTable");
|
|
|
|
$query->setLimit(0, 99);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT * FROM MyTable LIMIT 0 OFFSET 99',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-06-29 09:40:28 +02:00
|
|
|
/**
|
|
|
|
* @expectedException InvalidArgumentException
|
|
|
|
*/
|
|
|
|
public function testNegativeLimit() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setLimit(-10);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException InvalidArgumentException
|
|
|
|
*/
|
|
|
|
public function testNegativeOffset() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setLimit(1, -10);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException InvalidArgumentException
|
|
|
|
*/
|
|
|
|
public function testNegativeOffsetAndLimit() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setLimit(-10, -10);
|
|
|
|
}
|
|
|
|
|
2012-04-15 10:34:10 +02:00
|
|
|
public function testReverseOrderBy() {
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom('MyTable');
|
2012-04-15 10:34:10 +02:00
|
|
|
|
|
|
|
// default is ASC
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setOrderBy("Name");
|
2012-04-15 10:34:10 +02:00
|
|
|
$query->reverseOrderBy();
|
|
|
|
|
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql());
|
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setOrderBy("Name DESC");
|
2012-04-15 10:34:10 +02:00
|
|
|
$query->reverseOrderBy();
|
|
|
|
|
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY Name ASC',$query->sql());
|
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setOrderBy(array("Name" => "ASC"));
|
2012-04-15 10:34:10 +02:00
|
|
|
$query->reverseOrderBy();
|
|
|
|
|
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql());
|
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setOrderBy(array("Name" => 'DESC', 'Color' => 'asc'));
|
2012-04-15 10:34:10 +02:00
|
|
|
$query->reverseOrderBy();
|
|
|
|
|
|
|
|
$this->assertEquals('SELECT * FROM MyTable ORDER BY Name ASC, Color DESC',$query->sql());
|
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setOrderBy('implode("MyName","Color") DESC');
|
2012-04-15 10:34:10 +02:00
|
|
|
$query->reverseOrderBy();
|
|
|
|
|
2012-09-26 23:34:00 +02:00
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
|
|
|
|
$query->sql());
|
2008-08-09 07:57:44 +02:00
|
|
|
}
|
2012-04-15 10:34:10 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testFiltersOnID() {
|
2009-01-10 12:35:50 +01:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("ID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is true with simple unquoted column name"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("ID=5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is true with simple unquoted column name and no spaces in equals sign"
|
|
|
|
);
|
2012-05-03 09:34:16 +02:00
|
|
|
|
2009-01-10 12:35:50 +01:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("Identifier = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertFalse(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is false with custom column name (starting with 'id')"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("ParentID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertFalse(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is false with column name ending in 'ID'"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("MyTable.ID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is true with table and column name"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("MyTable.ID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnID(),
|
|
|
|
"filtersOnID() is true with table and quoted column name "
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function testFiltersOnFK() {
|
2009-01-10 12:35:50 +01:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("ID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertFalse(
|
|
|
|
$query->filtersOnFK(),
|
|
|
|
"filtersOnFK() is true with simple unquoted column name"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("Identifier = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertFalse(
|
|
|
|
$query->filtersOnFK(),
|
|
|
|
"filtersOnFK() is false with custom column name (starting with 'id')"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("MyTable.ParentID = 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnFK(),
|
|
|
|
"filtersOnFK() is true with table and column name"
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setWhere("MyTable.`ParentID`= 5");
|
2009-01-10 12:35:50 +01:00
|
|
|
$this->assertTrue(
|
|
|
|
$query->filtersOnFK(),
|
|
|
|
"filtersOnFK() is true with table and quoted column name "
|
|
|
|
);
|
|
|
|
}
|
2010-10-19 00:58:43 +02:00
|
|
|
|
|
|
|
public function testInnerJoin() {
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom('MyTable');
|
|
|
|
$query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2');
|
|
|
|
$query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID');
|
2010-10-19 00:58:43 +02:00
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable '.
|
2011-10-29 06:06:42 +02:00
|
|
|
'INNER JOIN "MyOtherTable" ON MyOtherTable.ID = 2 '.
|
|
|
|
'LEFT JOIN "MyLastTable" ON MyOtherTable.ID = MyLastTable.ID',
|
2010-10-19 00:58:43 +02:00
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom('MyTable');
|
|
|
|
$query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2', 'table1');
|
|
|
|
$query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID', 'table2');
|
2010-10-19 00:58:43 +02:00
|
|
|
|
2012-05-03 09:34:16 +02:00
|
|
|
$this->assertEquals('SELECT * FROM MyTable '.
|
2010-10-19 00:58:43 +02:00
|
|
|
'INNER JOIN "MyOtherTable" AS "table1" ON MyOtherTable.ID = 2 '.
|
|
|
|
'LEFT JOIN "MyLastTable" AS "table2" ON MyOtherTable.ID = MyLastTable.ID',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
}
|
2015-03-18 04:09:09 +01:00
|
|
|
|
2014-07-17 03:27:28 +02:00
|
|
|
public function testJoinSubSelect() {
|
|
|
|
|
2015-03-18 04:09:09 +01:00
|
|
|
// Test sub-select works
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"MyTable"');
|
|
|
|
$query->addInnerJoin('(SELECT * FROM "MyOtherTable")',
|
|
|
|
'"Mot"."MyTableID" = "MyTable"."ID"', 'Mot');
|
|
|
|
$query->addLeftJoin('(SELECT "MyLastTable"."MyOtherTableID", COUNT(1) as "MyLastTableCount" '
|
|
|
|
. 'FROM "MyLastTable" GROUP BY "MyOtherTableID")',
|
|
|
|
'"Mlt"."MyOtherTableID" = "Mot"."ID"', 'Mlt');
|
|
|
|
$query->setOrderBy('COALESCE("Mlt"."MyLastTableCount", 0) DESC');
|
2014-07-17 03:27:28 +02:00
|
|
|
|
2015-03-18 04:09:09 +01:00
|
|
|
$this->assertEquals('SELECT *, COALESCE("Mlt"."MyLastTableCount", 0) AS "_SortColumn0" FROM "MyTable" '.
|
|
|
|
'INNER JOIN (SELECT * FROM "MyOtherTable") AS "Mot" ON "Mot"."MyTableID" = "MyTable"."ID" ' .
|
|
|
|
'LEFT JOIN (SELECT "MyLastTable"."MyOtherTableID", COUNT(1) as "MyLastTableCount" FROM "MyLastTable" '
|
|
|
|
. 'GROUP BY "MyOtherTableID") AS "Mlt" ON "Mlt"."MyOtherTableID" = "Mot"."ID" ' .
|
2014-07-17 03:27:28 +02:00
|
|
|
'ORDER BY "_SortColumn0" DESC',
|
2015-03-18 04:09:09 +01:00
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Test that table names do not get mistakenly identified as sub-selects
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"MyTable"');
|
|
|
|
$query->addInnerJoin('NewsArticleSelected', '"News"."MyTableID" = "MyTable"."ID"', 'News');
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT * FROM "MyTable" INNER JOIN "NewsArticleSelected" AS "News" ON '.
|
|
|
|
'"News"."MyTableID" = "MyTable"."ID"',
|
2014-07-17 03:27:28 +02:00
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-06-22 04:34:06 +02:00
|
|
|
public function testSetWhereAny() {
|
2011-12-09 14:09:07 +01:00
|
|
|
$query = new SQLQuery();
|
2012-05-03 09:34:16 +02:00
|
|
|
$query->setFrom('MyTable');
|
2011-12-09 14:09:07 +01:00
|
|
|
|
2012-06-22 04:34:06 +02:00
|
|
|
$query->setWhereAny(array("Monkey = 'Chimp'", "Color = 'Brown'"));
|
2011-12-09 14:09:07 +01:00
|
|
|
$this->assertEquals("SELECT * FROM MyTable WHERE (Monkey = 'Chimp' OR Color = 'Brown')",$query->sql());
|
|
|
|
}
|
2012-11-16 01:27:51 +01:00
|
|
|
|
|
|
|
public function testSelectFirst() {
|
|
|
|
// Test first from sequence
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$result = $query->firstRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
2012-11-16 01:27:51 +01:00
|
|
|
foreach($result as $row) {
|
2014-02-10 01:32:39 +01:00
|
|
|
$records[] = $row;
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$this->assertCount(1, $records);
|
|
|
|
$this->assertEquals('Object 1', $records[0]['Name']);
|
|
|
|
|
2012-11-16 01:27:51 +01:00
|
|
|
// Test first from empty sequence
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
|
|
|
$result = $query->firstRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
|
|
|
foreach($result as $row) {
|
|
|
|
$records[] = $row;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertCount(0, $records);
|
2012-11-16 01:27:51 +01:00
|
|
|
|
|
|
|
// Test that given the last item, the 'first' in this list matches the last
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$query->setLimit(1, 1);
|
|
|
|
$result = $query->firstRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
2012-11-16 01:27:51 +01:00
|
|
|
foreach($result as $row) {
|
2014-02-10 01:32:39 +01:00
|
|
|
$records[] = $row;
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$this->assertCount(1, $records);
|
|
|
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSelectLast() {
|
|
|
|
// Test last in sequence
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$result = $query->lastRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
2012-11-16 01:27:51 +01:00
|
|
|
foreach($result as $row) {
|
2014-02-10 01:32:39 +01:00
|
|
|
$records[] = $row;
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$this->assertCount(1, $records);
|
|
|
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
2012-11-16 01:27:51 +01:00
|
|
|
|
|
|
|
// Test last from empty sequence
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
|
|
|
$result = $query->lastRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
|
|
|
foreach($result as $row) {
|
|
|
|
$records[] = $row;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertCount(0, $records);
|
|
|
|
|
2012-11-16 01:27:51 +01:00
|
|
|
// Test that given the first item, the 'last' in this list matches the first
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('"Name"');
|
|
|
|
$query->setLimit(1);
|
|
|
|
$result = $query->lastRow()->execute();
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$records = array();
|
2012-11-16 01:27:51 +01:00
|
|
|
foreach($result as $row) {
|
2014-02-10 01:32:39 +01:00
|
|
|
$records[] = $row;
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
2014-02-10 01:32:39 +01:00
|
|
|
|
|
|
|
$this->assertCount(1, $records);
|
|
|
|
$this->assertEquals('Object 1', $records[0]['Name']);
|
2012-11-16 01:27:51 +01:00
|
|
|
}
|
2014-02-10 01:32:39 +01:00
|
|
|
|
2012-12-20 14:04:22 +01:00
|
|
|
/**
|
|
|
|
* Tests aggregate() function
|
|
|
|
*/
|
|
|
|
public function testAggregate() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
2013-03-28 18:17:43 +01:00
|
|
|
$query->setGroupBy('"Common"');
|
2012-12-20 14:04:22 +01:00
|
|
|
|
|
|
|
$queryClone = $query->aggregate('COUNT(*)', 'cnt');
|
|
|
|
$result = $queryClone->execute();
|
|
|
|
$this->assertEquals(array(2), $result->column('cnt'));
|
|
|
|
}
|
2012-05-03 09:34:16 +02:00
|
|
|
|
2013-09-06 08:01:52 +02:00
|
|
|
/**
|
|
|
|
* Tests that an ORDER BY is only added if a LIMIT is set.
|
|
|
|
*/
|
|
|
|
public function testAggregateNoOrderByIfNoLimit() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('Common');
|
|
|
|
$query->setLimit(array());
|
|
|
|
|
|
|
|
$aggregate = $query->aggregate('MAX("ID")');
|
|
|
|
$limit = $aggregate->getLimit();
|
|
|
|
$this->assertEquals(array(), $aggregate->getOrderBy());
|
|
|
|
$this->assertEquals(array(), $limit);
|
|
|
|
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy('Common');
|
|
|
|
$query->setLimit(2);
|
|
|
|
|
|
|
|
$aggregate = $query->aggregate('MAX("ID")');
|
|
|
|
$limit = $aggregate->getLimit();
|
|
|
|
$this->assertEquals(array('Common' => 'ASC'), $aggregate->getOrderBy());
|
|
|
|
$this->assertEquals(array('start' => 0, 'limit' => 2), $limit);
|
|
|
|
}
|
|
|
|
|
2012-12-20 03:52:46 +01:00
|
|
|
/**
|
|
|
|
* Test that "_SortColumn0" is added for an aggregate in the ORDER BY
|
|
|
|
* clause, in combination with a LIMIT and GROUP BY clause.
|
|
|
|
* For some databases, like MSSQL, this is a complicated scenario
|
|
|
|
* because a subselect needs to be done to query paginated data.
|
|
|
|
*/
|
|
|
|
public function testOrderByContainingAggregateAndLimitOffset() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setSelect(array('"Name"', '"Meta"'));
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
2013-04-02 12:07:41 +02:00
|
|
|
$query->setOrderBy(array('MAX("Date")'));
|
2012-12-20 03:52:46 +01:00
|
|
|
$query->setGroupBy(array('"Name"', '"Meta"'));
|
|
|
|
$query->setLimit('1', '1');
|
|
|
|
|
|
|
|
$records = array();
|
|
|
|
foreach($query->execute() as $record) {
|
|
|
|
$records[] = $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertCount(1, $records);
|
|
|
|
|
|
|
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
|
|
|
$this->assertEquals('2012-05-01 09:00:00', $records['0']['_SortColumn0']);
|
|
|
|
}
|
2013-10-03 03:20:31 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Test that multiple order elements are maintained in the given order
|
|
|
|
*/
|
|
|
|
public function testOrderByMultiple() {
|
|
|
|
if(DB::getConn() instanceof MySQLDatabase) {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setSelect(array('"Name"', '"Meta"'));
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
$query->setOrderBy(array('MID("Name", 8, 1) DESC', '"Name" ASC'));
|
|
|
|
|
|
|
|
$records = array();
|
|
|
|
foreach($query->execute() as $record) {
|
|
|
|
$records[] = $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertCount(2, $records);
|
|
|
|
|
|
|
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
|
|
|
$this->assertEquals('2', $records[0]['_SortColumn0']);
|
|
|
|
|
|
|
|
$this->assertEquals('Object 1', $records[1]['Name']);
|
|
|
|
$this->assertEquals('1', $records[1]['_SortColumn0']);
|
|
|
|
}
|
|
|
|
}
|
2012-12-20 03:52:46 +01:00
|
|
|
|
2015-05-22 04:18:57 +02:00
|
|
|
public function testSelect() {
|
|
|
|
$query = new SQLQuery('"Title"', '"MyTable"');
|
|
|
|
$query->addSelect('"TestField"');
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT "Title", "TestField" FROM "MyTable"',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Test replacement of select
|
|
|
|
$query->setSelect(array(
|
|
|
|
'Field' => '"Field"',
|
|
|
|
'AnotherAlias' => '"AnotherField"'
|
|
|
|
));
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT "Field", "AnotherField" AS "AnotherAlias" FROM "MyTable"',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Check that ' as ' selects don't get mistaken as aliases
|
|
|
|
$query->addSelect(array(
|
|
|
|
'Relevance' => "MATCH (Title, MenuTitle) AGAINST ('Two as One')"
|
|
|
|
));
|
|
|
|
$this->assertEquals(
|
|
|
|
'SELECT "Field", "AnotherField" AS "AnotherAlias", MATCH (Title, MenuTitle) AGAINST (' .
|
|
|
|
'\'Two as One\') AS "Relevance" FROM "MyTable"',
|
|
|
|
$query->sql()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2013-09-13 05:44:02 +02:00
|
|
|
/**
|
|
|
|
* Test passing in a LIMIT with OFFSET clause string.
|
|
|
|
*/
|
|
|
|
public function testLimitSetFromClauseString() {
|
|
|
|
$query = new SQLQuery();
|
|
|
|
$query->setSelect('*');
|
|
|
|
$query->setFrom('"SQLQueryTest_DO"');
|
|
|
|
|
|
|
|
$query->setLimit('20 OFFSET 10');
|
|
|
|
$limit = $query->getLimit();
|
|
|
|
$this->assertEquals(20, $limit['limit']);
|
|
|
|
$this->assertEquals(10, $limit['start']);
|
|
|
|
}
|
|
|
|
|
2008-08-09 07:57:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class SQLQueryTest_DO extends DataObject implements TestOnly {
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $db = array(
|
2008-08-09 07:57:44 +02:00
|
|
|
"Name" => "Varchar",
|
|
|
|
"Meta" => "Varchar",
|
2012-12-20 14:04:22 +01:00
|
|
|
"Common" => "Varchar",
|
2012-12-20 03:52:46 +01:00
|
|
|
"Date" => "SS_Datetime"
|
2008-08-09 07:57:44 +02:00
|
|
|
);
|
2008-08-09 06:38:44 +02:00
|
|
|
}
|
|
|
|
|
2012-12-10 06:11:07 +01:00
|
|
|
class SQLQueryTestBase extends DataObject implements TestOnly {
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $db = array(
|
2012-12-10 06:11:07 +01:00
|
|
|
"Title" => "Varchar",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
class SQLQueryTestChild extends SQLQueryTestBase {
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $db = array(
|
2012-12-10 06:11:07 +01:00
|
|
|
"Name" => "Varchar",
|
|
|
|
);
|
2012-02-12 21:22:11 +01:00
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $has_one = array(
|
2012-12-10 06:11:07 +01:00
|
|
|
);
|
|
|
|
}
|