diff --git a/src/System/Database/MyModel/Model.php b/src/System/Database/MyModel/Model.php index 5a56a9d3..0a2b351c 100644 --- a/src/System/Database/MyModel/Model.php +++ b/src/System/Database/MyModel/Model.php @@ -49,7 +49,9 @@ class Model implements \ArrayAccess, \IteratorAggregate protected int $limit_start = 0; protected int $limit_end = 0; protected int $offset = 0; - protected string $sort_order = ''; + + /** @var array */ + protected $sort_order = []; // magic ---------------------- @@ -543,14 +545,14 @@ public function limitOffset(int $limit, int $offset) /** * Set sort column and order * column name must register. - * - * @return static */ - public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null) + public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self { $order = 0 === $order_using ? 'ASC' : 'DESC'; $belong_to ??= $this->table_name; - $this->sort_order = "ORDER BY {$belong_to}.{$column_name} {$order}"; + $res = "{$belong_to}.{$column_name}"; + + $this->sort_order[$res] = $order; return $this; } diff --git a/src/System/Database/MyQuery/Query.php b/src/System/Database/MyQuery/Query.php index ce456902..ff2ea582 100644 --- a/src/System/Database/MyQuery/Query.php +++ b/src/System/Database/MyQuery/Query.php @@ -38,8 +38,8 @@ abstract class Query /** @var int offest */ protected $_offset = 0; - /** @var string Sort result ASC|DESC */ - protected $_sort_order = ''; + /** @var array Sort result ASC|DESC */ + protected array $_sort_order = []; public const ORDER_ASC = 0; public const ORDER_DESC = 1; diff --git a/src/System/Database/MyQuery/Select.php b/src/System/Database/MyQuery/Select.php index aea71c30..f84f8a07 100644 --- a/src/System/Database/MyQuery/Select.php +++ b/src/System/Database/MyQuery/Select.php @@ -166,12 +166,32 @@ public function limitOffset(int $limit, int $offset): self public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null) { $order = 0 === $order_using ? 'ASC' : 'DESC'; - $belong_to ??= null === $this->_sub_query ? "{$this->_table}" : $this->_sub_query->getAlias(); - $this->_sort_order = "ORDER BY $belong_to.$column_name $order"; + $belong_to ??= null === $this->_sub_query ? $this->_table : $this->_sub_query->getAlias(); + $res = "{$belong_to}.{$column_name}"; + + $this->_sort_order[$res] = $order; return $this; } + /** + * Set sort column and order + * with Column if not null. + */ + public function orderIfNotNull(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self + { + return $this->order("{$column_name} IS NOT NULL", $order_using, $belong_to); + } + + /** + * Set sort column and order + * with Column if null. + */ + public function orderIfNull(string $column_name, int $order_using = MyQuery::ORDER_ASC, ?string $belong_to = null): self + { + return $this->order("{$column_name} IS NULL", $order_using, $belong_to); + } + /** * Adds one or more columns to the * GROUP BY clause of the SQL query. @@ -195,7 +215,7 @@ protected function builder(): string $build['join'] = $this->joinBuilder(); $build['where'] = $this->getWhere(); $build['group_by'] = $this->getGroupBy(); - $build['sort_order'] = $this->_sort_order; + $build['sort_order'] = $this->getOrderBy(); $build['limit'] = $this->getLimit(); $condition = implode(' ', array_filter($build, fn ($item) => $item !== '')); @@ -232,7 +252,26 @@ private function getGroupBy(): string return "GROUP BY {$group_by}"; } - public function sortOrderRef(int $limit_start, int $limit_end, int $offset, string $sort_ordder): void + private function getOrderBy(): string + { + if ([] === $this->_sort_order) { + return ''; + } + + $orders = []; + foreach ($this->_sort_order as $column => $order) { + $orders[] = "{$column} {$order}"; + } + + $orders = implode(', ', $orders); + + return "ORDER BY {$orders}"; + } + + /** + * @param array $sort_ordder + */ + public function sortOrderRef(int $limit_start, int $limit_end, int $offset, $sort_ordder): void { $this->_limit_start = $limit_start; $this->_limit_end = $limit_end; diff --git a/tests/DataBase/Query/SelectTest.php b/tests/DataBase/Query/SelectTest.php index 135dca0c..e22a5a31 100644 --- a/tests/DataBase/Query/SelectTest.php +++ b/tests/DataBase/Query/SelectTest.php @@ -302,4 +302,46 @@ public function itCanSelectWithGroupBy(): void $select_multy->__toString() ); } + + /** @test */ + public function itCanGenerateMultyOrder(): void + { + $select = MyQuery::from('base_1', $this->PDO) + ->select() + ->order('id', MyQuery::ORDER_ASC) + ->order('name', MyQuery::ORDER_DESC) + ; + + $this->assertEquals( + 'SELECT * FROM base_1 ORDER BY base_1.id ASC, base_1.name DESC', + $select->__toString(), + 'order by query' + ); + } + + /** @test */ + public function itCanSelectWithOrderIfNotNull() + { + $select = MyQuery::from('test', $this->PDO) + ->select() + ->orderIfNotNull('column_1'); + + $this->assertEquals( + 'SELECT * FROM test ORDER BY test.column_1 IS NOT NULL ASC', + $select->__toString() + ); + } + + /** @test */ + public function itCanSelectWithOrderIfNull() + { + $select = MyQuery::from('test', $this->PDO) + ->select() + ->orderIfNull('column_1'); + + $this->assertEquals( + 'SELECT * FROM test ORDER BY test.column_1 IS NULL ASC', + $select->__toString() + ); + } }