FOSElasticaBundle/Doctrine/AbstractProvider.php

171 lines
5 KiB
PHP
Raw Normal View History

2011-04-17 19:56:32 +02:00
<?php
namespace FOS\ElasticaBundle\Doctrine;
2011-04-17 19:56:32 +02:00
use Doctrine\Common\Persistence\ManagerRegistry;
use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
use FOS\ElasticaBundle\Provider\IndexableInterface;
2015-03-14 09:53:05 +01:00
use Symfony\Component\OptionsResolver\OptionsResolver;
2011-04-17 19:56:32 +02:00
abstract class AbstractProvider extends BaseAbstractProvider
2011-04-17 19:56:32 +02:00
{
2015-03-11 05:54:04 +01:00
/**
* @var SliceFetcherInterface
*/
private $sliceFetcher;
/**
* @var ManagerRegistry
*/
protected $managerRegistry;
/**
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
2015-03-12 11:20:00 +01:00
* @param IndexableInterface $indexable
* @param string $objectClass
2015-03-14 09:53:05 +01:00
* @param array $baseOptions
2015-03-12 11:20:00 +01:00
* @param ManagerRegistry $managerRegistry
2015-03-12 11:57:26 +01:00
* @param SliceFetcherInterface $sliceFetcher
*/
public function __construct(
ObjectPersisterInterface $objectPersister,
IndexableInterface $indexable,
$objectClass,
2015-03-14 09:53:05 +01:00
array $baseOptions,
2014-10-13 15:40:31 +02:00
ManagerRegistry $managerRegistry,
SliceFetcherInterface $sliceFetcher = null
) {
2015-03-14 09:53:05 +01:00
parent::__construct($objectPersister, $indexable, $objectClass, $baseOptions);
$this->managerRegistry = $managerRegistry;
2014-10-13 15:40:31 +02:00
$this->sliceFetcher = $sliceFetcher;
2011-04-17 19:56:32 +02:00
}
2015-03-14 09:53:05 +01:00
/**
* Counts objects that would be indexed using the query builder.
*
* @param object $queryBuilder
*
* @return integer
*/
abstract protected function countObjects($queryBuilder);
/**
* Creates the query builder, which will be used to fetch objects to index.
*
* @param string $method
*
* @return object
*/
abstract protected function createQueryBuilder($method);
/**
* Fetches a slice of objects using the query builder.
*
* @param object $queryBuilder
* @param integer $limit
* @param integer $offset
*
* @return array
*/
abstract protected function fetchSlice($queryBuilder, $limit, $offset);
2011-04-17 19:56:32 +02:00
/**
* {@inheritDoc}
2011-04-17 19:56:32 +02:00
*/
2015-03-14 09:53:05 +01:00
protected function doPopulate($options, \Closure $loggerClosure = null)
2011-04-17 19:56:32 +02:00
{
2015-03-14 09:53:05 +01:00
$manager = $this->managerRegistry->getManagerForClass($this->objectClass);
2015-03-14 09:53:05 +01:00
$queryBuilder = $this->createQueryBuilder($options['query_builder_method']);
$nbObjects = $this->countObjects($queryBuilder);
2015-03-14 09:53:05 +01:00
$offset = $options['offset'];
2011-04-17 19:56:32 +02:00
$objects = array();
2015-03-14 09:53:05 +01:00
for (; $offset < $nbObjects; $offset += $options['batch_size']) {
try {
$objects = $this->getSlice($queryBuilder, $options['batch_size'], $offset, $objects);
$objects = $this->filterObjects($options, $objects);
2015-03-14 09:53:05 +01:00
if (!empty($objects)) {
$this->objectPersister->insertMany($objects);
2015-03-14 09:53:05 +01:00
}
} catch (BulkResponseException $e) {
if (!$options['ignore_errors']) {
throw $e;
}
if (null !== $loggerClosure) {
$loggerClosure(
$options['batch_size'],
$nbObjects,
sprintf('<error>%s</error>', $e->getMessage())
);
}
}
2011-04-17 19:56:32 +02:00
2015-03-14 09:53:05 +01:00
if ($options['clear_object_manager']) {
$manager->clear();
2011-04-17 19:56:32 +02:00
}
2015-03-14 09:53:05 +01:00
usleep($options['sleep']);
2015-03-14 09:53:05 +01:00
if (null !== $loggerClosure) {
$loggerClosure($options['batch_size'], $nbObjects);
}
2011-04-17 19:56:32 +02:00
}
2015-03-14 09:53:05 +01:00
}
2015-03-14 09:53:05 +01:00
/**
* {@inheritDoc}
*/
protected function configureOptions()
{
parent::configureOptions();
$this->resolver->setDefaults(array(
'clear_object_manager' => true,
'debug_logging' => false,
'ignore_errors' => false,
'offset' => 0,
'query_builder_method' => 'createQueryBuilder',
'sleep' => 0
));
2011-04-17 19:56:32 +02:00
}
/**
* If this Provider has a SliceFetcher defined, we use it instead of falling back to
* the fetchSlice methods defined in the ORM/MongoDB subclasses.
*
* @param $queryBuilder
2015-03-12 11:45:24 +01:00
* @param int $limit
* @param int $offset
* @param array $lastSlice
2015-03-12 11:45:24 +01:00
*
* @return array
*/
2015-03-14 09:54:01 +01:00
private function getSlice($queryBuilder, $limit, $offset, $lastSlice)
{
if (!$this->sliceFetcher) {
return $this->fetchSlice($queryBuilder, $limit, $offset);
}
$manager = $this->managerRegistry->getManagerForClass($this->objectClass);
$identifierFieldNames = $manager
->getClassMetadata($this->objectClass)
->getIdentifierFieldNames();
return $this->sliceFetcher->fetch(
$queryBuilder,
$limit,
$offset,
$lastSlice,
$identifierFieldNames
);
}
2011-04-17 19:56:32 +02:00
}