mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUG Sort column order maintained correctly when using expressions in SQLQuery and DataQuery
This commit is contained in:
parent
6e72262c96
commit
afaf7f6b4e
@ -256,7 +256,10 @@ class DataQuery {
|
|||||||
$baseClass = array_shift($tableClasses);
|
$baseClass = array_shift($tableClasses);
|
||||||
|
|
||||||
if($orderby = $query->getOrderBy()) {
|
if($orderby = $query->getOrderBy()) {
|
||||||
|
$newOrderby = array();
|
||||||
foreach($orderby as $k => $dir) {
|
foreach($orderby as $k => $dir) {
|
||||||
|
$newOrderby[$k] = $dir;
|
||||||
|
|
||||||
// don't touch functions in the ORDER BY or public function calls
|
// don't touch functions in the ORDER BY or public function calls
|
||||||
// selected as fields
|
// selected as fields
|
||||||
if(strpos($k, '(') !== false) continue;
|
if(strpos($k, '(') !== false) continue;
|
||||||
@ -284,9 +287,9 @@ class DataQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove original sort
|
// remove original sort
|
||||||
unset($orderby[$k]);
|
unset($newOrderby[$k]);
|
||||||
// add new columns sort
|
// add new columns sort
|
||||||
$orderby[$qualCol] = $dir;
|
$newOrderby[$qualCol] = $dir;
|
||||||
|
|
||||||
// To-do: Remove this if block once SQLQuery::$select has been refactored to store getSelect()
|
// To-do: Remove this if block once SQLQuery::$select has been refactored to store getSelect()
|
||||||
// format internally; then this check can be part of selectField()
|
// format internally; then this check can be part of selectField()
|
||||||
@ -305,7 +308,7 @@ class DataQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$query->setOrderBy($orderby);
|
$query->setOrderBy($newOrderby);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +519,7 @@ class SQLQuery {
|
|||||||
* @example $sql->orderby("Column", "DESC");
|
* @example $sql->orderby("Column", "DESC");
|
||||||
* @example $sql->orderby(array("Column" => "ASC", "ColumnTwo" => "DESC"));
|
* @example $sql->orderby(array("Column" => "ASC", "ColumnTwo" => "DESC"));
|
||||||
*
|
*
|
||||||
* @param string|array $orderby Clauses to add (escaped SQL statements)
|
* @param string|array $clauses Clauses to add (escaped SQL statements)
|
||||||
* @param string $dir Sort direction, ASC or DESC
|
* @param string $dir Sort direction, ASC or DESC
|
||||||
*
|
*
|
||||||
* @return SQLQuery
|
* @return SQLQuery
|
||||||
@ -566,21 +566,23 @@ class SQLQuery {
|
|||||||
// directly in the ORDER BY
|
// directly in the ORDER BY
|
||||||
if($this->orderby) {
|
if($this->orderby) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
$orderby = array();
|
||||||
foreach($this->orderby as $clause => $dir) {
|
foreach($this->orderby as $clause => $dir) {
|
||||||
|
|
||||||
// public function calls and multi-word columns like "CASE WHEN ..."
|
// public function calls and multi-word columns like "CASE WHEN ..."
|
||||||
if(strpos($clause, '(') !== false || strpos($clause, " ") !== false ) {
|
if(strpos($clause, '(') !== false || strpos($clause, " ") !== false ) {
|
||||||
// remove the old orderby
|
|
||||||
unset($this->orderby[$clause]);
|
|
||||||
|
|
||||||
|
// Move the clause to the select fragment, substituting a placeholder column in the sort fragment.
|
||||||
$clause = trim($clause);
|
$clause = trim($clause);
|
||||||
$column = "_SortColumn{$i}";
|
$column = "_SortColumn{$i}";
|
||||||
|
|
||||||
$this->selectField($clause, $column);
|
$this->selectField($clause, $column);
|
||||||
$this->addOrderBy('"' . $column . '"', $dir);
|
$clause = '"' . $column . '"';
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$orderby[$clause] = $dir;
|
||||||
}
|
}
|
||||||
|
$this->orderby = $orderby;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -115,6 +115,15 @@ class DataQueryTest extends SapphireTest {
|
|||||||
|
|
||||||
$this->assertEquals($dq->sql(), $orgDq->sql());
|
$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()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -480,6 +480,31 @@ class SQLQueryTest extends SapphireTest {
|
|||||||
$this->assertEquals('2012-05-01 09:00:00', $records['0']['_SortColumn0']);
|
$this->assertEquals('2012-05-01 09:00:00', $records['0']['_SortColumn0']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test passing in a LIMIT with OFFSET clause string.
|
* Test passing in a LIMIT with OFFSET clause string.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user