From a2c7f849072d62d145c5f0a36fe33a503d1ac518 Mon Sep 17 00:00:00 2001 From: yuri Date: Thu, 26 Feb 2015 13:24:32 +0200 Subject: [PATCH] ORM: massRelate --- application/Espo/ORM/DB/Mapper.php | 61 ++++++++++++++++++++++++++++++ tests/Espo/ORM/DB/MapperTest.php | 21 ++++++++-- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/application/Espo/ORM/DB/Mapper.php b/application/Espo/ORM/DB/Mapper.php index 12b2623ff5..18939f973c 100644 --- a/application/Espo/ORM/DB/Mapper.php +++ b/application/Espo/ORM/DB/Mapper.php @@ -372,6 +372,67 @@ abstract class Mapper implements IMapper } } + public function massRelate(IEntity $entity, $relationName, array $params = array()) + { + if (!$entity) { + return false; + } + $id = $entity->id; + + if (empty($id) || empty($relationName)) { + return false; + } + + $relOpt = $entity->relations[$relationName]; + + if (!isset($relOpt['entity']) || !isset($relOpt['type'])) { + throw new \LogicException("Not appropriate defenition for relationship {$relationName} in " . $entity->getEntityType() . " entity"); + } + + $relType = $relOpt['type']; + + $className = (!empty($relOpt['class'])) ? $relOpt['class'] : $relOpt['entity']; + $relEntity = $this->entityFactory->create($className); + $foreignEntityType = $relEntity->getEntityType(); + + $keySet = $this->query->getKeys($entity, $relationName); + + switch ($relType) { + case IEntity::MANY_MANY: + $key = $keySet['key']; + $foreignKey = $keySet['foreignKey']; + $nearKey = $keySet['nearKey']; + $distantKey = $keySet['distantKey']; + + $relTable = $this->toDb($relOpt['relationName']); + + + $params['select'] = array('id'); + $subSql = $this->query->createSelectQuery($foreignEntityType, $params); + + $fieldsPart = $this->toDb($nearKey); + $valuesPart = $this->pdo->quote($entity->id); + + if (!empty($relOpt['conditions']) && is_array($relOpt['conditions'])) { + foreach ($relOpt['conditions'] as $f => $v) { + $fieldsPart .= ", " . $this->toDb($f); + $valuesPart .= ", " . $this->pdo->quote($v); + } + } + $fieldsPart .= ", " . $this->toDb($distantKey); + + $subSql = substr($subSql, 7); + + $subSql = "SELECT " . $valuesPart . ", " . $subSql; + + $sql = "INSERT INTO `".$relTable."` (".$fieldsPart.") (".$subSql.") ON DUPLICATE KEY UPDATE deleted = '0'"; + + return $this->pdo->query($sql); + + break; + } + } + public function addRelation(IEntity $entity, $relationName, $id = null, $relEntity = null, $data = null) { if (!is_null($relEntity)) { diff --git a/tests/Espo/ORM/DB/MapperTest.php b/tests/Espo/ORM/DB/MapperTest.php index 9fc5354492..25b7aad6ac 100644 --- a/tests/Espo/ORM/DB/MapperTest.php +++ b/tests/Espo/ORM/DB/MapperTest.php @@ -1,4 +1,4 @@ -entityFactory = $this->getMockBuilder('\\Espo\\ORM\\EntityFactory')->disableOriginalConstructor()->getMock(); $this->entityFactory->expects($this->any()) @@ -64,7 +64,7 @@ class DBMapperTest extends PHPUnit_Framework_TestCase })); $this->query = new Query($this->pdo, $this->entityFactory); - + $this->db = new MysqlMapper($this->pdo, $this->entityFactory, $this->query); $this->db->setReturnCollection(true); @@ -432,6 +432,21 @@ class DBMapperTest extends PHPUnit_Framework_TestCase $this->assertEquals($value, 10); } + + public function testMassRelate() + { + $query = "INSERT INTO `post_tag` (post_id, tag_id) (SELECT '1', tag.id AS `id` FROM `tag` WHERE tag.name = 'test' AND tag.deleted = '0') ON DUPLICATE KEY UPDATE deleted = '0'"; + $return = true; + $this->mockQuery($query, $return); + + $this->post->id = '1'; + + $this->db->massRelate($this->post, 'tags', array( + 'whereClause' => array( + 'name' => 'test' + ) + )); + } }