Skip to content

Commit

Permalink
Merge pull request #11195 from ryomo/issue-2411
Browse files Browse the repository at this point in the history
Fix total_items and total_pages in Paginator when it has `GROUP BY` #2411
  • Loading branch information
andresgutierrez committed Dec 12, 2015
2 parents e8385a3 + 362a5a9 commit fc8ece5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# [2.0.10](https://github.com/phalcon/cphalcon/releases/tag/phalcon-v2.0.10) (2015-XX-XX)
- ORM: Added support for DATE columns in Oracle
- Fixed wrong total_items and total_pages in Paginator when the query builder has set groupBy()

# [2.0.9](https://github.com/phalcon/cphalcon/releases/tag/phalcon-v2.0.9) (2015-11-24)
- Fixed bug that double serializes data using Redis adapter
Expand Down
9 changes: 9 additions & 0 deletions phalcon/paginator/adapter/querybuilder.zep
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ class QueryBuilder extends Adapter implements AdapterInterface
*/
totalBuilder->columns("COUNT(*) [rowcount]");

/**
* Change 'COUNT()' parameters, when the query contains 'GROUP BY'
*/
var groups = totalBuilder->getGroupBy();
if !empty groups {
var groupColumn = implode(", ", groups);
totalBuilder->groupBy(null)->columns(["COUNT(DISTINCT ".groupColumn.") AS rowcount"]);
}

/**
* Remove the 'ORDER BY' clause, PostgreSQL requires this
*/
Expand Down
108 changes: 108 additions & 0 deletions unit-tests/PaginatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ public function testQueryBuilderPaginator()
$this->assertEquals($page->limit, 10);

$this->assertEquals($page->current, 1);
$this->assertEquals($page->total_items, 2180);
$this->assertEquals($page->total_pages, 218);

$this->assertInternalType('int', $page->total_items);
Expand Down Expand Up @@ -429,4 +430,111 @@ public function testQueryBuilderPaginator()
$this->assertEquals($setterResult, $paginator);
}

public function testQueryBuilderPaginatorGroupBy()
{
require 'unit-tests/config.db.php';
if (empty($configMysql)) {
$this->markTestSkipped('Test skipped');
return;
}

$di = $this->_loadDI();

$builder = $di['modelsManager']->createBuilder()
->columns('cedula, nombres')
->from('Personnes')
->orderBy('cedula')
->groupBy(['email']);

$paginator = new Phalcon\Paginator\Adapter\QueryBuilder(array(
"builder" => $builder,
"limit"=> 10,
"page" => 1
));

$page = $paginator->getPaginate();

$this->assertEquals(get_class($page), 'stdClass');

$this->assertEquals(count($page->items), 10);

$this->assertEquals($page->before, 1);
$this->assertEquals($page->next, 2);
$this->assertEquals($page->last, 18);
$this->assertEquals($page->limit, 10);

$this->assertEquals($page->current, 1);
$this->assertEquals($page->total_items, 178);
$this->assertEquals($page->total_pages, 18);

$this->assertInternalType('int', $page->total_items);
$this->assertInternalType('int', $page->total_pages);

//Middle page
$paginator->setCurrentPage(10);

$page = $paginator->getPaginate();

$this->assertEquals(get_class($page), 'stdClass');

$this->assertEquals(count($page->items), 10);

$this->assertEquals($page->before, 9);
$this->assertEquals($page->next, 11);
$this->assertEquals($page->last, 18);

$this->assertEquals($page->current, 10);
$this->assertEquals($page->total_pages, 18);

$this->assertInternalType('int', $page->total_items);
$this->assertInternalType('int', $page->total_pages);

//Last page
$paginator->setCurrentPage(18);

$page = $paginator->getPaginate();

$this->assertEquals(get_class($page), 'stdClass');

$this->assertEquals(count($page->items), 9);

$this->assertEquals($page->before, 17);
$this->assertEquals($page->next, 18);
$this->assertEquals($page->last, 18);

$this->assertEquals($page->current, 18);
$this->assertEquals($page->total_pages, 18);

$this->assertInternalType('int', $page->total_items);
$this->assertInternalType('int', $page->total_pages);

// test of getter/setters of querybuilder adapter

// -- current page --
$currentPage = $paginator->getCurrentPage();
$this->assertEquals($currentPage, 18);

// -- limit --
$rowsLimit = $paginator->getLimit();
$this->assertEquals($rowsLimit, 10);

$setterResult = $paginator->setLimit(25);
$rowsLimit = $paginator->getLimit();
$this->assertEquals($rowsLimit, 25);
$this->assertEquals($setterResult, $paginator);

// -- builder --
$queryBuilder = $paginator->getQueryBuilder();
$this->assertEquals($builder, $queryBuilder);

$builder2 = $di['modelsManager']->createBuilder()
->columns('cedula, nombres')
->from('Personnes')
->groupBy(['email']);

$setterResult = $paginator->setQueryBuilder($builder2);
$queryBuilder = $paginator->getQueryBuilder();
$this->assertEquals($builder2, $queryBuilder);
$this->assertEquals($setterResult, $paginator);
}
}

0 comments on commit fc8ece5

Please sign in to comment.