DoctrineDbalStorageWriter   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 55
rs 10
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A writeRecord() 0 34 4
A __construct() 0 12 1
1
<?php
2
3
namespace Avoran\RapidoAdapter\DoctrineDbalStorage;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Exception\InvalidArgumentException;
7
use Avoran\Rapido\ReadModel\ReadModelConfiguration;
8
use Avoran\Rapido\ReadModel\ReadModelField;
9
use Avoran\Rapido\ReadModel\StorageWriter;
10
use Doctrine\DBAL\Platforms\MySqlPlatform;
11
use Doctrine\DBAL\Platforms\SqlitePlatform;
12
13
class DoctrineDbalStorageWriter implements StorageWriter
14
{
15
    private $connection;
16
    private $tableNameGenerator;
17
    private $idColumnName;
18
    private $dbalTypeMapper;
19
20
    public function __construct
21
    (
22
        Connection $connection,
23
        NameGenerator $tableNameGenerator,
24
        $idColumnName,
25
        DbalTypeMapper $dbalTypeMapper
26
    )
27
    {
28
        $this->connection = $connection;
29
        $this->tableNameGenerator = $tableNameGenerator;
30
        $this->idColumnName = $idColumnName;
31
        $this->dbalTypeMapper = $dbalTypeMapper;
32
    }
33
34
    public function writeRecord(ReadModelConfiguration $metadata, $recordData)
35
    {
36
        $tableName = $this->tableNameGenerator->generate($metadata->getName());
37
        $record = $metadata->createRecord($recordData);
38
39
        $rowData = array_merge([$this->idColumnName => $record->getId()], $record->getData());
40
41
        $idType = $this->dbalTypeMapper->mapReadModelToDbalType($metadata->getId()->getDataType());
42
        $types = array_merge([$idType], array_map(function (ReadModelField $field) {
43
            return $this->dbalTypeMapper->mapReadModelToDbalType($field->getDataType());
44
        }, $metadata->getFields()));
45
46
        $columns = $values = $insertSet = $updateSet = [];
47
48
        foreach ($rowData as $columnName => $value) {
49
            $columns[]   = $columnName;
50
            $values[]    = $value;
51
            $insertSet[] = '?';
52
            $updateSet[] = "$columnName = ?";
53
        }
54
55
        $columnsStr = implode(', ', $columns);
56
        $insertParams = implode(', ', $insertSet);
57
        $updateParams = implode(', ', $updateSet);
58
59
        if ($this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
60
            $query = "INSERT INTO $tableName ($columnsStr) VALUES ($insertParams) ON DUPLICATE KEY UPDATE $updateParams";
61
        } elseif ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
62
            $query = "INSERT INTO $tableName ($columnsStr) VALUES ($insertParams) ON CONFLICT($this->idColumnName) DO UPDATE SET $updateParams";
63
        } else {
64
            throw new InvalidArgumentException('This database platform is not supported by Rapido');
65
        }
66
67
        $this->connection->executeQuery($query, array_merge($values, $values), array_merge($types, $types));
68
    }
69
}
70