diff --git a/lib/HireVoice/Neo4j/EntityManager.php b/lib/HireVoice/Neo4j/EntityManager.php index 2570eb0..77ec60e 100644 --- a/lib/HireVoice/Neo4j/EntityManager.php +++ b/lib/HireVoice/Neo4j/EntityManager.php @@ -262,18 +262,24 @@ function findAny($id) */ public function load($node) { - if (! isset($this->loadedNodes[$node->getId()])) { + if ($node instanceof Proxy\Entity) { + $pk = $this->getPrimaryKeyValue($node); + }else{ + $pk = $node->getId(); + } + + if (! isset($this->loadedNodes[$pk])) { $em = $this; $entity = $this->proxyFactory->fromNode($node, $this->metaRepository, function ($node) use ($em) { return $em->load($node); }); - $this->loadedNodes[$node->getId()] = $entity; + $this->loadedNodes[$pk] = $entity; $this->nodes[$this->getHash($entity)] = $node; } - return $this->loadedNodes[$node->getId()]; + return $this->loadedNodes[$pk]; } /** @@ -287,9 +293,9 @@ public function load($node) public function reload($entity) { if ($entity instanceof Proxy\Entity) { - return $this->load($this->findAny($entity->getId())); + return $this->load($this->findAny($this->getPrimaryKeyValue($entity))); } else { - return $this->find(get_class($entity), $entity->getId()); + return $this->find(get_class($entity), $this->getPrimaryKeyValue($entity)); } } @@ -536,7 +542,7 @@ private function traverseRelations($entity, $addCallback, $removeCallback = null if ($property->isTraversed()) { if ($entry = $property->getValue($entity)) { if ($removeCallback) { - $this->removePreviousRelations($entity, $property->getName(), $entry); + $this->removePreviousRelations($entity, $property->getName(), $property->getDirection(), $entry); } $addCallback($entry, $property->getName(), $property->getDirection()); } @@ -616,7 +622,7 @@ private function writeRelations() { $this->begin(); foreach ($this->entities as $entity) { - $this->writeRelationsFor($entity); + $this->writeRelationsFor($entity); } $this->commit(); } @@ -653,14 +659,20 @@ private function writeRelationsFor($entity) $this->traverseRelations($entity, $addCallback, $removeCallback); } - private function removePreviousRelations($from, $relation, $exception) + private function removePreviousRelations($from, $relation, $direction, $exception) { $node = $this->getLoadedNode($from); - + foreach ($this->getRelationsFrom($node, $relation) as $r) { - if (basename($r['end']) != $exception->getId()) { + if(strtolower($direction) == 'to'){ + $rstart = basename($r['start']); + }else{ + $rstart = basename($r['end']); + } + + if ($rstart != $this->getPrimaryKeyValue($exception)){ $this->deleteRelationship($r); - } + } } } @@ -761,7 +773,7 @@ private function index($entity) $class = $meta->getName(); $mainIndex = $this->createIndex($class); - $mainIndex->add($node, 'id', $entity->getId()); + $mainIndex->add($node, 'id', $this->getPrimaryKeyValue($entity)); } private function writeIndexes() @@ -796,7 +808,7 @@ private function removeIndexes(){ } $class = $meta->getName(); $mainIndex = $this->createIndex($class); - $mainIndex->remove($node, 'id', $entity->getId()); + $mainIndex->remove($node, 'id', $this->getPrimaryKeyValue($entity)); } } /** @@ -844,4 +856,15 @@ public function getPathFinder() { return clone $this->pathFinder; } + + /** + * @return \HireVoice\Neo4j\Meta\Property + */ + public function getPrimaryKeyValue($entity) + { + $meta = $this->getMeta($entity); + $pk = $meta->getPrimaryKey(); + $pkGetter = 'get'.ucfirst($pk->getName()); + return $entity->$pkGetter(); + } } diff --git a/lib/HireVoice/Neo4j/Proxy/Factory.php b/lib/HireVoice/Neo4j/Proxy/Factory.php index bbf9cf8..f3c5c90 100644 --- a/lib/HireVoice/Neo4j/Proxy/Factory.php +++ b/lib/HireVoice/Neo4j/Proxy/Factory.php @@ -237,7 +237,10 @@ private function __loadProperty(\$name, \$propertyName) \$root = \$relation['end']; } - if (basename(\$root) == \$this->getId()) { + \$pk = \$this->neo4j_meta->getPrimaryKey(); + \$pkGetter = 'get'.ucfirst(\$pk->getName()); + + if (basename(\$root) == \$this->\$pkGetter()) { \$node = \$this->neo4j_node->getClient()->getNode(basename(\$nodeUrl)); \$loader = \$this->neo4j_loadCallback; \$collection->add(\$loader(\$node)); diff --git a/lib/HireVoice/Neo4j/Tests/Entity/Olive.php b/lib/HireVoice/Neo4j/Tests/Entity/Olive.php new file mode 100644 index 0000000..0c74efe --- /dev/null +++ b/lib/HireVoice/Neo4j/Tests/Entity/Olive.php @@ -0,0 +1,83 @@ +veryStrangePrimaryKey = $veryStrangePrimaryKey; + return $this; + } + + /** + * @return mixed + */ + public function getVeryStrangePrimaryKey() + { + return $this->veryStrangePrimaryKey; + } + + /** + * @param mixed $name + * + * @return Olive + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + +} + diff --git a/lib/HireVoice/Neo4j/Tests/Entity/Pasta.php b/lib/HireVoice/Neo4j/Tests/Entity/Pasta.php new file mode 100644 index 0000000..dc7addb --- /dev/null +++ b/lib/HireVoice/Neo4j/Tests/Entity/Pasta.php @@ -0,0 +1,145 @@ +olives = new \Doctrine\Common\Collections\ArrayCollection(); + } + /** + * @param mixed $strangePrimaryKey + * + * @return Pasta + */ + public function setStrangePrimaryKey($strangePrimaryKey) + { + $this->strangePrimaryKey = $strangePrimaryKey; + return $this; + } + + /** + * @return mixed + */ + public function getStrangePrimaryKey() + { + return $this->strangePrimaryKey; + } + + /** + * @param mixed $name + * + * @return Pasta + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + + /** + * @param mixed $olives + * + * @return Pasta + */ + public function setOlives($olives) + { + $this->olives = $olives; + return $this; + } + + /** + * @return mixed + */ + public function getOlives() + { + return $this->olives; + } + + /** + * + * @param + */ + public function addOlive($olive) + { + $this->olives[] = $olive; + } + /** + * @param mixed $tomato + * + * @return Pasta + */ + public function setTomato($tomato) + { + $this->tomato = $tomato; + return $this; + } + + /** + * @return mixed + */ + public function getTomato() + { + return $this->tomato; + } + +} + diff --git a/lib/HireVoice/Neo4j/Tests/Entity/Tomato.php b/lib/HireVoice/Neo4j/Tests/Entity/Tomato.php new file mode 100644 index 0000000..5e5bfcf --- /dev/null +++ b/lib/HireVoice/Neo4j/Tests/Entity/Tomato.php @@ -0,0 +1,83 @@ +veryStrangePrimaryKey = $veryStrangePrimaryKey; + return $this; + } + + /** + * @return mixed + */ + public function getVeryStrangePrimaryKey() + { + return $this->veryStrangePrimaryKey; + } + + /** + * @param mixed $name + * + * @return Tomato + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + +} + diff --git a/lib/HireVoice/Neo4j/Tests/FreePrimaryKeyTest.php b/lib/HireVoice/Neo4j/Tests/FreePrimaryKeyTest.php new file mode 100644 index 0000000..dc54694 --- /dev/null +++ b/lib/HireVoice/Neo4j/Tests/FreePrimaryKeyTest.php @@ -0,0 +1,132 @@ +getEntityManager(); + + $pasta= new Entity\Pasta(); + $pasta->setName('Good pasta with tomato and olives'); + + $olive1 = new Entity\Olive(); + $olive1->setName('black olive'); + $olive2 = new Entity\Olive(); + $olive2->setName('green olive'); + + $tomato = new Entity\Tomato(); + + $pasta->addOlive($olive1); + $pasta->addOlive($olive2); + + $pasta->setTomato($tomato); + + $em->persist($pasta); + $em->flush(); + $this->pkVal = $pasta->getStrangePrimaryKey(); + } + + public function testInsert(){ + $em = $this->getEntityManager(); + $this->setupDb(); + + $loaded = $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal); + + $this->assertGreaterThanOrEqual(1, count($loaded)); + $this->assertGreaterThanOrEqual(2, count($loaded->getOlives())); + $this->assertGreaterThanOrEqual(1, count($loaded->getTomato())); + } + + public function testEntityReload(){ + $em = $this->getEntityManager(); + $this->setupDb(); + + $loaded = $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal); + + $entity = $loaded->getEntity(); + + $reloadEntity = $em->reload($entity); + + $this->assertGreaterThanOrEqual(1, count($loaded)); + $this->assertGreaterThanOrEqual(2, count($loaded->getOlives())); + $this->assertGreaterThanOrEqual(1, count($loaded->getTomato())); + } + + + public function testUpdate(){ + $em = $this->getEntityManager(); + $this->setupDb(); + + $loaded = $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal); + + $loaded->setName('This pasta is terrible'); + + $olive1 = new Entity\Olive(); + $olive1->setName('terrible olive'); + + $loaded->addOlive($olive1); + + $em->persist($loaded); + $em->flush(); + + unset($loaded); + $em->clear(); + + $loaded = $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal); + + $this->assertGreaterThanOrEqual(1, count($loaded)); + $this->assertEquals('This pasta is terrible', $loaded->getName()); + $this->assertGreaterThanOrEqual(3, count($loaded->getOlives())); + + $update_found = FALSE; + foreach($loaded->getOlives() as $olive){ + if($olive->getName() == 'terrible olive'){ + $update_found = TRUE; + } + } + $this->assertTrue( $update_found ); + $this->assertGreaterThanOrEqual(1, count($loaded->getTomato())); + } + + function testRemove() + { + $this->setupDb(); + $em = $this->getEntityManager(); + $loaded = $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal); + $em->remove($loaded); + $em->flush(); + $this->assertEquals(null, $em->find('HireVoice\Neo4j\Tests\Entity\Pasta', $this->pkVal)); + } + + function testFindAny(){ + $this->setupDb(); + $em = $this->getEntityManager(); + $loaded = $em->findAny($this->pkVal); + $this->assertEquals('Good pasta with tomato and olives', $loaded->getName()); + } +} diff --git a/lib/HireVoice/Neo4j/Tests/InheritanceTest.php b/lib/HireVoice/Neo4j/Tests/InheritanceTest.php index 738175b..ac12226 100644 --- a/lib/HireVoice/Neo4j/Tests/InheritanceTest.php +++ b/lib/HireVoice/Neo4j/Tests/InheritanceTest.php @@ -104,4 +104,31 @@ public function testChildAttribValue() $this->assertEquals(5, $mp->getRooms()); } + + public function testRemove() + { + $em = $this->getEntityManager(); + + $movie = new Entity\Movie; + $movie->setTitle('Army of Darkness'); + + $cinema = new Entity\Cinema; + $cinema->setName('Nuovo Cinema paradiso'); + $cinema->addPresentedMovie($movie); + + $multiplex = new Entity\Multiplex(); + $multiplex->setName('Multisala Portanova'); + $multiplex->addPresentedMovie($movie); + $multiplex->setRooms(5); + + $em->persist($multiplex); + $em->flush(); + + $id = $multiplex->getId(); + + $em->remove($multiplex); + $em->flush(); + + $this->assertEquals(null, $em->getRepository('HireVoice\Neo4j\Tests\Entity\Multiplex')->findOneBy(array('id' => $id))); + } }