Skip to content

Commit

Permalink
Added method Hyperf\Database\Query\Builder::forPageBeforeId (#2411)
Browse files Browse the repository at this point in the history
  • Loading branch information
limingxinleo committed Sep 2, 2020
1 parent 2f6596d commit 6bb40b6
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG-2.0.md
@@ -1,5 +1,9 @@
# v2.0.10 - TBD

## Added

- [#2411](https://github.com/hyperf/hyperf/pull/2411) Added method `Hyperf\Database\Query\Builder::forPageBeforeId` for database.

# v2.0.9 - 2020-08-31

## Added
Expand Down
23 changes: 21 additions & 2 deletions src/database/src/Query/Builder.php
Expand Up @@ -1705,13 +1705,32 @@ public function forPage($page, $perPage = 15)
return $this->skip(($page - 1) * $perPage)->take($perPage);
}

/**
* Constrain the query to the previous "page" of results before a given ID.
*
* @param int $perPage
* @param null|int $lastId
* @param string $column
* @return $this
*/
public function forPageBeforeId($perPage = 15, $lastId = 0, $column = 'id')
{
$this->orders = $this->removeExistingOrdersFor($column);

if (! is_null($lastId)) {
$this->where($column, '<', $lastId);
}

return $this->orderBy($column, 'desc')->limit($perPage);
}

/**
* Constrain the query to the next "page" of results after a given ID.
*
* @param int $perPage
* @param null|int $lastId
* @param string $column
* @return \Hyperf\Database\Query\Builder|static
* @return $this
*/
public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
{
Expand All @@ -1721,7 +1740,7 @@ public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
$this->where($column, '>', $lastId);
}

return $this->orderBy($column, 'asc')->take($perPage);
return $this->orderBy($column, 'asc')->limit($perPage);
}

/**
Expand Down
96 changes: 96 additions & 0 deletions src/database/tests/ModelRealBuilderTest.php
@@ -0,0 +1,96 @@
<?php

declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Database;

use Hyperf\Database\Events\QueryExecuted;
use HyperfTest\Database\Stubs\ContainerStub;
use HyperfTest\Database\Stubs\Model\User;
use Mockery;
use PHPUnit\Framework\TestCase;
use Psr\EventDispatcher\EventDispatcherInterface;
use Swoole\Coroutine\Channel;

/**
* @internal
* @coversNothing
*/
class ModelRealBuilderTest extends TestCase
{
/**
* @var array
*/
protected $channel;

protected function setUp()
{
$this->channel = new Channel(999);
}

protected function tearDown()
{
Mockery::close();
}

public function testForPageBeforeId()
{
$this->getContainer();

User::query()->forPageBeforeId(2)->get();
User::query()->forPageBeforeId(2, null)->get();
User::query()->forPageBeforeId(2, 1)->get();

$sqls = [
['select * from `user` where `id` < ? order by `id` desc limit 2', [0]],
['select * from `user` order by `id` desc limit 2', []],
['select * from `user` where `id` < ? order by `id` desc limit 2', [1]],
];
while ($event = $this->channel->pop(0.001)) {
if ($event instanceof QueryExecuted) {
$this->assertSame([$event->sql, $event->bindings], array_shift($sqls));
}
}
}

public function testForPageAfterId()
{
$this->getContainer();

User::query()->forPageAfterId(2)->get();
User::query()->forPageAfterId(2, null)->get();
User::query()->forPageAfterId(2, 1)->get();

$sqls = [
['select * from `user` where `id` > ? order by `id` asc limit 2', [0]],
['select * from `user` order by `id` asc limit 2', []],
['select * from `user` where `id` > ? order by `id` asc limit 2', [1]],
];
while ($event = $this->channel->pop(0.001)) {
if ($event instanceof QueryExecuted) {
$this->assertSame([$event->sql, $event->bindings], array_shift($sqls));
}
}
}

protected function getContainer()
{
$dispatcher = Mockery::mock(EventDispatcherInterface::class);
$dispatcher->shouldReceive('dispatch')->with(Mockery::any())->andReturnUsing(function ($event) {
$this->channel->push($event);
});
$container = ContainerStub::getContainer(function ($conn) use ($dispatcher) {
$conn->setEventDispatcher($dispatcher);
});
$container->shouldReceive('get')->with(EventDispatcherInterface::class)->andReturn($dispatcher);

return $container;
}
}

0 comments on commit 6bb40b6

Please sign in to comment.