From 3d5bc3bb0c17853e09ac830092d451ba42e8735b Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Thu, 23 Jul 2020 13:43:37 +0300 Subject: [PATCH] orm mapper mass insert --- application/Espo/ORM/DB/BaseMapper.php | 76 +++++++++++++++++++++----- tests/unit/Espo/ORM/DB/MapperTest.php | 24 ++++++++ 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/application/Espo/ORM/DB/BaseMapper.php b/application/Espo/ORM/DB/BaseMapper.php index 8a89640ce0..52ec101207 100644 --- a/application/Espo/ORM/DB/BaseMapper.php +++ b/application/Espo/ORM/DB/BaseMapper.php @@ -980,27 +980,73 @@ abstract class BaseMapper implements Mapper { $dataList = $this->toValueMap($entity); - $fieldArr = []; - $valArr = []; - foreach ($dataList as $field => $value) { - $fieldArr[] = $this->toDb($field); + $columnList = $this->getInsertColumnList($entity); + $valueList = $this->getInsertValueList($entity); - $type = $entity->getAttributes()[$field]['type']; - - $value = $this->prepareValueForInsert($type, $value); - - $valArr[] = $this->quote($value); - } - $fieldsPart = "`" . implode("`, `", $fieldArr) . "`"; - $valuesPart = implode(", ", $valArr); + $fieldsPart = "`" . implode("`, `", $columnList) . "`"; + $valuesPart = implode(", ", $valueList); $sql = $this->composeInsertQuery($this->toDb($entity->getEntityType()), $fieldsPart, $valuesPart); - if ($this->pdo->query($sql)) { - return $entity->id; + $result = $this->pdo->query($sql); + + if (!$result) { + return null; } - return null; + return $entity->id; + } + + public function massInsert(Collection $collection) : bool + { + if (!count($collection)) return true; + + $columnList = $this->getInsertColumnList($collection[0]); + + $fieldsPart = "`" . implode("`, `", $columnList) . "`"; + + $valuesPartList = []; + + foreach ($collection as $entity) { + $valueList = $this->getInsertValueList($entity); + $valuesPart = implode(", ", $valueList); + $valuesPartList[] = $valuesPart; + } + + $sql = $this->composeInsertQuery($this->toDb($entity->getEntityType()), $fieldsPart, $valuesPartList); + + $result = $this->pdo->query($sql); + + return (bool) $result; + } + + protected function getInsertColumnList(Entity $entity) : array + { + $columnList = []; + + $dataList = $this->toValueMap($entity); + + foreach ($dataList as $attribute => $value) { + $columnList[] = $this->toDb($attribute); + } + + return $columnList; + } + + + protected function getInsertValueList(Entity $entity) : array + { + $valueList = []; + + $dataList = $this->toValueMap($entity); + + foreach ($dataList as $attribute => $value) { + $type = $entity->getAttributeType($attribute); + $value = $this->prepareValueForInsert($type, $value); + $valueList[] = $this->quote($value); + } + + return $valueList; } public function update(Entity $entity) : ?string diff --git a/tests/unit/Espo/ORM/DB/MapperTest.php b/tests/unit/Espo/ORM/DB/MapperTest.php index e5cb54e606..ad8740fcfd 100644 --- a/tests/unit/Espo/ORM/DB/MapperTest.php +++ b/tests/unit/Espo/ORM/DB/MapperTest.php @@ -30,6 +30,7 @@ use Espo\ORM\DB\MysqlMapper; use Espo\ORM\DB\Query\Mysql as Query; use Espo\ORM\EntityFactory; +use Espo\ORM\EntityCollection; use Espo\Entities\Post; use Espo\Entities\Comment; @@ -348,6 +349,29 @@ class DBMapperTest extends \PHPUnit\Framework\TestCase $this->db->insert($this->post); } + public function testMassInsert() + { + $query = "INSERT INTO `post` (`id`, `name`) VALUES ('1', 'test1'), ('2', 'test2')"; + $return = true; + $this->mockQuery($query, $return); + + $post1 = $this->entityFactory->create('Post'); + $post2 = $this->entityFactory->create('Post'); + + $post1->id = '1'; + $post1->set('name', 'test1'); + + $post2->id = '2'; + $post2->set('name', 'test2'); + + $collection = new EntityCollection([ + $post1, + $post2, + ]); + + $this->db->massInsert($collection); + } + public function testUpdate() { $query = "UPDATE `post` SET `name` = 'test' WHERE post.id = '1' AND post.deleted = '0'";