-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEntityManager.php
111 lines (98 loc) · 3.36 KB
/
EntityManager.php
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
namespace WebStream\Database;
use WebStream\DI\Injector;
/**
* EntityManager
* @author Ryuichi TANAKA.
* @since 2015/01/11
* @version 0.7
*/
class EntityManager
{
use Injector;
/**
* @var string エンティティクラスパス
*/
private string $classpath;
/**
* @var array<string> カラムメタ情報
*/
private array $columnMeta;
/**
* コンストラクタ
* @param string エンティティクラスパス
*/
public function __construct($classpath)
{
$this->classpath = $classpath;
}
/**
* カラムメタ情報を設定する
* @param array $columnMeta カラムメタ情報
*/
public function setColumnMeta(array $columnMeta)
{
$this->columnMeta = $columnMeta;
}
/**
* 列データをエンティティに変換して返却する
* @param array $row 列データ
* @return object 列データエンティティ
* @throws \ReflectionException
*/
public function getEntity(array $row)
{
$instance = new $this->classpath();
$propertyMap = null;
// EntityPropertyを使っている場合はリフレクションを使用しない
if (!array_key_exists(EntityProperty::class, class_uses($instance))) {
$propertyMap = [];
$refClass = new \ReflectionClass($instance);
$properties = $refClass->getProperties();
foreach ($properties as $property) {
if ($property->isPrivate() || $property->isProtected()) {
$property->setAccessible(true);
}
$propertyMap[strtolower($property->getName())] = $property;
}
}
foreach ($row as $col => $value) {
switch ($this->columnMeta[$col]) {
case 'LONG': // mysql:int
case 'SHORT': // mysql:smallint
case 'int4': // postgres:int
case 'int2': // postgres:smallint
case 'integer': // sqlite:int
case 'smallint': // sqlite:smallint
$value = intval($value);
break;
case 'LONGLONG': // mysql:bigint
case 'int8': // postgres:bigint
case 'bigint': // sqlite:bigint
$value = doubleval($value);
break;
case 'DATETIME': // mysql:datetime
case 'DATE': // mysql:date
case 'timestamp': // postgres:timestamp, sqlite:timestamp
case 'date': // postgres:date, sqlite:date
$value = new \DateTime($value);
break;
default: // string
break;
}
$col = strtolower(preg_replace_callback('/_([a-zA-Z])/', function ($matches) {
return ucfirst($matches[1]);
}, $col));
if ($propertyMap === null) {
$instance->{$col} = $value;
} else {
if (array_key_exists($col, $propertyMap)) {
$propertyMap[$col]->setValue($instance, $value);
} else {
$this->logger->error("Column '$col' is failed mapping in " . $this->classpath);
}
}
}
return $instance;
}
}