-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStatementQuery.php
More file actions
92 lines (83 loc) · 2.57 KB
/
StatementQuery.php
File metadata and controls
92 lines (83 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
declare(strict_types=1);
namespace Bancer\NativeQueryMapper\ORM;
use Cake\Database\StatementInterface;
use Cake\ORM\Table;
class StatementQuery
{
protected Table $rootTable;
protected StatementInterface $stmt;
protected bool $isExecuted;
/**
* @var mixed[]|null
*/
protected $mapStrategy = null;
public function __construct(Table $rootTable, StatementInterface $stmt)
{
$this->rootTable = $rootTable;
$this->stmt = $stmt;
$this->isExecuted = false;
}
/**
* Provide a custom mapping strategy.
*
* @param mixed[] $strategy
* @return $this
*/
public function mapStrategy(array $strategy): self
{
$this->mapStrategy = $strategy;
return $this;
}
/**
* Execute and hydrate results.
*
* @return \Cake\Datasource\EntityInterface[]
*/
public function all(): array
{
if (!$this->isExecuted) {
$this->stmt->execute();
$this->isExecuted = true;
}
$rows = $this->stmt->fetchAll(\PDO::FETCH_ASSOC);
if (!$rows) {
return [];
}
if ($this->mapStrategy === null) {
$aliases = $this->extractAliases($rows);
$strategy = new MappingStrategy($this->rootTable, $aliases);
$this->mapStrategy = $strategy->build()->toArray();
}
$hydrator = new AutoHydratorRecursive($this->rootTable, $this->mapStrategy);
return $hydrator->hydrateMany($rows);
}
/**
* Extracts aliases of the columns from the query's result set.
*
* @param mixed[] $rows Result set rows.
* @return string[]
*/
protected function extractAliases(array $rows): array
{
$firstRow = $rows[0] ?? [];
if (!is_array($firstRow)) {
throw new \InvalidArgumentException('First element of the result set is not an array');
}
$keys = array_keys($firstRow);
$aliases = [];
foreach ($keys as $key) {
if (!is_string($key) || !str_contains($key, '__')) {
throw new UnknownAliasException("Column '$key' must use an alias in the format {Alias}__$key");
}
[$alias, $field] = explode('__', $key, 2);
if (mb_strlen($alias) <= 0 || mb_strlen($field) <= 0) {
$message = "Alias '$key' is invalid. Column alias must use {Alias}__{column_name} format";
throw new UnknownAliasException($message);
}
$aliases[] = $alias;
}
sort($aliases);
return $aliases;
}
}