Issues (11)

src/DataSource/DataMapper/AbstractMapper.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace DataSource\DataMapper;
6
7
use ArrayIterator;
8
use DataSource\Connection;
9
use Behavioral\IdentityMap;
10
use BasePatterns\RecordSet\Row;
11
use Exception\ApplicationException;
12
use BasePatterns\RecordSet\RecordSet;
13
use MetadataMapping\Metadata\DataMap;
14
use DataSource\Exception\SQLException;
15
use BasePatterns\LayerSupertype\DomainObject;
16
17
abstract class AbstractMapper
18
{
19
    private Connection $db;
20
21
    private ?DataMap $dataMap = null;
22
23
    abstract protected function findStatement(): string;
24
25
    abstract protected function loadDataMap(): DataMap;
26
27 3
    public function __construct(Connection $connection)
28
    {
29 3
        $this->db = $connection;
30 3
    }
31
32 3
    public function getDataMap()
33
    {
34 3
        return $this->dataMap = $this->dataMap ?: $this->loadDataMap();
35
    }
36
37 1
    public function findObjectsWhere(string $whereClause, array $bindValues): ArrayIterator
38
    {
39 1
        $sql = sprintf(
40 1
            "SELECT %s FROM %s WHERE %s",
41 1
            $this->getDataMap()->columnList(),
42 1
            $this->getDataMap()->getTableName(),
43 1
            $whereClause
44
        );
45
46
        try {
47 1
            $stmt = $this->db->prepare($sql);
48 1
            $rs = $stmt->executeQuery($bindValues);
49 1
            return $this->loadAll($rs);
50
        } catch (SQLException $e) {
51
            throw new ApplicationException(
52
                $e->getMessage(),
53
                (int) $e->getCode(),
54
                $e
55
            );
56
        }
57
    }
58
59 1
    protected function abstractFind(int $id): DomainObject
60
    {
61 1
        if ($result = IdentityMap::get($id, $this->getDataMap()->getDomainClass()->getName()) ?? null) {
62
            return $result;
63
        }
64
65
        try {
66 1
            $findStatement = $this->db->prepare($this->findStatement());
67 1
            $findStatement->bindValue(1, $id);
68 1
            $rs = $findStatement->executeQuery();
69
70 1
            return $this->load($rs->current());
71
        } catch (SQLException $e) {
72
            throw new ApplicationException(
73
                $e->getMessage(),
74
                (int) $e->getCode(),
75
                $e
76
            );
77
        }
78
    }
79
80 1
    protected function findMany(StatementSource $source): ArrayIterator
81
    {
82
        try {
83 1
            $stmt = $this->db->prepare($source->getSql());
84 1
            foreach ($source->getParameters() as $i => $value) {
85 1
                $stmt->bindValue($i, $value);
86
            }
87 1
            $rs = $stmt->executeQuery();
88
89 1
            return $this->loadAll($rs);
90
        } catch (SQLException $e) {
91
            throw new ApplicationException(
92
                $e->getMessage(),
93
                (int) $e->getCode(),
94
                $e
95
            );
96
        }
97
    }
98
99 3
    protected function load(array $row): DomainObject
100
    {
101 3
        $id = $row['id'];
102 3
        if ($result = IdentityMap::get($id, $this->getDataMap()->getDomainClass()->getName()) ?? null) {
103 2
            return $result;
104
        }
105
106 3
        $result = $this->getDataMap()->getDomainClass()->newInstanceWithoutConstructor();
107 3
        $result->setId($id);
108 3
        $this->loadFields($row, $result);
109 3
        IdentityMap::set($result);
110
111 3
        return $result;
112
    }
113
114 2
    protected function loadAll(ArrayIterator $rs): ArrayIterator
115
    {
116
        $result = \array_map([$this, 'load'], $rs->getArrayCopy());
117 2
118 2
        return new ArrayIterator($result);
119
    }
120 2
121
    private function loadFields(array $row, DomainObject $result): void
122
    {
123 3
        foreach ($this->dataMap->getColumnMaps() as $columnMap) {
0 ignored issues
show
The method getColumnMaps() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

123
        foreach ($this->dataMap->/** @scrutinizer ignore-call */ getColumnMaps() as $columnMap) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
124
            $columnMap->setField($result, $row[$columnMap->getColumnName()]);
125 3
        }
126 3
    }
127
}
128