diff --git a/src/IndexManager.php b/src/IndexManager.php
index 5ec0c3c..9696043 100644
--- a/src/IndexManager.php
+++ b/src/IndexManager.php
@@ -20,6 +20,10 @@ class IndexManager
public const ALIAS = 'o';
private const IDENTIFIER = 'id';
+ private const ACTION_INSERT = 'insert';
+ private const ACTION_UPDATE = 'update';
+ private const ACTION_REPLACE = 'replace';
+
private $connection;
private $index;
@@ -50,19 +54,24 @@ public function flushIndex(): ResultSetInterface
public function replace($object): ResultSetInterface
{
- return $this->createInsertReplaceQuery($object, false)->execute();
+ return $this->createCRUDQuery($object, self::ACTION_REPLACE)->execute();
}
- private function createInsertReplaceQuery($object, bool $insert = true, ?SphinxQL $sphinxQL = null): SphinxQL
+ private function createCRUDQuery($object, string $action, ?SphinxQL $sphinxQL = null): SphinxQL
{
$index = $this->getIndex();
- $columns = [self::IDENTIFIER];
- $values = [$this->getIdentityValue($object)];
+ $columns = [];
+ $values = [];
- foreach ($index->getFields() as $name => $field) {
- $columns[] = $name;
- $values[] = $this->getValue($object, $field['property'], Index::ATTR_TYPE_STRING);
+ if (self::ACTION_UPDATE !== $action) {
+ $columns = [self::IDENTIFIER];
+ $values = [$this->getIdentityValue($object)];
+
+ foreach ($index->getFields() as $name => $field) {
+ $columns[] = $name;
+ $values[] = $this->getValue($object, $field['property'], Index::ATTR_TYPE_STRING);
+ }
}
foreach ($index->getAttributes() as $name => $attribute) {
@@ -70,13 +79,40 @@ private function createInsertReplaceQuery($object, bool $insert = true, ?SphinxQ
$values[] = $this->getValue($object, $attribute['property'], $attribute['type']);
}
+ $prevQL = null;
+
+ if (self::ACTION_UPDATE === $action && null !== $sphinxQL) {
+ $prevQL = (clone $sphinxQL)->compile()->getCompiled();
+ }
+
if (!$sphinxQL) {
$sphinxQL = $this->createQuery();
- $sphinxQL = $insert ? $sphinxQL->insert()->into($index->getName()) : $sphinxQL->replace()->into($index->getName());
+
+ switch ($action) {
+ case self::ACTION_INSERT:
+ $sphinxQL = $sphinxQL->insert()->into($index->getName());
+ break;
+ case self::ACTION_REPLACE:
+ $sphinxQL = $sphinxQL->replace()->into($index->getName());
+ break;
+ case self::ACTION_UPDATE:
+ $sphinxQL = $sphinxQL->update($index->getName());
+ break;
+ }
}
- $sphinxQL->columns($columns);
- $sphinxQL->values($values);
+ $sphinxQL->set(array_combine($columns, $values));
+
+ if (self::ACTION_UPDATE === $action) {
+ $sphinxQL
+ ->resetWhere()
+ ->where(self::IDENTIFIER, '=', $this->getIdentityValue($object));
+
+ if (null !== $prevQL) {
+ $currentQL = $sphinxQL->compile()->getCompiled();
+ $sphinxQL->query($prevQL.';'.$currentQL);
+ }
+ }
return $sphinxQL;
}
@@ -160,20 +196,15 @@ public function delete(array $ids): ?ResultSetInterface
public function bulkReplace(array $objects): ?ResultSetInterface
{
- if (!count($objects)) {
- return null;
- }
-
- $sq = null;
-
- foreach ($objects as $object) {
- $sq = $this->createInsertReplaceQuery($object, false, $sq);
- }
+ return $this->bulkAction($objects, self::ACTION_REPLACE);
+ }
- return $sq->execute();
+ public function bulkUpdate(array $objects): ?ResultSetInterface
+ {
+ return $this->bulkAction($objects, self::ACTION_UPDATE);
}
- public function bulkInsert(array $objects): ?ResultSetInterface
+ private function bulkAction(array $objects, string $action): ?ResultSetInterface
{
if (!count($objects)) {
return null;
@@ -182,23 +213,25 @@ public function bulkInsert(array $objects): ?ResultSetInterface
$sq = null;
foreach ($objects as $object) {
- $sq = $this->createInsertReplaceQuery($object, true, $sq);
+ $sq = $this->createCRUDQuery($object, $action, $sq);
}
return $sq->execute();
}
- public function insert($object): ResultSetInterface
+ public function bulkInsert(array $objects): ?ResultSetInterface
{
- return $this->createInsertReplaceQuery($object, true)->execute();
+ return $this->bulkAction($objects, self::ACTION_INSERT);
}
- public function update($object): void
+ public function insert($object): ResultSetInterface
{
- //TODO check update field
- //All attributes types (int, bigint, float, strings, MVA, JSON) can be dynamically updated.
+ return $this->createCRUDQuery($object, self::ACTION_INSERT)->execute();
+ }
- throw new ManticoreException('Not implemented yet');
+ public function update($object): ResultSetInterface
+ {
+ return $this->createCRUDQuery($object, self::ACTION_UPDATE)->execute();
}
public function find($query = '', int $page = 1, int $limit = 10): array
diff --git a/src/Resources/views/data_collector/icon.svg b/src/Resources/views/data_collector/icon.svg
index ade8123..55e0e9d 100644
--- a/src/Resources/views/data_collector/icon.svg
+++ b/src/Resources/views/data_collector/icon.svg
@@ -1 +1,41 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/tests/IndexManagerTest.php b/tests/IndexManagerTest.php
index 3233a57..0c13db6 100644
--- a/tests/IndexManagerTest.php
+++ b/tests/IndexManagerTest.php
@@ -73,6 +73,26 @@ public function testReplace()
$indexManager->replace($entity);
}
+ public function testUpdate()
+ {
+ $entity = new SimpleEntity();
+ $entity->setId(1)->setStatus('enabled')->setName('name1');
+
+ $index = $this->createIndex();
+
+ $connection = $this->createConnection();
+
+ $connection
+ ->expects($this->once())
+ ->method('query')
+ ->with('UPDATE test_index SET status = \'enabled\' WHERE id = 1')
+ ->willReturn($this->createMock(ResultSet::class));
+
+ $managerRegistry = $this->createMock(ManagerRegistry::class);
+ $indexManager = new IndexManager($connection, $index, $managerRegistry);
+ $indexManager->update($entity);
+ }
+
public function testDelete()
{
$index = $this->createIndex();
@@ -136,6 +156,29 @@ public function testBulkInsert()
$indexManager->bulkInsert([$entity, $entity2]);
}
+ public function testBulkUpdate()
+ {
+ $entity = new SimpleEntity();
+ $entity->setId(1)->setStatus('enabled')->setName('name1');
+
+ $entity2 = new SimpleEntity();
+ $entity2->setId(2)->setStatus('disabled')->setName('name2');
+
+ $index = $this->createIndex();
+
+ $connection = $this->createConnection();
+
+ $connection
+ ->expects($this->once())
+ ->method('query')
+ ->with('UPDATE test_index SET status = \'enabled\' WHERE id = 1;UPDATE test_index SET status = \'disabled\' WHERE id = 2')
+ ->willReturn($this->createMock(ResultSet::class));
+
+ $managerRegistry = $this->createMock(ManagerRegistry::class);
+ $indexManager = new IndexManager($connection, $index, $managerRegistry);
+ $indexManager->bulkUpdate([$entity, $entity2]);
+ }
+
public function testFind()
{
$entity = new SimpleEntity();