From e027ee799a9846ebb59c5e92e7c00d577b814e1b Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 22 Mar 2021 18:57:55 +0300 Subject: [PATCH 1/3] orderBy: ignore duplicated fields --- src/Query/SelectQuery.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Query/SelectQuery.php b/src/Query/SelectQuery.php index b698db7..aa1ec22 100644 --- a/src/Query/SelectQuery.php +++ b/src/Query/SelectQuery.php @@ -52,7 +52,7 @@ class SelectQuery extends ActiveQuery implements /** @var array */ protected $columns = ['*']; - /** @var array */ + /** @var string[][] */ protected $orderBy = []; /** @var array */ @@ -165,18 +165,30 @@ public function forUpdate(): SelectQuery public function orderBy($expression, $direction = self::SORT_ASC): SelectQuery { if (!is_array($expression)) { - $this->orderBy[] = [$expression, $direction]; - + $this->addOrder($expression, $direction); return $this; } foreach ($expression as $nested => $dir) { - $this->orderBy[] = [$nested, $dir]; + $this->addOrder($nested, $dir); } return $this; } + /** + * @param string $field Field name. + * @param string $order Sorting direction, ASC|DESC. + * @return self|$this + */ + private function addOrder(string $field, string $order): SelectQuery + { + if (!array_key_exists($field, $this->orderBy)) { + $this->orderBy[$field] = [$field, $order]; + } + return $this; + } + /** * Column or expression to group query by. * @@ -420,7 +432,7 @@ public function getTokens(): array 'where' => $this->whereTokens, 'having' => $this->havingTokens, 'groupBy' => $this->groupBy, - 'orderBy' => $this->orderBy, + 'orderBy' => array_values($this->orderBy), 'limit' => $this->limit, 'offset' => $this->offset, 'union' => $this->unionTokens, From aec2cbfcbfe9631b4277591707385576dcd05a8c Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 22 Mar 2021 19:37:18 +0300 Subject: [PATCH 2/3] Fix --- src/Query/SelectQuery.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Query/SelectQuery.php b/src/Query/SelectQuery.php index aa1ec22..4644d3e 100644 --- a/src/Query/SelectQuery.php +++ b/src/Query/SelectQuery.php @@ -52,7 +52,7 @@ class SelectQuery extends ActiveQuery implements /** @var array */ protected $columns = ['*']; - /** @var string[][] */ + /** @var string[][]|FragmentInterface[][] */ protected $orderBy = []; /** @var array */ @@ -177,13 +177,15 @@ public function orderBy($expression, $direction = self::SORT_ASC): SelectQuery } /** - * @param string $field Field name. - * @param string $order Sorting direction, ASC|DESC. + * @param string|FragmentInterface $field + * @param string $order Sorting direction, ASC|DESC. * @return self|$this */ - private function addOrder(string $field, string $order): SelectQuery + private function addOrder($field, string $order): SelectQuery { - if (!array_key_exists($field, $this->orderBy)) { + if (!is_string($field)) { + $this->orderBy[] = [$field, $order]; + } elseif (!array_key_exists($field, $this->orderBy)) { $this->orderBy[$field] = [$field, $order]; } return $this; From bf9f357740e3168821ba21019d10882d8d00b9fd Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 22 Mar 2021 21:30:02 +0300 Subject: [PATCH 3/3] Add test --- tests/Database/SelectQueryTest.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/Database/SelectQueryTest.php b/tests/Database/SelectQueryTest.php index c2478e5..a9df70b 100644 --- a/tests/Database/SelectQueryTest.php +++ b/tests/Database/SelectQueryTest.php @@ -815,6 +815,36 @@ public function testOrderByDesc3(): void ); } + public function testOrderByTwiceBySameName(): void + { + $select = $this->database + ->select() + ->from(['users']) + ->where(['name' => 'Anton']) + ->orderBy('name', 'DESC') + ->orderBy('name', 'ASC'); + + $this->assertSameQuery( + 'SELECT * FROM {users} WHERE {name} = ? ORDER BY {name} DESC', + $select + ); + } + + public function testOrderByTwiceBySameNameArray(): void + { + $select = $this->database + ->select() + ->from(['users']) + ->where(['name' => 'Anton']) + ->orderBy('name', 'DESC') + ->orderBy(['name' => 'ASC', 'foo' => 'DESC']); + + $this->assertSameQuery( + 'SELECT * FROM {users} WHERE {name} = ? ORDER BY {name} DESC, {foo} DESC', + $select + ); + } + public function testMultipleOrderBy(): void { $select = $this->database