Skip to content

Commit d0dd552

Browse files
authored
Merge pull request #23 from ukfast/allow_null_sort_order_to_be_changed
Allow null sort order to be changed
2 parents d6005ca + 4fddb22 commit d0dd552

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ Sieve will also allow consumers of your API to specify sort order. You can do th
8989
* `sort=age:asc`
9090
* `sort=id:desc`
9191

92+
By default, MySQL will sort `null` values first for ascending sorts and last for descending sorts. Depending on the context
93+
of the column this may not be the desired functionality. You can change this using the following URL queries:
94+
95+
* `sort=priority:asc_nulls_last`
96+
* `sort=priority:desc_nulls_first`
97+
98+
9299
You can set a default sort using the `setDefaultSort` on the`Sieve` class.
93100

94101
```php

src/Sieve.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class Sieve
1212

1313
protected $defaultSort = null;
1414

15+
protected $sortable = [];
16+
1517
public function __construct(Request $request)
1618
{
1719
$this->request = $request;
@@ -37,7 +39,7 @@ public function getFilters()
3739
public function apply($queryBuilder)
3840
{
3941
foreach ($this->getFilters() as $sieveFilter) {
40-
/** @var Filter */
42+
/** @var ModifiesQueries */
4143
$filter = $sieveFilter['filter'];
4244
$property = $sieveFilter['property'];
4345

@@ -77,6 +79,16 @@ public function apply($queryBuilder)
7779
if ($this->getSort() == "$property:asc") {
7880
$queryBuilder->orderBy($column, "asc");
7981
}
82+
83+
if ($this->getSort() == "$property:asc_nulls_last") {
84+
$queryBuilder->orderByRaw("ISNULL(\"$column\") asc")
85+
->orderBy($column, 'asc');
86+
}
87+
88+
if ($this->getSort() == "$property:desc_nulls_first") {
89+
$queryBuilder->orderByRaw("ISNULL(\"$column\") desc")
90+
->orderBy($column, 'desc');
91+
}
8092
}
8193

8294
return $this;

tests/SieveTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,54 @@ public function applies_sieve_sorts_to_a_query_builder_asc()
7474
);
7575
}
7676

77+
/**
78+
* @test
79+
*/
80+
public function applies_sieve_sorts_to_a_query_builder_asc_nulls_last()
81+
{
82+
$request = Request::create('/', 'GET', [
83+
'sort' => 'name:asc_nulls_last',
84+
]);
85+
86+
$seive = new Sieve($request);
87+
$seive->addFilter('name', new StringFilter);
88+
89+
/** @var Builder */
90+
$builder = $this->app->make(Builder::class);
91+
$builder->from('pets');
92+
93+
$seive->apply($builder);
94+
95+
$this->assertEquals(
96+
'select * from "pets" order by ISNULL("name") asc, "name" asc',
97+
$builder->toSql()
98+
);
99+
}
100+
101+
/**
102+
* @test
103+
*/
104+
public function applies_sieve_sorts_to_a_query_builder_desc_nulls_first()
105+
{
106+
$request = Request::create('/', 'GET', [
107+
'sort' => 'name:desc_nulls_first',
108+
]);
109+
110+
$seive = new Sieve($request);
111+
$seive->addFilter('name', new StringFilter);
112+
113+
/** @var Builder */
114+
$builder = $this->app->make(Builder::class);
115+
$builder->from('pets');
116+
117+
$seive->apply($builder);
118+
119+
$this->assertEquals(
120+
'select * from "pets" order by ISNULL("name") desc, "name" desc',
121+
$builder->toSql()
122+
);
123+
}
124+
77125
/**
78126
* @test
79127
*/

0 commit comments

Comments
 (0)