Implement callback checking in the provider

This commit is contained in:
Tim Nagel 2014-06-16 16:17:04 +10:00
parent 66d2410999
commit e54cc3c243
4 changed files with 126 additions and 28 deletions

View file

@ -6,6 +6,7 @@ use Doctrine\Common\Persistence\ManagerRegistry;
use Elastica\Exception\Bulk\ResponseException as BulkResponseException; use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface; use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider; use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
use FOS\ElasticaBundle\Provider\IndexableInterface;
abstract class AbstractProvider extends BaseAbstractProvider abstract class AbstractProvider extends BaseAbstractProvider
{ {
@ -15,13 +16,19 @@ abstract class AbstractProvider extends BaseAbstractProvider
* Constructor. * Constructor.
* *
* @param ObjectPersisterInterface $objectPersister * @param ObjectPersisterInterface $objectPersister
* @param string $objectClass * @param IndexableInterface $indexable
* @param array $options * @param string $objectClass
* @param ManagerRegistry $managerRegistry * @param array $options
* @param ManagerRegistry $managerRegistry
*/ */
public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $options, $managerRegistry) public function __construct(
{ ObjectPersisterInterface $objectPersister,
parent::__construct($objectPersister, $objectClass, array_merge(array( IndexableInterface $indexable,
$objectClass,
array $options,
ManagerRegistry $managerRegistry
) {
parent::__construct($objectPersister, $indexable, $objectClass, array_merge(array(
'clear_object_manager' => true, 'clear_object_manager' => true,
'debug_logging' => false, 'debug_logging' => false,
'ignore_errors' => false, 'ignore_errors' => false,
@ -53,6 +60,10 @@ abstract class AbstractProvider extends BaseAbstractProvider
$stepStartTime = microtime(true); $stepStartTime = microtime(true);
} }
$objects = $this->fetchSlice($queryBuilder, $batchSize, $offset); $objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
if ($loggerClosure) {
$stepNbObjects = count($objects);
}
$objects = array_filter($objects, array($this, 'isObjectIndexable'));
if (!$ignoreErrors) { if (!$ignoreErrors) {
$this->objectPersister->insertMany($objects); $this->objectPersister->insertMany($objects);
@ -73,7 +84,6 @@ abstract class AbstractProvider extends BaseAbstractProvider
usleep($sleep); usleep($sleep);
if ($loggerClosure) { if ($loggerClosure) {
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset; $stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects; $percentComplete = 100 * $stepCount / $nbObjects;
$timeDifference = microtime(true) - $stepStartTime; $timeDifference = microtime(true) - $stepStartTime;

View file

@ -68,4 +68,11 @@ interface ObjectPersisterInterface
* @param array $identifiers array of domain model object identifiers * @param array $identifiers array of domain model object identifiers
*/ */
public function deleteManyByIdentifiers(array $identifiers); public function deleteManyByIdentifiers(array $identifiers);
/**
* Returns the elastica type used by this persister
*
* @return \Elastica\Type
*/
public function getType();
} }

View file

@ -24,23 +24,48 @@ abstract class AbstractProvider implements ProviderInterface
*/ */
protected $options; protected $options;
/**
* @var Indexable
*/
private $indexable;
/** /**
* Constructor. * Constructor.
* *
* @param ObjectPersisterInterface $objectPersister * @param ObjectPersisterInterface $objectPersister
* @param string $objectClass * @param IndexableInterface $indexable
* @param array $options * @param string $objectClass
* @param array $options
*/ */
public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $options = array()) public function __construct(
{ ObjectPersisterInterface $objectPersister,
$this->objectPersister = $objectPersister; IndexableInterface $indexable,
$objectClass,
array $options = array()
) {
$this->indexable = $indexable;
$this->objectClass = $objectClass; $this->objectClass = $objectClass;
$this->objectPersister = $objectPersister;
$this->options = array_merge(array( $this->options = array_merge(array(
'batch_size' => 100, 'batch_size' => 100,
), $options); ), $options);
} }
/**
* Checks if a given object should be indexed or not.
*
* @param object $object
* @return bool
*/
protected function isObjectIndexable($object)
{
$typeName = $this->objectPersister->getType()->getName();
$indexName = $this->objectPersister->getType()->getIndex()->getName();
return $this->indexable->isObjectIndexable($indexName, $typeName, $object);
}
/** /**
* Get string with RAM usage information (current and peak) * Get string with RAM usage information (current and peak)
* *

View file

@ -9,24 +9,42 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
private $objectPersister; private $objectPersister;
private $options; private $options;
private $managerRegistry; private $managerRegistry;
private $indexable;
public function setUp() public function setUp()
{ {
if (!interface_exists('Doctrine\Common\Persistence\ManagerRegistry')) { if (!interface_exists('Doctrine\Common\Persistence\ManagerRegistry')) {
$this->markTestSkipped('Doctrine Common is not available.'); $this->markTestSkipped('Doctrine Common is not available.');
} }
$this->objectClass = 'objectClass'; $this->objectClass = 'objectClass';
$this->options = array('debug_logging' => true); $this->options = array('debug_logging' => true);
$this->objectPersister = $this->getMockObjectPersister(); $this->objectPersister = $this->getMockObjectPersister();
$this->managerRegistry = $this->getMockManagerRegistry(); $this->managerRegistry = $this->getMockManagerRegistry();
$this->objectManager = $this->getMockObjectManager(); $this->objectManager = $this->getMockObjectManager();
$this->indexable = $this->getMockIndexable();
$this->managerRegistry->expects($this->any()) $index = $this->getMockBuilder('Elastica\Index')->disableOriginalConstructor()->getMock();
->method('getManagerForClass') $index->expects($this->any())
->with($this->objectClass) ->method('getName')
->will($this->returnValue($this->objectManager)); ->will($this->returnValue('index'));
$type = $this->getMockBuilder('Elastica\Type')->disableOriginalConstructor()->getMock();
$type->expects($this->any())
->method('getName')
->will($this->returnValue('type'));
$type->expects($this->any())
->method('getIndex')
->will($this->returnValue($index));
$this->objectPersister->expects($this->any())
->method('getType')
->will($this->returnValue($type));
$this->managerRegistry->expects($this->any())
->method('getManagerForClass')
->with($this->objectClass)
->will($this->returnValue($this->objectManager));
} }
/** /**
@ -59,14 +77,13 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
->with($queryBuilder, $batchSize, $offset) ->with($queryBuilder, $batchSize, $offset)
->will($this->returnValue($objects)); ->will($this->returnValue($objects));
$this->objectPersister->expects($this->at($i))
->method('insertMany')
->with($objects);
$this->objectManager->expects($this->at($i)) $this->objectManager->expects($this->at($i))
->method('clear'); ->method('clear');
} }
$this->objectPersister->expects($this->exactly(count($objectsByIteration)))
->method('insertMany');
$provider->populate(); $provider->populate();
} }
@ -159,6 +176,36 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
$provider->populate(null, array('ignore-errors' => false)); $provider->populate(null, array('ignore-errors' => false));
} }
public function testPopulateRunsIndexCallable()
{
$nbObjects = 2;
$objects = array(1, 2);
$provider = $this->getMockAbstractProvider();
$provider->expects($this->any())
->method('countObjects')
->will($this->returnValue($nbObjects));
$provider->expects($this->any())
->method('fetchSlice')
->will($this->returnValue($objects));
$this->indexable->expects($this->at(0))
->method('isObjectIndexable')
->with('index', 'type', 1)
->will($this->returnValue(false));
$this->indexable->expects($this->at(1))
->method('isObjectIndexable')
->with('index', 'type', 2)
->will($this->returnValue(true));
$this->objectPersister->expects($this->once())
->method('insertMany')
->with(array(1 => 2));
$provider->populate();
}
/** /**
* @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject * @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject
*/ */
@ -166,6 +213,7 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{ {
return $this->getMockForAbstractClass('FOS\ElasticaBundle\Doctrine\AbstractProvider', array( return $this->getMockForAbstractClass('FOS\ElasticaBundle\Doctrine\AbstractProvider', array(
$this->objectPersister, $this->objectPersister,
$this->indexable,
$this->objectClass, $this->objectClass,
$this->options, $this->options,
$this->managerRegistry, $this->managerRegistry,
@ -205,6 +253,14 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{ {
return $this->getMock('FOS\ElasticaBundle\Persister\ObjectPersisterInterface'); return $this->getMock('FOS\ElasticaBundle\Persister\ObjectPersisterInterface');
} }
/**
* @return \FOS\ElasticaBundle\Provider\IndexableInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private function getMockIndexable()
{
return $this->getMock('FOS\ElasticaBundle\Provider\IndexableInterface');
}
} }
/** /**