Skip to content

Commit

Permalink
Merge pull request #32 from ans-group/multiple-sorts
Browse files Browse the repository at this point in the history
Allow more than one sort to be applied
  • Loading branch information
Gman98ish authored Jan 13, 2023
2 parents e99923d + 705bfcc commit dcfa656
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 13 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ Sieve will also allow consumers of your API to specify sort order. You can do th
* `sort=age:asc`
* `sort=id:desc`

If you do not specify a direction (for instance `sort=age`) then the sorting will be carried out in ascending order.

You can specify more than one column to sort by as a comma separated list. These will be applied in the order given.
For instance `sort=age:asc,name:asc` will return people in age order, then alphabetically.

By default, MySQL will sort `null` values first for ascending sorts and last for descending sorts. Depending on the context
of the column this may not be the desired functionality. You can change this using the following URL queries:

Expand Down
29 changes: 16 additions & 13 deletions src/Sieve.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,25 @@ public function apply($queryBuilder)
continue;
}

if ($this->getSort() == "$property:desc") {
$queryBuilder->orderBy($column, "desc");
}
$sorts = explode(',', $this->getSort());
foreach ($sorts as $sort) {
if ($sort == "$property:desc") {
$queryBuilder->orderBy($column, "desc");
}

if ($this->getSort() == "$property:asc") {
$queryBuilder->orderBy($column, "asc");
}
if ($sort == "$property:asc" || $sort == $property) {
$queryBuilder->orderBy($column, "asc");
}

if ($this->getSort() == "$property:asc_nulls_last") {
$queryBuilder->orderByRaw("ISNULL($column) asc")
->orderBy($column, 'asc');
}
if ($sort == "$property:asc_nulls_last") {
$queryBuilder->orderByRaw("ISNULL($column) asc")
->orderBy($column, 'asc');
}

if ($this->getSort() == "$property:desc_nulls_first") {
$queryBuilder->orderByRaw("ISNULL($column) desc")
->orderBy($column, 'desc');
if ($sort == "$property:desc_nulls_first") {
$queryBuilder->orderByRaw("ISNULL($column) desc")
->orderBy($column, 'desc');
}
}
}

Expand Down
74 changes: 74 additions & 0 deletions tests/SieveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ public function set_default_sort_filter()
$this->assertEquals($sieve->getSort(), 'name:desc');
}

/**
* @test
*/
public function applies_sieve_sorts_to_a_query_builder_asc_by_default()
{
$request = Request::create('/', 'GET', [
'sort' => 'name',
]);

$seive = new Sieve($request);
$seive->addFilter('name', new StringFilter);

/** @var Builder */
$builder = $this->app->make(Builder::class);
$builder->from('pets');

$seive->apply($builder);

$this->assertEquals(
'select * from "pets" order by "name" asc',
$builder->toSql()
);
}

/**
* @test
*/
Expand Down Expand Up @@ -122,6 +146,56 @@ public function applies_sieve_sorts_to_a_query_builder_desc_nulls_first()
);
}

/**
* @test
*/
public function allows_multiple_columns_to_be_ordered()
{
$request = Request::create('/', 'GET', [
'sort' => 'type:asc,name:desc',
]);

$seive = new Sieve($request);
$seive->addFilter('type', new StringFilter);
$seive->addFilter('name', new StringFilter);

/** @var Builder */
$builder = $this->app->make(Builder::class);
$builder->from('pets');

$seive->apply($builder);

$this->assertEquals(
'select * from "pets" order by "type" asc, "name" desc',
$builder->toSql()
);
}

/**
* @test
*/
public function allows_multiple_columns_to_be_ordered_including_a_null_column()
{
$request = Request::create('/', 'GET', [
'sort' => 'type:asc,name:desc_nulls_first',
]);

$seive = new Sieve($request);
$seive->addFilter('type', new StringFilter);
$seive->addFilter('name', new StringFilter);

/** @var Builder */
$builder = $this->app->make(Builder::class);
$builder->from('pets');

$seive->apply($builder);

$this->assertEquals(
'select * from "pets" order by "type" asc, ISNULL(name) desc, "name" desc',
$builder->toSql()
);
}

/**
* @test
*/
Expand Down

0 comments on commit dcfa656

Please sign in to comment.