Skip to content

Commit

Permalink
[5.2] Pagination optimize (#14188)
Browse files Browse the repository at this point in the history
* Add test for Eloquent paginate when there are no results

* Tests for Query Builder paginate method

* Make paginate query to get data only if there are any results
  • Loading branch information
mnabialek authored and taylorotwell committed Jul 1, 2016
1 parent 37665f1 commit 41fd377
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/Illuminate/Database/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,12 @@ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page',

$total = $query->getCountForPagination();

$this->forPage(
$results = $total ? $this->forPage(
$page = $page ?: Paginator::resolveCurrentPage($pageName),
$perPage = $perPage ?: $this->model->getPerPage()
);
)->get($columns) : [];

return new LengthAwarePaginator($this->get($columns), $total, $perPage, $page, [
return new LengthAwarePaginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $p

$total = $this->getCountForPagination($columns);

$results = $this->forPage($page, $perPage)->get($columns);
$results = $total ? $this->forPage($page, $perPage)->get($columns) : [];

return new LengthAwarePaginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
Expand Down
18 changes: 18 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,24 @@ public function testPaginatedModelCollectionRetrieval()
$this->assertEquals('foo@gmail.com', $models[0]->email);
}

public function testPaginatedModelCollectionRetrievalWhenNoElements()
{
Paginator::currentPageResolver(function () {
return 1;
});
$models = EloquentTestUser::oldest('id')->paginate(2);

$this->assertEquals(0, $models->count());
$this->assertInstanceOf('Illuminate\Pagination\LengthAwarePaginator', $models);

Paginator::currentPageResolver(function () {
return 2;
});
$models = EloquentTestUser::oldest('id')->paginate(2);

$this->assertEquals(0, $models->count());
}

public function testCountForPaginationWithGrouping()
{
EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
Expand Down
95 changes: 93 additions & 2 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?php

use Illuminate\Pagination\LengthAwarePaginator;
use Mockery as m;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Expression as Raw;
use Illuminate\Pagination\AbstractPaginator as Paginator;

class DatabaseQueryBuilderTest extends PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -1652,6 +1654,95 @@ public function testChunkPaginatesUsingId()
}, 'someIdField');
}

public function testPaginate()
{
$perPage = 16;
$columns = ['test'];
$pageName = 'page-name';
$page = 1;
$builder = $this->getMockQueryBuilder();
$path = 'http://foo.bar?page=3';

$results = collect([['test' => 'foo'], ['test' => 'bar']]);

$builder->shouldReceive('getCountForPagination')->once()->with($columns)->andReturn(2);
$builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturn($builder);
$builder->shouldReceive('get')->once()->andReturn($results);

Paginator::currentPathResolver(function () use ($path) {
return $path;
});

$result = $builder->paginate($perPage, $columns, $pageName, $page);

$this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [
'path' => $path,
'pageName' => $pageName,
]), $result);
}

public function testPaginateWithDefaultArguments()
{
$perPage = 15;
$columns = ['*'];
$pageName = 'page';
$page = 1;
$builder = $this->getMockQueryBuilder();
$path = 'http://foo.bar?page=3';

$results = collect([['test' => 'foo'], ['test' => 'bar']]);

$builder->shouldReceive('getCountForPagination')->once()->with($columns)->andReturn(2);
$builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturn($builder);
$builder->shouldReceive('get')->once()->andReturn($results);

Paginator::currentPageResolver(function () use ($path) {
return 1;
});

Paginator::currentPathResolver(function () use ($path) {
return $path;
});

$result = $builder->paginate();

$this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [
'path' => $path,
'pageName' => $pageName,
]), $result);
}

public function testPaginateWhenNoResults()
{
$perPage = 15;
$columns = ['*'];
$pageName = 'page';
$page = 1;
$builder = $this->getMockQueryBuilder();
$path = 'http://foo.bar?page=3';

$results = [];

$builder->shouldReceive('getCountForPagination')->once()->with($columns)->andReturn(0);
$builder->shouldNotReceive('forPage');
$builder->shouldNotReceive('get');

Paginator::currentPageResolver(function () use ($path) {
return 1;
});

Paginator::currentPathResolver(function () use ($path) {
return $path;
});

$result = $builder->paginate();

$this->assertEquals(new LengthAwarePaginator($results, 0, $perPage, $page, [
'path' => $path,
'pageName' => $pageName,
]), $result);
}

protected function getBuilder()
{
$grammar = new Illuminate\Database\Query\Grammars\Grammar;
Expand Down Expand Up @@ -1705,11 +1796,11 @@ protected function getMySqlBuilderWithProcessor()
*/
protected function getMockQueryBuilder()
{
$builder = m::mock('Illuminate\Database\Query\Builder[forPageAfterId,get]', [
$builder = m::mock('Illuminate\Database\Query\Builder', [
m::mock('Illuminate\Database\ConnectionInterface'),
new Illuminate\Database\Query\Grammars\Grammar,
m::mock('Illuminate\Database\Query\Processors\Processor'),
]);
])->makePartial();

return $builder;
}
Expand Down

0 comments on commit 41fd377

Please sign in to comment.