Support type Closure|Expression|ModelBuilder|static|string of $column for QueryBuilder::orderBy(). (#6868)

Co-authored-by: 李铭昕 <715557344@qq.com>
This commit is contained in:
@长久同学 2024-06-14 13:20:46 +08:00 committed by GitHub
parent c7ff73ad0d
commit 7c128957a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 6 deletions

View File

@ -10,6 +10,7 @@
## Optimized
- [#6870](https://github.com/hyperf/hyperf/pull/6870) Updated default path for factories in Model Factory construct method.
- [#6868](https://github.com/hyperf/hyperf/pull/6868) Support type `Closure|Expression|ModelBuilder|static|string` of `$column` for `QueryBuilder::orderBy()`.
# v3.1.26 - 2024-06-13

View File

@ -1806,12 +1806,19 @@ class Builder
/**
* Add an "order by" clause to the query.
*
* @param string $column
* @param string $direction
* @param Closure|Expression|ModelBuilder|static|string $column
* @return $this
*/
public function orderBy($column, $direction = 'asc')
public function orderBy(mixed $column, string $direction = 'asc'): static
{
if ($this->isQueryable($column)) {
[$query, $bindings] = $this->createSub($column);
$column = new Expression('(' . $query . ')');
$this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');
}
$this->{$this->unions ? 'unionOrders' : 'orders'}[] = [
'column' => $column,
'direction' => strtolower($direction) === 'asc' ? 'asc' : 'desc',

View File

@ -996,9 +996,7 @@ class Grammar extends BaseGrammar
protected function compileOrdersToArray(Builder $query, $orders): array
{
return array_map(function ($order) {
return ! isset($order['sql'])
? $this->wrap($order['column']) . ' ' . $order['direction']
: $order['sql'];
return $order['sql'] ?? $this->wrap($order['column']) . ' ' . $order['direction'];
}, $orders);
}

View File

@ -13,9 +13,12 @@ declare(strict_types=1);
namespace HyperfTest\Database;
use Hyperf\Database\MySqlConnection;
use Hyperf\Database\Query\Builder;
use Hyperf\Database\Query\Grammars\MySqlGrammar as MySqlQueryGrammar;
use Hyperf\Database\Schema\Grammars\MySqlGrammar;
use Hyperf\Support\Fluent;
use Hyperf\Support\Reflection\ClassInvoker;
use Mockery;
use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\TestCase;
@ -39,4 +42,22 @@ class GrammarTest extends TestCase
$grammar = $conn->getQueryGrammar();
$this->assertInstanceOf(MySqlQueryGrammar::class, $grammar);
}
public function testCompileOrdersToArray()
{
$grammar = new MySqlQueryGrammar();
/** @var MySqlQueryGrammar $grammar */
$grammar = new ClassInvoker($grammar);
$res = $grammar->compileOrdersToArray(Mockery::mock(Builder::class), [
[
'column' => 'id',
'direction' => 'asc',
],
[
'sql' => 'name desc',
],
]);
$this->assertSame(['`id` asc', 'name desc'], $res);
}
}

View File

@ -172,6 +172,15 @@ class ModelRealBuilderTest extends TestCase
}
}
public function testOrderByModelBuilder()
{
$this->getContainer();
$sql = User::query()->orderBy(User::query()->select('id')->limit(1))->toSql();
$this->assertSame('select * from `user` order by (select `id` from `user` limit 1) asc', $sql);
}
public function testForPageAfterId()
{
$this->getContainer();