Skip to content

Commit 107ce4f

Browse files
authored
feat: enhance sorting functionality with multi-order support and null checks (#410)
1 parent bc99831 commit 107ce4f

File tree

4 files changed

+94
-11
lines changed

4 files changed

+94
-11
lines changed

src/System/Database/MyModel/Model.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ class Model implements \ArrayAccess, \IteratorAggregate
4949
protected int $limit_start = 0;
5050
protected int $limit_end = 0;
5151
protected int $offset = 0;
52-
protected string $sort_order = '';
52+
53+
/** @var array<string, string> */
54+
protected $sort_order = [];
5355

5456
// magic ----------------------
5557

@@ -543,14 +545,14 @@ public function limitOffset(int $limit, int $offset)
543545
/**
544546
* Set sort column and order
545547
* column name must register.
546-
*
547-
* @return static
548548
*/
549-
public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null)
549+
public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self
550550
{
551551
$order = 0 === $order_using ? 'ASC' : 'DESC';
552552
$belong_to ??= $this->table_name;
553-
$this->sort_order = "ORDER BY {$belong_to}.{$column_name} {$order}";
553+
$res = "{$belong_to}.{$column_name}";
554+
555+
$this->sort_order[$res] = $order;
554556

555557
return $this;
556558
}

src/System/Database/MyQuery/Query.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ abstract class Query
3838
/** @var int offest */
3939
protected $_offset = 0;
4040

41-
/** @var string Sort result ASC|DESC */
42-
protected $_sort_order = '';
41+
/** @var array<string, string> Sort result ASC|DESC */
42+
protected array $_sort_order = [];
4343

4444
public const ORDER_ASC = 0;
4545
public const ORDER_DESC = 1;

src/System/Database/MyQuery/Select.php

+43-4
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,32 @@ public function limitOffset(int $limit, int $offset): self
166166
public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null)
167167
{
168168
$order = 0 === $order_using ? 'ASC' : 'DESC';
169-
$belong_to ??= null === $this->_sub_query ? "{$this->_table}" : $this->_sub_query->getAlias();
170-
$this->_sort_order = "ORDER BY $belong_to.$column_name $order";
169+
$belong_to ??= null === $this->_sub_query ? $this->_table : $this->_sub_query->getAlias();
170+
$res = "{$belong_to}.{$column_name}";
171+
172+
$this->_sort_order[$res] = $order;
171173

172174
return $this;
173175
}
174176

177+
/**
178+
* Set sort column and order
179+
* with Column if not null.
180+
*/
181+
public function orderIfNotNull(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self
182+
{
183+
return $this->order("{$column_name} IS NOT NULL", $order_using, $belong_to);
184+
}
185+
186+
/**
187+
* Set sort column and order
188+
* with Column if null.
189+
*/
190+
public function orderIfNull(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self
191+
{
192+
return $this->order("{$column_name} IS NULL", $order_using, $belong_to);
193+
}
194+
175195
/**
176196
* Adds one or more columns to the
177197
* GROUP BY clause of the SQL query.
@@ -195,7 +215,7 @@ protected function builder(): string
195215
$build['join'] = $this->joinBuilder();
196216
$build['where'] = $this->getWhere();
197217
$build['group_by'] = $this->getGroupBy();
198-
$build['sort_order'] = $this->_sort_order;
218+
$build['sort_order'] = $this->getOrderBy();
199219
$build['limit'] = $this->getLimit();
200220

201221
$condition = implode(' ', array_filter($build, fn ($item) => $item !== ''));
@@ -232,7 +252,26 @@ private function getGroupBy(): string
232252
return "GROUP BY {$group_by}";
233253
}
234254

235-
public function sortOrderRef(int $limit_start, int $limit_end, int $offset, string $sort_ordder): void
255+
private function getOrderBy(): string
256+
{
257+
if ([] === $this->_sort_order) {
258+
return '';
259+
}
260+
261+
$orders = [];
262+
foreach ($this->_sort_order as $column => $order) {
263+
$orders[] = "{$column} {$order}";
264+
}
265+
266+
$orders = implode(', ', $orders);
267+
268+
return "ORDER BY {$orders}";
269+
}
270+
271+
/**
272+
* @param array<string, string> $sort_ordder
273+
*/
274+
public function sortOrderRef(int $limit_start, int $limit_end, int $offset, $sort_ordder): void
236275
{
237276
$this->_limit_start = $limit_start;
238277
$this->_limit_end = $limit_end;

tests/DataBase/Query/SelectTest.php

+42
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,46 @@ public function itCanSelectWithGroupBy(): void
302302
$select_multy->__toString()
303303
);
304304
}
305+
306+
/** @test */
307+
public function itCanGenerateMultyOrder(): void
308+
{
309+
$select = MyQuery::from('base_1', $this->PDO)
310+
->select()
311+
->order('id', MyQuery::ORDER_ASC)
312+
->order('name', MyQuery::ORDER_DESC)
313+
;
314+
315+
$this->assertEquals(
316+
'SELECT * FROM base_1 ORDER BY base_1.id ASC, base_1.name DESC',
317+
$select->__toString(),
318+
'order by query'
319+
);
320+
}
321+
322+
/** @test */
323+
public function itCanSelectWithOrderIfNotNull()
324+
{
325+
$select = MyQuery::from('test', $this->PDO)
326+
->select()
327+
->orderIfNotNull('column_1');
328+
329+
$this->assertEquals(
330+
'SELECT * FROM test ORDER BY test.column_1 IS NOT NULL ASC',
331+
$select->__toString()
332+
);
333+
}
334+
335+
/** @test */
336+
public function itCanSelectWithOrderIfNull()
337+
{
338+
$select = MyQuery::from('test', $this->PDO)
339+
->select()
340+
->orderIfNull('column_1');
341+
342+
$this->assertEquals(
343+
'SELECT * FROM test ORDER BY test.column_1 IS NULL ASC',
344+
$select->__toString()
345+
);
346+
}
305347
}

0 commit comments

Comments
 (0)