Skip to content

Commit 5b80112

Browse files
committed
- Added OrderBySpecification
- Added a way to define OrderBy by external parameters
1 parent 01769e8 commit 5b80112

File tree

5 files changed

+108
-16
lines changed

5 files changed

+108
-16
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
language: php
22

33
php:
4-
- 7
4+
- 7.1
5+
- 7.0
56
- 5.6
67
- 5.5
78
- 5.4
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
namespace Kir\MySQL\Builder\Expr;
3+
4+
class DBExprOrderBySpec implements OrderBySpecification {
5+
/** @var array[] */
6+
private $fields = [];
7+
8+
/**
9+
* @param $spec
10+
* @param $sortFieldsSpec
11+
*/
12+
public function __construct($spec, $sortFieldsSpec) {
13+
$expressions = [];
14+
foreach($spec as $specReference => $dbExpr) {
15+
if(is_int($specReference)) {
16+
$specReference = $dbExpr;
17+
}
18+
$expressions[$specReference] = $dbExpr;
19+
}
20+
foreach($sortFieldsSpec as $sortFieldSpec) {
21+
if(array_key_exists(0, $sortFieldSpec) && array_key_exists($sortFieldSpec[0], $expressions)) {
22+
$direction = 'ASC';
23+
if(array_key_exists(1, $sortFieldSpec) && strtoupper($sortFieldSpec[1]) !== 'ASC') {
24+
$direction = 'DESC';
25+
}
26+
$this->fields[] = [
27+
$expressions[$sortFieldSpec[0]],
28+
$direction
29+
];
30+
}
31+
}
32+
}
33+
34+
/**
35+
* Returns an array[], where each value is a [db-expression, sort-direction]
36+
* The sort-direction can be either ASC or DESC
37+
*
38+
* @return array[]
39+
*/
40+
public function getFields() {
41+
return $this->fields;
42+
}
43+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
namespace Kir\MySQL\Builder\Expr;
3+
4+
interface OrderBySpecification {
5+
/**
6+
* Returns an array[], where each value is a [db-expression, sort-direction]
7+
* The sort-direction can be either ASC or DESC
8+
*
9+
* @return array[]
10+
*/
11+
public function getFields();
12+
}

src/Builder/Traits/OrderByBuilder.php

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
11
<?php
22
namespace Kir\MySQL\Builder\Traits;
33

4+
use Kir\MySQL\Builder\Expr\OrderBySpecification;
5+
46
trait OrderByBuilder {
57
use AbstractDB;
68

79
/** @var array */
810
private $orderBy = array();
911

1012
/**
11-
* @param string $expression
13+
* @param string|OrderBySpecification $expression
1214
* @param string $direction
1315
* @return $this
1416
*/
1517
public function orderBy($expression, $direction = 'asc') {
16-
if(strtolower($direction) != 'desc') {
17-
$direction = 'ASC';
18-
}
19-
if(is_array($expression)) {
20-
if(!count($expression)) {
21-
return $this;
18+
if($expression instanceof OrderBySpecification) {
19+
foreach($expression->getFields() as $field) {
20+
$this->addOrder($field[0], $field[1]);
2221
}
23-
$arguments = array(
24-
$expression[0],
25-
array_slice($expression, 1)
26-
);
27-
$expression = call_user_func_array(array($this->db(), 'quoteExpression'), $arguments);
22+
return $this;
2823
}
29-
$this->orderBy[] = array($expression, $direction);
24+
$this->addOrder($expression, $direction);
3025
return $this;
3126
}
32-
27+
3328
/**
29+
* @param string $fieldName
30+
* @param array $values
31+
* @return $this
3432
*/
3533
public function orderByValues($fieldName, array $values) {
3634
$expr = [];
@@ -57,4 +55,31 @@ protected function buildOrder($query) {
5755
}
5856
return $query.join(",\n", $arr)."\n";
5957
}
58+
59+
/**
60+
* @param string $expression
61+
* @param string $direction
62+
*/
63+
private function addOrder($expression, $direction) {
64+
$direction = $this->fixDirection($direction);
65+
if(is_array($expression)) {
66+
if(!count($expression)) {
67+
return;
68+
}
69+
$arguments = array(
70+
$expression[0],
71+
array_slice($expression, 1)
72+
);
73+
$expression = call_user_func_array(array($this->db(), 'quoteExpression'), $arguments);
74+
}
75+
$this->orderBy[] = array($expression, $direction);
76+
}
77+
78+
/**
79+
* @param string $direction
80+
* @return string
81+
*/
82+
private function fixDirection($direction) {
83+
return strtoupper($direction) !== 'ASC' ? 'DESC' : 'ASC';
84+
}
6085
}

tests/Builder/SelectTest.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace Kir\MySQL\Builder;
33

44
use Kir\MySQL\Builder\Expr\DBExprFilter;
5+
use Kir\MySQL\Builder\Expr\DBExprOrderBySpec;
56
use Kir\MySQL\Builder\Expr\OptionalDBFilterMap;
67
use Kir\MySQL\Builder\Expr\RequiredDBFilterMap;
78
use Kir\MySQL\Builder\Expr\RequiredValueNotFoundException;
@@ -307,7 +308,7 @@ public function testOptionalExpressions() {
307308
$this->assertEquals("SELECT\n\tt.field\nFROM\n\ttest t\n", $query);
308309
}
309310

310-
public function testRequired() {
311+
public function testRequiredExpression() {
311312
$filter = ['filter' => ['name' => 'aaa']];
312313
$req = new RequiredDBFilterMap($filter);
313314

@@ -327,4 +328,14 @@ public function testRequired() {
327328
->where($req('t.field=?', 'filter.id'))
328329
->asString();
329330
}
331+
332+
public function testSortSpecification() {
333+
$query = TestSelect::create()
334+
->field('t.field')
335+
->from('t', 'test')
336+
->orderBy(new DBExprOrderBySpec(['field1', 'field2'], [['field2', 'ASC'], ['field1', 'DESC'], ['field3' => 'ASC']]))
337+
->asString();
338+
339+
$this->assertEquals("SELECT\n\tt.field\nFROM\n\ttest t\nORDER BY\n\tfield2 ASC,\n\tfield1 DESC\n", $query);
340+
}
330341
}

0 commit comments

Comments
 (0)