Add method for multi insert or update to Repository
[MAILPOET-3378]
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace MailPoet\Doctrine;
|
namespace MailPoet\Doctrine;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||||
use MailPoetVendor\Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
|
use MailPoetVendor\Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
|
||||||
use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
|
use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
@@ -19,6 +20,11 @@ abstract class Repository {
|
|||||||
/** @var DoctrineEntityRepository */
|
/** @var DoctrineEntityRepository */
|
||||||
protected $doctrineRepository;
|
protected $doctrineRepository;
|
||||||
|
|
||||||
|
/** @var string[] */
|
||||||
|
protected $ignoreColumnsForUpdate = [
|
||||||
|
'created_at',
|
||||||
|
];
|
||||||
|
|
||||||
public function __construct(EntityManager $entityManager) {
|
public function __construct(EntityManager $entityManager) {
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->classMetadata = $entityManager->getClassMetadata($this->getEntityClassName());
|
$this->classMetadata = $entityManager->getClassMetadata($this->getEntityClassName());
|
||||||
@@ -72,8 +78,7 @@ abstract class Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function truncate() {
|
public function truncate() {
|
||||||
$cmd = $this->entityManager->getClassMetadata($this->getEntityClassName());
|
$tableName = $this->getTableName();
|
||||||
$tableName = $cmd->getTableName();
|
|
||||||
$connection = $this->entityManager->getConnection();
|
$connection = $this->entityManager->getConnection();
|
||||||
$connection->query('SET FOREIGN_KEY_CHECKS=0');
|
$connection->query('SET FOREIGN_KEY_CHECKS=0');
|
||||||
$q = "TRUNCATE $tableName";
|
$q = "TRUNCATE $tableName";
|
||||||
@@ -103,4 +108,52 @@ abstract class Repository {
|
|||||||
* @return class-string<T>
|
* @return class-string<T>
|
||||||
*/
|
*/
|
||||||
abstract protected function getEntityClassName();
|
abstract protected function getEntityClassName();
|
||||||
|
|
||||||
|
protected function getTableName(): string {
|
||||||
|
return $this->entityManager->getClassMetadata($this->getEntityClassName())->getTableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insertOrUpdateMultiple(array $columns, array $data, ?DateTime $updatedAt = null): int {
|
||||||
|
$tableName = $this->getTableName();
|
||||||
|
$entityColumns = $this->entityManager->getClassMetadata($this->getEntityClassName())->getColumnNames();
|
||||||
|
|
||||||
|
if (!$columns || !$data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
$parameters = [];
|
||||||
|
foreach ($data as $key => $item) {
|
||||||
|
$paramNames = array_map(function (string $parameter) use ($key): string {
|
||||||
|
return ":{$parameter}_{$key}";
|
||||||
|
}, $columns);
|
||||||
|
|
||||||
|
foreach ($item as $columnKey => $column) {
|
||||||
|
$parameters[$paramNames[$columnKey]] = $column;
|
||||||
|
}
|
||||||
|
$rows[] = "(" . implode(', ', $paramNames) . ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
$updateColumns = array_map(function (string $column): string {
|
||||||
|
return "{$column} = VALUES($column)";
|
||||||
|
}, array_diff($columns, $this->ignoreColumnsForUpdate));
|
||||||
|
|
||||||
|
if ($updatedAt && in_array('updated_at', $entityColumns, true)) {
|
||||||
|
$parameters['updated_at'] = $updatedAt;
|
||||||
|
$updateColumns[] = "updated_at = :updated_at";
|
||||||
|
}
|
||||||
|
|
||||||
|
// we want to reset deleted_at for updated rows
|
||||||
|
if (in_array('deleted_at', $entityColumns, true)) {
|
||||||
|
$updateColumns[] = 'deleted_at = NULL';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $this->entityManager->getConnection()->executeUpdate("
|
||||||
|
INSERT INTO {$tableName} (`" . implode("`, `", $columns) . "`) VALUES
|
||||||
|
" . implode(", \n", $rows) . "
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
" . implode(", \n", $updateColumns) . "
|
||||||
|
", $parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user