diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php old mode 100755 new mode 100644 index e692040..07badd7 --- a/Command/PopulateCommand.php +++ b/Command/PopulateCommand.php @@ -45,6 +45,7 @@ class PopulateCommand extends ContainerAwareCommand ->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0) ->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0) ->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)') + ->addOption('no-stop-on-error', null, InputOption::VALUE_NONE, 'Do not stop on errors') ->setDescription('Populates search indexes from providers') ; } diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php index 796a5e4..109cfa0 100644 --- a/Doctrine/AbstractProvider.php +++ b/Doctrine/AbstractProvider.php @@ -3,6 +3,7 @@ namespace FOS\ElasticaBundle\Doctrine; use Doctrine\Common\Persistence\ManagerRegistry; +use Elastica\Exception\Bulk\ResponseException as BulkResponseException; use FOS\ElasticaBundle\Persister\ObjectPersisterInterface; use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider; @@ -23,6 +24,7 @@ abstract class AbstractProvider extends BaseAbstractProvider parent::__construct($objectPersister, $objectClass, array_merge(array( 'clear_object_manager' => true, 'query_builder_method' => 'createQueryBuilder', + 'stop_on_error' => true, ), $options)); $this->managerRegistry = $managerRegistry; @@ -38,6 +40,7 @@ abstract class AbstractProvider extends BaseAbstractProvider $offset = isset($options['offset']) ? intval($options['offset']) : 0; $sleep = isset($options['sleep']) ? intval($options['sleep']) : 0; $batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size']; + $stopOnError = isset($options['no-stop-on-error']) ? empty($options['no-stop-on-error']) : $this->options['stop_on_error']; for (; $offset < $nbObjects; $offset += $batchSize) { if ($loggerClosure) { @@ -45,7 +48,17 @@ abstract class AbstractProvider extends BaseAbstractProvider } $objects = $this->fetchSlice($queryBuilder, $batchSize, $offset); - $this->objectPersister->insertMany($objects); + if (!$stopOnError) { + $this->objectPersister->insertMany($objects); + } else { + try { + $this->objectPersister->insertMany($objects); + } catch(BulkResponseException $e) { + if ($loggerClosure) { + $loggerClosure(sprintf('%s',$e->getMessage())); + } + } + } if ($this->options['clear_object_manager']) { $this->managerRegistry->getManagerForClass($this->objectClass)->clear(); diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php index 0a9aceb..a3836bd 100644 --- a/Tests/Doctrine/AbstractProviderTest.php +++ b/Tests/Doctrine/AbstractProviderTest.php @@ -135,6 +135,28 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase $this->assertTrue($loggerClosureInvoked); } + public function testPopulateNotStopOnError() + { + $nbObjects = 1; + $objects = array(1); + + $provider = $this->getMockAbstractProvider(); + + $provider->expects($this->any()) + ->method('countObjects') + ->will($this->returnValue($nbObjects)); + + $provider->expects($this->any()) + ->method('fetchSlice') + ->will($this->returnValue($objects)); + + $this->objectPersister->expects($this->any()) + ->method('insertMany') + ->will($this->throwException($this->getMockBulkResponseException())); + + $provider->populate(null, array('no-stop-on-error' => true)); + } + /** * @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject */ @@ -148,6 +170,16 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase )); } + /** + * @return \Elastica\Exception\Bulk\ResponseException + */ + private function getMockBulkResponseException() + { + return $this->getMockBuilder('Elastica\Exception\Bulk\ResponseException') + ->disableOriginalConstructor() + ->getMock(); + } + /** * @return \Doctrine\Common\Persistence\ManagerRegistry|\PHPUnit_Framework_MockObject_MockObject */