Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Prevents collision of internal cache ids when using DbSelectAdapter #46

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Adapter/AdapterInterface.php
Original file line number Diff line number Diff line change
@@ -24,4 +24,11 @@ interface AdapterInterface extends Countable
* @return array
*/
public function getItems($offset, $itemCountPerPage);

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId();
}
10 changes: 10 additions & 0 deletions src/Adapter/ArrayAdapter.php
Original file line number Diff line number Diff line change
@@ -57,4 +57,14 @@ public function count()
{
return $this->count;
}

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId()
{
return json_encode($this);
}
}
10 changes: 10 additions & 0 deletions src/Adapter/Callback.php
Original file line number Diff line number Diff line change
@@ -62,4 +62,14 @@ public function count()
{
return call_user_func($this->countCallback);
}

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId()
{
return json_encode($this);
}
}
8 changes: 8 additions & 0 deletions src/Adapter/DbSelect.php
Original file line number Diff line number Diff line change
@@ -151,4 +151,12 @@ protected function getSelectCount()

return $countSelect;
}

/**
* @return string
*/
public function getCacheInternalId()
{
return hash('sha512', $this->select->getSqlString());
}
}
10 changes: 10 additions & 0 deletions src/Adapter/Iterator.php
Original file line number Diff line number Diff line change
@@ -68,4 +68,14 @@ public function count()
{
return $this->count;
}

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId()
{
return json_encode($this);
}
}
10 changes: 10 additions & 0 deletions src/Adapter/NullFill.php
Original file line number Diff line number Diff line change
@@ -56,4 +56,14 @@ public function count()
{
return $this->count;
}

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId()
{
return json_encode($this);
}
}
2 changes: 1 addition & 1 deletion src/Paginator.php
Original file line number Diff line number Diff line change
@@ -865,7 +865,7 @@ protected function _getCacheInternalId()
// @codingStandardsIgnoreEnd
return md5(
get_class($this->getAdapter())
. json_encode($this->getAdapter())
. $this->getAdapter()->getCacheInternalId()
. $this->getItemCountPerPage()
);
}
96 changes: 95 additions & 1 deletion test/PaginatorTest.php
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@

namespace ZendTest\Paginator;

use ArrayIterator;
use ArrayObject;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
@@ -945,6 +944,101 @@ public function testAcceptsComplexAdapters()
$this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems());
}

/**
* This piece of code tests the failure in determine different cache_id for different queries when using the
* generic TestAdapter. All the results will hit the same cache_id when simulating DbSelectAdapter object.
*/
public function testDbSelectAdapterLikeFailure()
{
$paginator = new Paginator\Paginator(
new TestAsset\TestAdapter(function () {
// Simulate some "real" params
return [
'driver' => [
'name' => 'mysql',
'uptime' => new \DateTime('Y-m-d H:i:s'),
],
'sql' => 'Select * FROM table1 where ID = 1'
];
})
);

$reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId');
$reflectionGetCacheInternalId->setAccessible(true);
$firstOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator);

sleep(1);

$paginator = new Paginator\Paginator(
new TestAsset\TestAdapter(function () {
return [
// Simulate some "real" params
'driver' => [
'name' => 'mysql',
'uptime' => new \DateTime('Y-m-d H:i:s'),
],
'sql' => 'Select * FROM table2 where ID = 2'
];
})
);
$reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId');
$reflectionGetCacheInternalId->setAccessible(true);
$secondOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator);

$this->assertEquals($firstOutputGetCacheInternalId, $secondOutputGetCacheInternalId);

$this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems());
}

/**
* This piece of code tests the success in determine different cache_id
* for different queries when using DbSelectAdapter object.
*/
public function testDbSelectAdapterLikeSuccess()
{
$select = new Sql\Select('table1');
$select->where('id = 1');
$select->where('nick = \'test\'');
$paginator = new Paginator\Paginator(
new TestAsset\TestDbSelectAdapter(
$select,
new DbAdapter\Adapter(
new DbAdapter\Driver\Pdo\Pdo(
new DbAdapter\Driver\Pdo\Connection([])
)
)
)
);

$reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId');
$reflectionGetCacheInternalId->setAccessible(true);
$firstOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator);
$this->assertCount(10, $paginator->getCurrentItems());
$this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems());

$select = new Sql\Select('table2');
$select->where('id = 2');
$select->where('nick = \'test\'');
$paginator = new Paginator\Paginator(
new TestAsset\TestDbSelectAdapter(
$select,
new DbAdapter\Adapter(
new DbAdapter\Driver\Pdo\Pdo(
new DbAdapter\Driver\Pdo\Connection([])
)
)
)
);
$reflectionGetCacheInternalId = new ReflectionMethod($paginator, '_getCacheInternalId');
$reflectionGetCacheInternalId->setAccessible(true);
$secondOutputGetCacheInternalId = $reflectionGetCacheInternalId->invoke($paginator);

$this->assertInstanceOf('ArrayObject', $paginator->getCurrentItems());
$this->assertCount(10, $paginator->getCurrentItems());

$this->assertNotEquals($firstOutputGetCacheInternalId, $secondOutputGetCacheInternalId);
}

/**
* @group 6808
* @group 6809
10 changes: 10 additions & 0 deletions test/TestAsset/TestAdapter.php
Original file line number Diff line number Diff line change
@@ -30,4 +30,14 @@ public function getItems($pageNumber, $itemCountPerPage)
{
return new \ArrayObject(range(1, 10));
}

/**
* Returns the internal cache id
*
* @return string
*/
public function getCacheInternalId()
{
return json_encode($this);
}
}
23 changes: 23 additions & 0 deletions test/TestAsset/TestDbSelectAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Paginator\TestAsset;

class TestDbSelectAdapter extends \Zend\Paginator\Adapter\DbSelect
{
public function count()
{
return 10;
}

public function getItems($pageNumber, $itemCountPerPage)
{
return new \ArrayObject(range(1, 10));
}
}