Merge pull request #18 from DanielSiepmann/feature/firstReview

Feature/first review
This commit is contained in:
Daniel Siepmann 2016-12-15 09:31:44 +01:00 committed by GitHub
commit af4de18b65
14 changed files with 47 additions and 55 deletions

View file

@ -50,6 +50,6 @@ class IndexCommandController extends CommandController
{ {
// TODO: Allow to index multiple tables at once? // TODO: Allow to index multiple tables at once?
// TODO: Also allow to index everything? // TODO: Also allow to index everything?
$this->indexerFactory->getIndexer($table)->index(); $this->indexerFactory->getIndexer($table)->indexAllDocuments();
} }
} }

View file

@ -33,7 +33,7 @@ interface ConnectionInterface
* *
* @return void * @return void
*/ */
public function add($documentType, array $document); public function addDocument($documentType, array $document);
/** /**
* Add the given documents. * Add the given documents.
@ -48,22 +48,26 @@ interface ConnectionInterface
/** /**
* Will update an existing document. * Will update an existing document.
* *
* NOTE: Batch updating is not yet supported.
*
* @param string $documentType * @param string $documentType
* @param array $document * @param array $document
* *
* @return void * @return void
*/ */
public function update($documentType, array $document); public function updateDocument($documentType, array $document);
/** /**
* Will remove an existing document. * Will remove an existing document.
* *
* NOTE: Batch deleting is not yet supported.
*
* @param string $documentType * @param string $documentType
* @param int $identifier * @param int $identifier
* *
* @return void * @return void
*/ */
public function delete($documentType, $identifier); public function deleteDocument($documentType, $identifier);
/** /**
* Search by given request and return result. * Search by given request and return result.

View file

@ -80,7 +80,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
$this->documentFactory = $documentFactory; $this->documentFactory = $documentFactory;
} }
public function add($documentType, array $document) public function addDocument($documentType, array $document)
{ {
$this->withType( $this->withType(
$documentType, $documentType,
@ -90,7 +90,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
); );
} }
public function delete($documentType, $identifier) public function deleteDocument($documentType, $identifier)
{ {
$this->withType( $this->withType(
$documentType, $documentType,
@ -100,7 +100,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
); );
} }
public function update($documentType, array $document) public function updateDocument($documentType, array $document)
{ {
$this->withType( $this->withType(
$documentType, $documentType,
@ -110,12 +110,6 @@ class Elasticsearch implements Singleton, ConnectionInterface
); );
} }
/**
* Add the given documents to elasticsearch.
*
* @param string $documentType
* @param array $documents
*/
public function addDocuments($documentType, array $documents) public function addDocuments($documentType, array $documents)
{ {
$this->withType( $this->withType(
@ -141,6 +135,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
/** /**
* @param SearchRequestInterface $searchRequest * @param SearchRequestInterface $searchRequest
*
* @return \Elastica\ResultSet * @return \Elastica\ResultSet
*/ */
public function search(SearchRequestInterface $searchRequest) public function search(SearchRequestInterface $searchRequest)
@ -152,7 +147,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
// TODO: Return wrapped result to implement our interface. // TODO: Return wrapped result to implement our interface.
// Also update php doc to reflect the change. // Also update php doc to reflect the change.
return $search->search($searchRequest->getSearchTerm()); return $search->search('"' . $searchRequest->getSearchTerm() . '"');
} }
/** /**

View file

@ -27,6 +27,8 @@ use TYPO3\CMS\Core\SingletonInterface as Singleton;
* The current connection to elasticsearch. * The current connection to elasticsearch.
* *
* Wrapper for Elastica\Client. * Wrapper for Elastica\Client.
*
* TODO: Catch inner exception and throw general ones (at least in Connection-Namespace (not elastic specific))
*/ */
class Connection implements Singleton class Connection implements Singleton
{ {

View file

@ -26,16 +26,18 @@ namespace Leonmrni\SearchCore\Domain\Index;
interface IndexerInterface interface IndexerInterface
{ {
/** /**
* Index the index. * Fetches all documents from the indexerService and pushes it to the connection.
* *
* @return void * @return void
*/ */
public function index(); public function indexAllDocuments();
/** /**
* Index a single record. * Fetches a single document from the indexerService and pushes it to the connection.
*
* @param string $identifier identifier, the indexer needs to identify a single document
* *
* @return void * @return void
*/ */
public function indexRecord($identifier); public function indexDocument($identifier);
} }

View file

@ -65,7 +65,7 @@ class TcaIndexer implements IndexerInterface
$this->connection = $connection; $this->connection = $connection;
} }
public function index() public function indexAllDocuments()
{ {
$this->logger->info('Start indexing'); $this->logger->info('Start indexing');
foreach ($this->getRecordGenerator() as $records) { foreach ($this->getRecordGenerator() as $records) {
@ -79,10 +79,10 @@ class TcaIndexer implements IndexerInterface
$this->logger->info('Finish indexing'); $this->logger->info('Finish indexing');
} }
public function indexRecord($identifier) public function indexDocument($identifier)
{ {
$this->logger->info('Start indexing single record.', [$identifier]); $this->logger->info('Start indexing single record.', [$identifier]);
$this->connection->add($this->tcaTableService->getTableName(), $this->getRecord($identifier)); $this->connection->addDocument($this->tcaTableService->getTableName(), $this->getRecord($identifier));
$this->logger->info('Finish indexing'); $this->logger->info('Finish indexing');
} }

View file

@ -55,6 +55,6 @@ class SearchRequest implements SearchRequestInterface
*/ */
public function getSearchTerm() public function getSearchTerm()
{ {
return '"' . $this->query . '"'; return $this->query;
} }
} }

View file

@ -35,21 +35,6 @@ class SearchService
*/ */
protected $connection; protected $connection;
/**
* @var \TYPO3\CMS\Core\Log\Logger
*/
protected $logger;
/**
* Inject log manager to get concrete logger from it.
*
* @param \TYPO3\CMS\Core\Log\LogManager $logManager
*/
public function injectLogger(\TYPO3\CMS\Core\Log\LogManager $logManager)
{
$this->logger = $logManager->getLogger(__CLASS__);
}
/** /**
* @param ConnectionInterface $connection * @param ConnectionInterface $connection
*/ */

View file

@ -27,6 +27,9 @@ use TYPO3\CMS\Core\SingletonInterface as Singleton;
* *
* This is the place to add mappings of further parts to adjust the data before * This is the place to add mappings of further parts to adjust the data before
* sending ot to connection. * sending ot to connection.
*
* TODO: Probably a candidate for deletion. Currently this class makes use of
* extbase DI. We have to resolve this somehow.
*/ */
class DataHandler implements Singleton class DataHandler implements Singleton
{ {
@ -64,7 +67,7 @@ class DataHandler implements Singleton
public function add($table, array $record) public function add($table, array $record)
{ {
$this->logger->debug('Record received for add.', [$table, $record]); $this->logger->debug('Record received for add.', [$table, $record]);
$this->indexerFactory->getIndexer($table)->indexRecord($record['uid']); $this->indexerFactory->getIndexer($table)->indexDocument($record['uid']);
} }
/** /**
@ -73,7 +76,7 @@ class DataHandler implements Singleton
public function update($table, array $record) public function update($table, array $record)
{ {
$this->logger->debug('Record received for update.', [$table, $record]); $this->logger->debug('Record received for update.', [$table, $record]);
$this->indexerFactory->getIndexer($table)->indexRecord($record['uid']); $this->indexerFactory->getIndexer($table)->indexDocument($record['uid']);
} }
/** /**
@ -83,6 +86,6 @@ class DataHandler implements Singleton
public function delete($table, $identifier) public function delete($table, $identifier)
{ {
$this->logger->debug('Record received for delete.', [$table, $identifier]); $this->logger->debug('Record received for delete.', [$table, $identifier]);
$this->connection->delete($table, $identifier); $this->connection->deleteDocument($table, $identifier);
} }
} }

View file

@ -26,6 +26,7 @@ use TYPO3\CMS\Core\Tests\FunctionalTestCase as CoreTestCase;
* All functional tests should extend this base class. * All functional tests should extend this base class.
* *
* It will take care of leaving a clean environment for next test. * It will take care of leaving a clean environment for next test.
* TODO: this is in reality an "elastica" abstract case - not search_core ;)
*/ */
abstract class AbstractFunctionalTestCase extends CoreTestCase abstract class AbstractFunctionalTestCase extends CoreTestCase
{ {

View file

@ -29,6 +29,5 @@
<logging> <logging>
<log type="coverage-html" target="../../.Build/report/functional/html" lowUpperBound="35" highLowerBound="70"/> <log type="coverage-html" target="../../.Build/report/functional/html" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="../../.Build/report/functional/clover/coverage"/> <log type="coverage-clover" target="../../.Build/report/functional/clover/coverage"/>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging> </logging>
</phpunit> </phpunit>

View file

@ -76,7 +76,7 @@ class DataHandlerTest extends AbstractFunctionalTestCase
$hook->processDatamap_afterDatabaseOperations('update', 'tt_content', 6, [], $dataHandler); $hook->processDatamap_afterDatabaseOperations('update', 'tt_content', 6, [], $dataHandler);
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.'); $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
} }
@ -91,7 +91,7 @@ class DataHandlerTest extends AbstractFunctionalTestCase
$hook->processCmdmap_deleteAction('tt_content', 6, [], false, $dataHandler); $hook->processCmdmap_deleteAction('tt_content', 6, [], false, $dataHandler);
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 0, 'Not exactly 0 document was indexed.'); $this->assertSame($response->getData()['hits']['total'], 0, 'Not exactly 0 document was indexed.');
} }
@ -99,10 +99,11 @@ class DataHandlerTest extends AbstractFunctionalTestCase
* @test * @test
* @expectedException \Elastica\Exception\ResponseException * @expectedException \Elastica\Exception\ResponseException
*/ */
public function someUnkownOperationDoesNotBreakSomething() public function someUnknownOperationDoesNotBreakSomething()
{ {
$dataHandler = new CoreDataHandler(); $dataHandler = new CoreDataHandler();
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class); $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
//TODO: this test is senseless, checking an exception not correct, this operation should not do anything!
$hook->processDatamap_afterDatabaseOperations('something', 'tt_content', 6, [], $dataHandler); $hook->processDatamap_afterDatabaseOperations('something', 'tt_content', 6, [], $dataHandler);
// Should trigger Exception // Should trigger Exception

View file

@ -44,12 +44,12 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class) ->get(IndexerFactory::class)
->getIndexer('tt_content') ->getIndexer('tt_content')
->index() ->indexAllDocuments()
; ;
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.'); $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
$this->assertArraySubset( $this->assertArraySubset(
['_source' => ['header' => 'indexed content element']], ['_source' => ['header' => 'indexed content element']],
@ -72,23 +72,24 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
} }
/** /**
* TODO: this does not test the indexer, it tests the backend
* @test * @test
*/ */
public function canHandleExisingIndex() public function canHandleExistingIndex()
{ {
$indexer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) $indexer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class) ->get(IndexerFactory::class)
->getIndexer('tt_content') ->getIndexer('tt_content')
; ;
$indexer->index(); $indexer->indexAllDocuments();
// Index 2nd time, index already exists in elasticsearch. // Index 2nd time, index already exists in elasticsearch.
$indexer->index(); $indexer->indexAllDocuments();
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.'); $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
} }
@ -103,12 +104,12 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class) ->get(IndexerFactory::class)
->getIndexer('tt_content') ->getIndexer('tt_content')
->index() ->indexAllDocuments()
; ;
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 2, 'Not exactly 2 documents were indexed.'); $this->assertSame($response->getData()['hits']['total'], 2, 'Not exactly 2 documents were indexed.');
$this->assertArraySubset( $this->assertArraySubset(
['_source' => ['header' => 'Also indexable record']], ['_source' => ['header' => 'Also indexable record']],
@ -134,11 +135,11 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class) ->get(IndexerFactory::class)
->getIndexer('tt_content') ->getIndexer('tt_content')
->index() ->indexAllDocuments()
; ;
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK()); $this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 3, 'Not exactly 3 documents were indexed.'); $this->assertSame($response->getData()['hits']['total'], 3, 'Not exactly 3 documents were indexed.');
$response = $this->client->request('typo3content/_search?q=uid:9'); $response = $this->client->request('typo3content/_search?q=uid:9');

View file

@ -29,6 +29,5 @@
<logging> <logging>
<log type="coverage-html" target="../../.Build/report/unit/html" lowUpperBound="35" highLowerBound="70"/> <log type="coverage-html" target="../../.Build/report/unit/html" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="../../.Build/report/unit/clover/coverage"/> <log type="coverage-clover" target="../../.Build/report/unit/clover/coverage"/>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging> </logging>
</phpunit> </phpunit>