silverstripe-framework/tests/php/ORM/SQLSelectTest.php

750 lines
23 KiB
PHP
Raw Normal View History

<?php
2016-10-14 03:30:05 +02:00
namespace SilverStripe\ORM\Tests;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\ORM\Queries\SQLSelect;
2016-06-23 01:37:22 +02:00
use SilverStripe\SQLite\SQLite3Database;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
use SilverStripe\Dev\Deprecation;
use SilverStripe\Dev\SapphireTest;
2015-07-31 07:18:49 +02:00
class SQLSelectTest extends SapphireTest {
2014-08-15 08:53:05 +02:00
2015-07-31 07:18:49 +02:00
protected static $fixture_file = 'SQLSelectTest.yml';
protected $extraDataObjects = array(
2016-10-14 03:30:05 +02:00
SQLSelectTest\TestObject::class,
SQLSelectTest\TestBase::class,
SQLSelectTest\TestChild::class
);
2016-03-08 21:50:18 +01:00
2015-06-15 08:35:01 +02:00
protected $oldDeprecation = null;
2016-03-08 21:50:18 +01:00
2015-06-15 08:35:01 +02:00
public function setUp() {
parent::setUp();
$this->oldDeprecation = Deprecation::dump_settings();
}
2016-03-08 21:50:18 +01:00
2015-06-15 08:35:01 +02:00
public function tearDown() {
Deprecation::restore_settings($this->oldDeprecation);
parent::tearDown();
}
2014-08-15 08:53:05 +02:00
2015-05-07 19:55:37 +02:00
public function testCount() {
//basic counting
2016-10-14 03:30:05 +02:00
$qry = SQLSelectTest\TestObject::get()->dataQuery()->getFinalisedQuery();
$qry->setGroupBy('"Common"');
2016-10-14 03:30:05 +02:00
$ids = $this->allFixtureIDs(SQLSelectTest\TestObject::class);
Merge 3 into master # Conflicts: # admin/javascript/LeftAndMain.Tree.js # admin/javascript/lang/cs.js # admin/javascript/lang/de.js # admin/javascript/lang/en.js # admin/javascript/lang/eo.js # admin/javascript/lang/es.js # admin/javascript/lang/fa_IR.js # admin/javascript/lang/fi.js # admin/javascript/lang/fr.js # admin/javascript/lang/id.js # admin/javascript/lang/id_ID.js # admin/javascript/lang/it.js # admin/javascript/lang/ja.js # admin/javascript/lang/lt.js # admin/javascript/lang/mi.js # admin/javascript/lang/nb.js # admin/javascript/lang/nl.js # admin/javascript/lang/pl.js # admin/javascript/lang/ro.js # admin/javascript/lang/ru.js # admin/javascript/lang/sk.js # admin/javascript/lang/sl.js # admin/javascript/lang/sr.js # admin/javascript/lang/sr@latin.js # admin/javascript/lang/sr_RS.js # admin/javascript/lang/sr_RS@latin.js # admin/javascript/lang/src/cs.js # admin/javascript/lang/src/de.js # admin/javascript/lang/src/en.js # admin/javascript/lang/src/eo.js # admin/javascript/lang/src/es.js # admin/javascript/lang/src/fi.js # admin/javascript/lang/src/fr.js # admin/javascript/lang/src/id.js # admin/javascript/lang/src/id_ID.js # admin/javascript/lang/src/it.js # admin/javascript/lang/src/ja.js # admin/javascript/lang/src/lt.js # admin/javascript/lang/src/mi.js # admin/javascript/lang/src/nb.js # admin/javascript/lang/src/nl.js # admin/javascript/lang/src/pl.js # admin/javascript/lang/src/ro.js # admin/javascript/lang/src/ru.js # admin/javascript/lang/src/sk.js # admin/javascript/lang/src/sl.js # admin/javascript/lang/src/sr.js # admin/javascript/lang/src/sr@latin.js # admin/javascript/lang/src/sr_RS.js # admin/javascript/lang/src/sr_RS@latin.js # admin/javascript/lang/src/sv.js # admin/javascript/lang/src/zh.js # admin/javascript/lang/sv.js # admin/javascript/lang/zh.js # css/GridField.css # forms/gridfield/GridFieldExportButton.php # javascript/GridField.js # javascript/lang/ar.js # javascript/lang/cs.js # javascript/lang/de.js # javascript/lang/en.js # javascript/lang/en_GB.js # javascript/lang/eo.js # javascript/lang/es.js # javascript/lang/fi.js # javascript/lang/fr.js # javascript/lang/id.js # javascript/lang/id_ID.js # javascript/lang/it.js # javascript/lang/ja.js # javascript/lang/lt.js # javascript/lang/mi.js # javascript/lang/nb.js # javascript/lang/nl.js # javascript/lang/pl.js # javascript/lang/ru.js # javascript/lang/sk.js # javascript/lang/sl.js # javascript/lang/sr.js # javascript/lang/sr@latin.js # javascript/lang/sr_RS.js # javascript/lang/sr_RS@latin.js # javascript/lang/src/ar.js # javascript/lang/src/cs.js # javascript/lang/src/de.js # javascript/lang/src/en.js # javascript/lang/src/eo.js # javascript/lang/src/es.js # javascript/lang/src/fi.js # javascript/lang/src/fr.js # javascript/lang/src/id.js # javascript/lang/src/id_ID.js # javascript/lang/src/it.js # javascript/lang/src/ja.js # javascript/lang/src/lt.js # javascript/lang/src/mi.js # javascript/lang/src/nb.js # javascript/lang/src/nl.js # javascript/lang/src/pl.js # javascript/lang/src/ru.js # javascript/lang/src/sk.js # javascript/lang/src/sl.js # javascript/lang/src/sr.js # javascript/lang/src/sr@latin.js # javascript/lang/src/sr_RS.js # javascript/lang/src/sr_RS@latin.js # javascript/lang/src/sv.js # javascript/lang/src/zh.js # javascript/lang/sv.js # javascript/lang/zh.js # scss/GridField.scss # tests/model/ManyManyListTest.php # tests/model/SQLQueryTest.php
2016-05-11 05:19:35 +02:00
$count = $qry->count('"SQLSelectTest_DO"."ID"');
$this->assertEquals(count($ids), $count);
$this->assertInternalType("int", $count);
//test with `having`
if (DB::get_conn() instanceof MySQLDatabase) {
$qry->setHaving('"Date" > 2012-02-01');
Merge 3 into master # Conflicts: # admin/javascript/LeftAndMain.Tree.js # admin/javascript/lang/cs.js # admin/javascript/lang/de.js # admin/javascript/lang/en.js # admin/javascript/lang/eo.js # admin/javascript/lang/es.js # admin/javascript/lang/fa_IR.js # admin/javascript/lang/fi.js # admin/javascript/lang/fr.js # admin/javascript/lang/id.js # admin/javascript/lang/id_ID.js # admin/javascript/lang/it.js # admin/javascript/lang/ja.js # admin/javascript/lang/lt.js # admin/javascript/lang/mi.js # admin/javascript/lang/nb.js # admin/javascript/lang/nl.js # admin/javascript/lang/pl.js # admin/javascript/lang/ro.js # admin/javascript/lang/ru.js # admin/javascript/lang/sk.js # admin/javascript/lang/sl.js # admin/javascript/lang/sr.js # admin/javascript/lang/sr@latin.js # admin/javascript/lang/sr_RS.js # admin/javascript/lang/sr_RS@latin.js # admin/javascript/lang/src/cs.js # admin/javascript/lang/src/de.js # admin/javascript/lang/src/en.js # admin/javascript/lang/src/eo.js # admin/javascript/lang/src/es.js # admin/javascript/lang/src/fi.js # admin/javascript/lang/src/fr.js # admin/javascript/lang/src/id.js # admin/javascript/lang/src/id_ID.js # admin/javascript/lang/src/it.js # admin/javascript/lang/src/ja.js # admin/javascript/lang/src/lt.js # admin/javascript/lang/src/mi.js # admin/javascript/lang/src/nb.js # admin/javascript/lang/src/nl.js # admin/javascript/lang/src/pl.js # admin/javascript/lang/src/ro.js # admin/javascript/lang/src/ru.js # admin/javascript/lang/src/sk.js # admin/javascript/lang/src/sl.js # admin/javascript/lang/src/sr.js # admin/javascript/lang/src/sr@latin.js # admin/javascript/lang/src/sr_RS.js # admin/javascript/lang/src/sr_RS@latin.js # admin/javascript/lang/src/sv.js # admin/javascript/lang/src/zh.js # admin/javascript/lang/sv.js # admin/javascript/lang/zh.js # css/GridField.css # forms/gridfield/GridFieldExportButton.php # javascript/GridField.js # javascript/lang/ar.js # javascript/lang/cs.js # javascript/lang/de.js # javascript/lang/en.js # javascript/lang/en_GB.js # javascript/lang/eo.js # javascript/lang/es.js # javascript/lang/fi.js # javascript/lang/fr.js # javascript/lang/id.js # javascript/lang/id_ID.js # javascript/lang/it.js # javascript/lang/ja.js # javascript/lang/lt.js # javascript/lang/mi.js # javascript/lang/nb.js # javascript/lang/nl.js # javascript/lang/pl.js # javascript/lang/ru.js # javascript/lang/sk.js # javascript/lang/sl.js # javascript/lang/sr.js # javascript/lang/sr@latin.js # javascript/lang/sr_RS.js # javascript/lang/sr_RS@latin.js # javascript/lang/src/ar.js # javascript/lang/src/cs.js # javascript/lang/src/de.js # javascript/lang/src/en.js # javascript/lang/src/eo.js # javascript/lang/src/es.js # javascript/lang/src/fi.js # javascript/lang/src/fr.js # javascript/lang/src/id.js # javascript/lang/src/id_ID.js # javascript/lang/src/it.js # javascript/lang/src/ja.js # javascript/lang/src/lt.js # javascript/lang/src/mi.js # javascript/lang/src/nb.js # javascript/lang/src/nl.js # javascript/lang/src/pl.js # javascript/lang/src/ru.js # javascript/lang/src/sk.js # javascript/lang/src/sl.js # javascript/lang/src/sr.js # javascript/lang/src/sr@latin.js # javascript/lang/src/sr_RS.js # javascript/lang/src/sr_RS@latin.js # javascript/lang/src/sv.js # javascript/lang/src/zh.js # javascript/lang/sv.js # javascript/lang/zh.js # scss/GridField.scss # tests/model/ManyManyListTest.php # tests/model/SQLQueryTest.php
2016-05-11 05:19:35 +02:00
$count = $qry->count('"SQLSelectTest_DO"."ID"');
$this->assertEquals(1, $count);
$this->assertInternalType("int", $count);
}
}
public function testUnlimitedRowCount() {
//basic counting
2016-10-14 03:30:05 +02:00
$qry = SQLSelectTest\TestObject::get()->dataQuery()->getFinalisedQuery();
$ids = $this->allFixtureIDs(SQLSelectTest\TestObject::class);
$qry->setLimit(1);
Merge 3 into master # Conflicts: # admin/javascript/LeftAndMain.Tree.js # admin/javascript/lang/cs.js # admin/javascript/lang/de.js # admin/javascript/lang/en.js # admin/javascript/lang/eo.js # admin/javascript/lang/es.js # admin/javascript/lang/fa_IR.js # admin/javascript/lang/fi.js # admin/javascript/lang/fr.js # admin/javascript/lang/id.js # admin/javascript/lang/id_ID.js # admin/javascript/lang/it.js # admin/javascript/lang/ja.js # admin/javascript/lang/lt.js # admin/javascript/lang/mi.js # admin/javascript/lang/nb.js # admin/javascript/lang/nl.js # admin/javascript/lang/pl.js # admin/javascript/lang/ro.js # admin/javascript/lang/ru.js # admin/javascript/lang/sk.js # admin/javascript/lang/sl.js # admin/javascript/lang/sr.js # admin/javascript/lang/sr@latin.js # admin/javascript/lang/sr_RS.js # admin/javascript/lang/sr_RS@latin.js # admin/javascript/lang/src/cs.js # admin/javascript/lang/src/de.js # admin/javascript/lang/src/en.js # admin/javascript/lang/src/eo.js # admin/javascript/lang/src/es.js # admin/javascript/lang/src/fi.js # admin/javascript/lang/src/fr.js # admin/javascript/lang/src/id.js # admin/javascript/lang/src/id_ID.js # admin/javascript/lang/src/it.js # admin/javascript/lang/src/ja.js # admin/javascript/lang/src/lt.js # admin/javascript/lang/src/mi.js # admin/javascript/lang/src/nb.js # admin/javascript/lang/src/nl.js # admin/javascript/lang/src/pl.js # admin/javascript/lang/src/ro.js # admin/javascript/lang/src/ru.js # admin/javascript/lang/src/sk.js # admin/javascript/lang/src/sl.js # admin/javascript/lang/src/sr.js # admin/javascript/lang/src/sr@latin.js # admin/javascript/lang/src/sr_RS.js # admin/javascript/lang/src/sr_RS@latin.js # admin/javascript/lang/src/sv.js # admin/javascript/lang/src/zh.js # admin/javascript/lang/sv.js # admin/javascript/lang/zh.js # css/GridField.css # forms/gridfield/GridFieldExportButton.php # javascript/GridField.js # javascript/lang/ar.js # javascript/lang/cs.js # javascript/lang/de.js # javascript/lang/en.js # javascript/lang/en_GB.js # javascript/lang/eo.js # javascript/lang/es.js # javascript/lang/fi.js # javascript/lang/fr.js # javascript/lang/id.js # javascript/lang/id_ID.js # javascript/lang/it.js # javascript/lang/ja.js # javascript/lang/lt.js # javascript/lang/mi.js # javascript/lang/nb.js # javascript/lang/nl.js # javascript/lang/pl.js # javascript/lang/ru.js # javascript/lang/sk.js # javascript/lang/sl.js # javascript/lang/sr.js # javascript/lang/sr@latin.js # javascript/lang/sr_RS.js # javascript/lang/sr_RS@latin.js # javascript/lang/src/ar.js # javascript/lang/src/cs.js # javascript/lang/src/de.js # javascript/lang/src/en.js # javascript/lang/src/eo.js # javascript/lang/src/es.js # javascript/lang/src/fi.js # javascript/lang/src/fr.js # javascript/lang/src/id.js # javascript/lang/src/id_ID.js # javascript/lang/src/it.js # javascript/lang/src/ja.js # javascript/lang/src/lt.js # javascript/lang/src/mi.js # javascript/lang/src/nb.js # javascript/lang/src/nl.js # javascript/lang/src/pl.js # javascript/lang/src/ru.js # javascript/lang/src/sk.js # javascript/lang/src/sl.js # javascript/lang/src/sr.js # javascript/lang/src/sr@latin.js # javascript/lang/src/sr_RS.js # javascript/lang/src/sr_RS@latin.js # javascript/lang/src/sv.js # javascript/lang/src/zh.js # javascript/lang/sv.js # javascript/lang/zh.js # scss/GridField.scss # tests/model/ManyManyListTest.php # tests/model/SQLQueryTest.php
2016-05-11 05:19:35 +02:00
$count = $qry->unlimitedRowCount('"SQLSelectTest_DO"."ID"');
$this->assertEquals(count($ids), $count);
$this->assertInternalType("int", $count);
// Test without column - SQLSelect has different logic for this
$count = $qry->unlimitedRowCount();
$this->assertEquals(2, $count);
$this->assertInternalType("int", $count);
2015-05-07 19:55:37 +02:00
//test with `having`
if (DB::get_conn() instanceof MySQLDatabase) {
2015-05-07 19:55:37 +02:00
$qry->setHaving('"Date" > 2012-02-01');
Merge 3 into master # Conflicts: # admin/javascript/LeftAndMain.Tree.js # admin/javascript/lang/cs.js # admin/javascript/lang/de.js # admin/javascript/lang/en.js # admin/javascript/lang/eo.js # admin/javascript/lang/es.js # admin/javascript/lang/fa_IR.js # admin/javascript/lang/fi.js # admin/javascript/lang/fr.js # admin/javascript/lang/id.js # admin/javascript/lang/id_ID.js # admin/javascript/lang/it.js # admin/javascript/lang/ja.js # admin/javascript/lang/lt.js # admin/javascript/lang/mi.js # admin/javascript/lang/nb.js # admin/javascript/lang/nl.js # admin/javascript/lang/pl.js # admin/javascript/lang/ro.js # admin/javascript/lang/ru.js # admin/javascript/lang/sk.js # admin/javascript/lang/sl.js # admin/javascript/lang/sr.js # admin/javascript/lang/sr@latin.js # admin/javascript/lang/sr_RS.js # admin/javascript/lang/sr_RS@latin.js # admin/javascript/lang/src/cs.js # admin/javascript/lang/src/de.js # admin/javascript/lang/src/en.js # admin/javascript/lang/src/eo.js # admin/javascript/lang/src/es.js # admin/javascript/lang/src/fi.js # admin/javascript/lang/src/fr.js # admin/javascript/lang/src/id.js # admin/javascript/lang/src/id_ID.js # admin/javascript/lang/src/it.js # admin/javascript/lang/src/ja.js # admin/javascript/lang/src/lt.js # admin/javascript/lang/src/mi.js # admin/javascript/lang/src/nb.js # admin/javascript/lang/src/nl.js # admin/javascript/lang/src/pl.js # admin/javascript/lang/src/ro.js # admin/javascript/lang/src/ru.js # admin/javascript/lang/src/sk.js # admin/javascript/lang/src/sl.js # admin/javascript/lang/src/sr.js # admin/javascript/lang/src/sr@latin.js # admin/javascript/lang/src/sr_RS.js # admin/javascript/lang/src/sr_RS@latin.js # admin/javascript/lang/src/sv.js # admin/javascript/lang/src/zh.js # admin/javascript/lang/sv.js # admin/javascript/lang/zh.js # css/GridField.css # forms/gridfield/GridFieldExportButton.php # javascript/GridField.js # javascript/lang/ar.js # javascript/lang/cs.js # javascript/lang/de.js # javascript/lang/en.js # javascript/lang/en_GB.js # javascript/lang/eo.js # javascript/lang/es.js # javascript/lang/fi.js # javascript/lang/fr.js # javascript/lang/id.js # javascript/lang/id_ID.js # javascript/lang/it.js # javascript/lang/ja.js # javascript/lang/lt.js # javascript/lang/mi.js # javascript/lang/nb.js # javascript/lang/nl.js # javascript/lang/pl.js # javascript/lang/ru.js # javascript/lang/sk.js # javascript/lang/sl.js # javascript/lang/sr.js # javascript/lang/sr@latin.js # javascript/lang/sr_RS.js # javascript/lang/sr_RS@latin.js # javascript/lang/src/ar.js # javascript/lang/src/cs.js # javascript/lang/src/de.js # javascript/lang/src/en.js # javascript/lang/src/eo.js # javascript/lang/src/es.js # javascript/lang/src/fi.js # javascript/lang/src/fr.js # javascript/lang/src/id.js # javascript/lang/src/id_ID.js # javascript/lang/src/it.js # javascript/lang/src/ja.js # javascript/lang/src/lt.js # javascript/lang/src/mi.js # javascript/lang/src/nb.js # javascript/lang/src/nl.js # javascript/lang/src/pl.js # javascript/lang/src/ru.js # javascript/lang/src/sk.js # javascript/lang/src/sl.js # javascript/lang/src/sr.js # javascript/lang/src/sr@latin.js # javascript/lang/src/sr_RS.js # javascript/lang/src/sr_RS@latin.js # javascript/lang/src/sv.js # javascript/lang/src/zh.js # javascript/lang/sv.js # javascript/lang/zh.js # scss/GridField.scss # tests/model/ManyManyListTest.php # tests/model/SQLQueryTest.php
2016-05-11 05:19:35 +02:00
$count = $qry->unlimitedRowCount('"SQLSelectTest_DO"."ID"');
$this->assertEquals(1, $count);
$this->assertInternalType("int", $count);
2015-05-07 19:55:37 +02:00
}
}
public function testEmptyQueryReturnsNothing() {
$query = new SQLSelect();
$this->assertSQLEquals('', $query->sql($parameters));
}
2014-08-15 08:53:05 +02:00
public function testSelectFromBasicTable() {
$query = new SQLSelect();
$query->setFrom('MyTable');
$this->assertSQLEquals("SELECT * FROM MyTable", $query->sql($parameters));
$query->addFrom('MyJoin');
$this->assertSQLEquals("SELECT * FROM MyTable MyJoin", $query->sql($parameters));
}
2014-08-15 08:53:05 +02:00
public function testSelectFromUserSpecifiedFields() {
$query = new SQLSelect();
$query->setSelect(array("Name", "Title", "Description"));
$query->setFrom("MyTable");
$this->assertSQLEquals("SELECT Name, Title, Description FROM MyTable", $query->sql($parameters));
}
2014-08-15 08:53:05 +02:00
public function testSelectWithWhereClauseFilter() {
$query = new SQLSelect();
$query->setSelect(array("Name","Meta"));
$query->setFrom("MyTable");
$query->setWhere("Name = 'Name'");
$query->addWhere("Meta = 'Test'");
$this->assertSQLEquals(
"SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')",
$query->sql($parameters)
);
}
2014-08-15 08:53:05 +02:00
public function testSelectWithConstructorParameters() {
$query = new SQLSelect(array("Foo", "Bar"), "FooBarTable");
$this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable", $query->sql($parameters));
$query = new SQLSelect(array("Foo", "Bar"), "FooBarTable", array("Foo = 'Boo'"));
$this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable WHERE (Foo = 'Boo')", $query->sql($parameters));
}
2014-08-15 08:53:05 +02:00
public function testSelectWithChainedMethods() {
$query = new SQLSelect();
$query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'");
$this->assertSQLEquals(
"SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')",
$query->sql($parameters)
);
}
2014-08-15 08:53:05 +02:00
public function testCanSortBy() {
$query = new SQLSelect();
$query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'");
$this->assertTrue($query->canSortBy('Name ASC'));
$this->assertTrue($query->canSortBy('Name'));
}
2014-08-15 08:53:05 +02:00
public function testSelectWithChainedFilterParameters() {
$query = new SQLSelect();
$query->setSelect(array("Name","Meta"))->setFrom("MyTable");
$query->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'")->addWhere("Beta != 'Gamma'");
$this->assertSQLEquals(
"SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test') AND (Beta != 'Gamma')",
$query->sql($parameters)
);
}
2014-08-15 08:53:05 +02:00
public function testSelectWithLimitClause() {
2014-08-15 08:53:05 +02:00
if(!(DB::get_conn() instanceof MySQLDatabase || DB::get_conn() instanceof SQLite3Database
|| DB::get_conn() instanceof PostgreSQLDatabase)) {
$this->markTestIncomplete();
}
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setLimit(99);
$this->assertSQLEquals("SELECT * FROM MyTable LIMIT 99", $query->sql($parameters));
2014-08-15 08:53:05 +02:00
// array limit with start (MySQL specific)
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setLimit(99, 97);
$this->assertSQLEquals("SELECT * FROM MyTable LIMIT 99 OFFSET 97", $query->sql($parameters));
}
2014-08-15 08:53:05 +02:00
public function testSelectWithOrderbyClause() {
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('MyName');
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC', $query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('MyName desc');
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('MyName ASC, Color DESC');
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color DESC', $query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('MyName ASC, Color');
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color ASC', $query->sql($parameters));
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy(array('MyName' => 'desc'));
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy(array('MyName' => 'desc', 'Color'));
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC, Color ASC', $query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('implode("MyName","Color")');
$this->assertSQLEquals(
2014-08-15 08:53:05 +02:00
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
$query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('implode("MyName","Color") DESC');
$this->assertSQLEquals(
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" DESC',
$query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setOrderBy('RAND()');
$this->assertSQLEquals(
'SELECT *, RAND() AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
$query->sql($parameters));
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->addFrom('INNER JOIN SecondTable USING (ID)');
$query->addFrom('INNER JOIN ThirdTable USING (ID)');
$query->setOrderBy('MyName');
$this->assertSQLEquals(
'SELECT * FROM MyTable '
. 'INNER JOIN SecondTable USING (ID) '
. 'INNER JOIN ThirdTable USING (ID) '
. 'ORDER BY MyName ASC',
$query->sql($parameters));
}
public function testNullLimit() {
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setLimit(null);
$this->assertSQLEquals(
'SELECT * FROM MyTable',
$query->sql($parameters)
);
}
public function testZeroLimit() {
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setLimit(0);
$this->assertSQLEquals(
'SELECT * FROM MyTable',
$query->sql($parameters)
);
}
public function testZeroLimitWithOffset() {
2014-08-15 08:53:05 +02:00
if(!(DB::get_conn() instanceof MySQLDatabase || DB::get_conn() instanceof SQLite3Database
|| DB::get_conn() instanceof PostgreSQLDatabase)) {
$this->markTestIncomplete();
}
$query = new SQLSelect();
$query->setFrom("MyTable");
$query->setLimit(0, 99);
$this->assertSQLEquals(
'SELECT * FROM MyTable LIMIT 0 OFFSET 99',
$query->sql($parameters)
);
}
/**
* @expectedException InvalidArgumentException
*/
public function testNegativeLimit() {
$query = new SQLSelect();
$query->setLimit(-10);
}
/**
* @expectedException InvalidArgumentException
*/
public function testNegativeOffset() {
$query = new SQLSelect();
$query->setLimit(1, -10);
}
/**
* @expectedException InvalidArgumentException
*/
public function testNegativeOffsetAndLimit() {
$query = new SQLSelect();
$query->setLimit(-10, -10);
}
public function testReverseOrderBy() {
$query = new SQLSelect();
$query->setFrom('MyTable');
2014-08-15 08:53:05 +02:00
// default is ASC
$query->setOrderBy("Name");
$query->reverseOrderBy();
2014-08-15 08:53:05 +02:00
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql($parameters));
$query->setOrderBy("Name DESC");
$query->reverseOrderBy();
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name ASC',$query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query->setOrderBy(array("Name" => "ASC"));
$query->reverseOrderBy();
2014-08-15 08:53:05 +02:00
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query->setOrderBy(array("Name" => 'DESC', 'Color' => 'asc'));
$query->reverseOrderBy();
2014-08-15 08:53:05 +02:00
$this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name ASC, Color DESC',$query->sql($parameters));
2014-08-15 08:53:05 +02:00
$query->setOrderBy('implode("MyName","Color") DESC');
$query->reverseOrderBy();
2014-08-15 08:53:05 +02:00
$this->assertSQLEquals(
'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC',
$query->sql($parameters));
}
public function testFiltersOnID() {
$query = new SQLSelect();
$query->setWhere("ID = 5");
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with simple unquoted column name"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere('"ID" = 5');
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with simple quoted column name"
);
$query = new SQLSelect();
$query->setWhere(array('"ID"' => 4));
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with parameterised quoted column name"
);
$query = new SQLSelect();
$query->setWhere(array('"ID" = ?' => 4));
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with parameterised quoted column name"
);
$query = new SQLSelect();
$query->setWhere('"ID" IN (5,4)');
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with WHERE ID IN"
);
$query = new SQLSelect();
$query->setWhere(array('"ID" IN ?' => array(1,2)));
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with parameterised WHERE ID IN"
);
$query = new SQLSelect();
$query->setWhere("ID=5");
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with simple unquoted column name and no spaces in equals sign"
);
$query = new SQLSelect();
$query->setWhere("Identifier = 5");
$this->assertFalse(
$query->filtersOnID(),
"filtersOnID() is false with custom column name (starting with 'id')"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("ParentID = 5");
$this->assertFalse(
$query->filtersOnID(),
"filtersOnID() is false with column name ending in 'ID'"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("MyTable.ID = 5");
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with table and column name"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("MyTable.ID = 5");
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with table and quoted column name "
);
}
2014-08-15 08:53:05 +02:00
public function testFiltersOnFK() {
$query = new SQLSelect();
$query->setWhere("ID = 5");
$this->assertFalse(
$query->filtersOnFK(),
"filtersOnFK() is true with simple unquoted column name"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("Identifier = 5");
$this->assertFalse(
$query->filtersOnFK(),
"filtersOnFK() is false with custom column name (starting with 'id')"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("MyTable.ParentID = 5");
$this->assertTrue(
$query->filtersOnFK(),
"filtersOnFK() is true with table and column name"
);
2014-08-15 08:53:05 +02:00
$query = new SQLSelect();
$query->setWhere("MyTable.`ParentID`= 5");
$this->assertTrue(
$query->filtersOnFK(),
"filtersOnFK() is true with table and quoted column name "
);
}
public function testInnerJoin() {
$query = new SQLSelect();
$query->setFrom('MyTable');
$query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2');
$query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID');
$this->assertSQLEquals('SELECT * FROM MyTable '.
'INNER JOIN "MyOtherTable" ON MyOtherTable.ID = 2 '.
'LEFT JOIN "MyLastTable" ON MyOtherTable.ID = MyLastTable.ID',
$query->sql($parameters)
);
$query = new SQLSelect();
$query->setFrom('MyTable');
$query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2', 'table1');
$query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID', 'table2');
$this->assertSQLEquals('SELECT * FROM MyTable '.
'INNER JOIN "MyOtherTable" AS "table1" ON MyOtherTable.ID = 2 '.
'LEFT JOIN "MyLastTable" AS "table2" ON MyOtherTable.ID = MyLastTable.ID',
$query->sql($parameters)
);
}
2014-08-15 08:53:05 +02:00
public function testJoinSubSelect() {
Merge remote-tracking branch 'origin/3' Conflicts: composer.json docs/en/00_Getting_Started/00_Server_Requirements.md docs/en/00_Getting_Started/01_Installation/04_Other_installation_Options/Windows_IIS7.md docs/en/00_Getting_Started/01_Installation/04_Other_installation_Options/Windows_Platform_Installer.md docs/en/00_Getting_Started/04_Directory_Structure.md docs/en/01_Tutorials/01_Building_A_Basic_Site.md docs/en/01_Tutorials/02_Extending_A_Basic_Site.md docs/en/01_Tutorials/03_Forms.md docs/en/01_Tutorials/04_Site_Search.md docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md docs/en/01_Tutorials/index.md docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md docs/en/02_Developer_Guides/01_Templates/06_Themes.md docs/en/02_Developer_Guides/03_Forms/How_Tos/Simple_Contact_Form.md docs/en/02_Developer_Guides/05_Extending/05_Injector.md docs/en/02_Developer_Guides/14_Files/index.md docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/03_CMS_Layout.md docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/06_Javascript_Development.md docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/How_Tos/Customise_CMS_Tree.md docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/How_Tos/Customise_Site_Reports.md docs/en/02_Developer_Guides/18_Cookies_And_Sessions/01_Cookies.md docs/en/04_Changelogs/3.1.9.md docs/en/05_Contributing/00_Issues_and_Bugs.md docs/en/05_Contributing/02_Release_Process.md docs/en/05_Contributing/03_Documentation.md
2015-01-15 22:08:40 +01:00
$query = new SQLSelect();
$query->setFrom('MyTable');
2014-08-15 08:53:05 +02:00
$query->addInnerJoin('(SELECT * FROM MyOtherTable)',
'Mot.MyTableID = MyTable.ID', 'Mot');
$query->addLeftJoin('(SELECT MyLastTable.MyOtherTableID, COUNT(1) as MyLastTableCount FROM MyLastTable '
2014-08-15 08:53:05 +02:00
. 'GROUP BY MyOtherTableID)',
'Mlt.MyOtherTableID = Mot.ID', 'Mlt');
$query->setOrderBy('COALESCE(Mlt.MyLastTableCount, 0) DESC');
$this->assertSQLEquals('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 ' .
'ORDER BY "_SortColumn0" DESC',
$query->sql($parameters)
);
}
2014-08-15 08:53:05 +02:00
public function testSetWhereAny() {
$query = new SQLSelect();
$query->setFrom('MyTable');
$query->setWhereAny(array(
'Monkey' => 'Chimp',
'Color' => 'Brown'
));
$sql = $query->sql($parameters);
$this->assertSQLEquals("SELECT * FROM MyTable WHERE ((Monkey = ?) OR (Color = ?))", $sql);
$this->assertEquals(array('Chimp', 'Brown'), $parameters);
}
2014-08-15 08:53:05 +02:00
public function testSelectFirst() {
// Test first from sequence
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$result = $query->firstRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(1, $records);
$this->assertEquals('Object 1', $records[0]['Name']);
// Test first from empty sequence
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$query->setWhere(array('"Name"' => 'Nonexistent Object'));
$result = $query->firstRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(0, $records);
2014-08-15 08:53:05 +02:00
// Test that given the last item, the 'first' in this list matches the last
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$query->setLimit(1, 1);
$result = $query->firstRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(1, $records);
$this->assertEquals('Object 2', $records[0]['Name']);
}
2014-08-15 08:53:05 +02:00
public function testSelectLast() {
// Test last in sequence
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$result = $query->lastRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(1, $records);
$this->assertEquals('Object 2', $records[0]['Name']);
2014-08-15 08:53:05 +02:00
// Test last from empty sequence
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
$result = $query->lastRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(0, $records);
// Test that given the first item, the 'last' in this list matches the first
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setOrderBy('"Name"');
$query->setLimit(1);
$result = $query->lastRow()->execute();
$records = array();
foreach($result as $row) {
$records[] = $row;
}
$this->assertCount(1, $records);
$this->assertEquals('Object 1', $records[0]['Name']);
}
/**
* Tests aggregate() function
*/
public function testAggregate() {
$query = new SQLSelect('"Common"');
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setGroupBy('"Common"');
2014-08-15 08:53:05 +02:00
$queryClone = $query->aggregate('COUNT(*)', 'cnt');
$result = $queryClone->execute();
$this->assertEquals(array(2), $result->column('cnt'));
}
/**
* Tests that an ORDER BY is only added if a LIMIT is set.
*/
public function testAggregateNoOrderByIfNoLimit() {
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_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 SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_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);
}
/**
* 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 SQLSelect();
$query->setSelect(array('"Name"', '"Meta"'));
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
2013-04-02 12:07:41 +02:00
$query->setOrderBy(array('MAX("Date")'));
$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']);
}
2014-08-15 08:53:05 +02:00
/**
* Test that multiple order elements are maintained in the given order
*/
public function testOrderByMultiple() {
if(DB::get_conn() instanceof MySQLDatabase) {
$query = new SQLSelect();
$query->setSelect(array('"Name"', '"Meta"'));
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_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']);
}
}
2015-05-22 04:18:57 +02:00
public function testSelect() {
$query = new SQLSelect('"Title"', '"MyTable"');
2015-05-22 04:18:57 +02:00
$query->addSelect('"TestField"');
2015-06-02 10:19:12 +02:00
$this->assertSQLEquals(
2015-05-22 04:18:57 +02:00
'SELECT "Title", "TestField" FROM "MyTable"',
$query->sql()
);
// Test replacement of select
$query->setSelect(array(
'Field' => '"Field"',
'AnotherAlias' => '"AnotherField"'
));
2015-06-02 10:19:12 +02:00
$this->assertSQLEquals(
2015-05-22 04:18:57 +02:00
'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')"
));
2015-06-02 10:19:12 +02:00
$this->assertSQLEquals(
2015-05-22 04:18:57 +02:00
'SELECT "Field", "AnotherField" AS "AnotherAlias", MATCH (Title, MenuTitle) AGAINST (' .
'\'Two as One\') AS "Relevance" FROM "MyTable"',
$query->sql()
);
}
/**
* Test passing in a LIMIT with OFFSET clause string.
*/
public function testLimitSetFromClauseString() {
$query = new SQLSelect();
$query->setSelect('*');
2015-07-31 07:18:49 +02:00
$query->setFrom('"SQLSelectTest_DO"');
$query->setLimit('20 OFFSET 10');
$limit = $query->getLimit();
$this->assertEquals(20, $limit['limit']);
$this->assertEquals(10, $limit['start']);
}
public function testParameterisedInnerJoins() {
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setSelect(array('"SQLSelectTest_DO"."Name"', '"SubSelect"."Count"'));
$query->setFrom('"SQLSelectTest_DO"');
$query->addInnerJoin(
2015-07-31 07:18:49 +02:00
'(SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase" GROUP BY "Title" HAVING "Title" NOT LIKE ?)',
'"SQLSelectTest_DO"."Name" = "SubSelect"."Title"',
'SubSelect',
20,
array('%MyName%')
);
2015-07-31 07:18:49 +02:00
$query->addWhere(array('"SQLSelectTest_DO"."Date" > ?' => '2012-08-08 12:00'));
2015-07-31 07:18:49 +02:00
$this->assertSQLEquals('SELECT "SQLSelectTest_DO"."Name", "SubSelect"."Count"
FROM "SQLSelectTest_DO" INNER JOIN (SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase"
GROUP BY "Title" HAVING "Title" NOT LIKE ?) AS "SubSelect" ON "SQLSelectTest_DO"."Name" =
"SubSelect"."Title"
2015-07-31 07:18:49 +02:00
WHERE ("SQLSelectTest_DO"."Date" > ?)', $query->sql($parameters)
);
$this->assertEquals(array('%MyName%', '2012-08-08 12:00'), $parameters);
$query->execute();
}
public function testParameterisedLeftJoins() {
$query = new SQLSelect();
2015-07-31 07:18:49 +02:00
$query->setSelect(array('"SQLSelectTest_DO"."Name"', '"SubSelect"."Count"'));
$query->setFrom('"SQLSelectTest_DO"');
$query->addLeftJoin(
2015-07-31 07:18:49 +02:00
'(SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase" GROUP BY "Title" HAVING "Title" NOT LIKE ?)',
'"SQLSelectTest_DO"."Name" = "SubSelect"."Title"',
'SubSelect',
20,
array('%MyName%')
);
2015-07-31 07:18:49 +02:00
$query->addWhere(array('"SQLSelectTest_DO"."Date" > ?' => '2012-08-08 12:00'));
2015-07-31 07:18:49 +02:00
$this->assertSQLEquals('SELECT "SQLSelectTest_DO"."Name", "SubSelect"."Count"
FROM "SQLSelectTest_DO" LEFT JOIN (SELECT "Title", COUNT(*) AS "Count" FROM "SQLSelectTestBase"
GROUP BY "Title" HAVING "Title" NOT LIKE ?) AS "SubSelect" ON "SQLSelectTest_DO"."Name" =
"SubSelect"."Title"
2015-07-31 07:18:49 +02:00
WHERE ("SQLSelectTest_DO"."Date" > ?)', $query->sql($parameters)
);
$this->assertEquals(array('%MyName%', '2012-08-08 12:00'), $parameters);
$query->execute();
}
}