data mapper POC
[m6w6/pq-gateway] / lib / pq / Mapper / ObjectCache.php
1 <?php
2
3 namespace pq\Mapper;
4
5 use OutOfBoundsException;
6 use pq\Exception\BadMethodCallException;
7 use pq\Gateway\Row;
8
9 class ObjectCache
10 {
11 private $map;
12 private $obj = [];
13 private $row = [];
14
15 function __construct(MapInterface $map) {
16 $this->map = $map;
17 }
18
19 function reset() {
20 $this->obj = [];
21 $this->row = [];
22 }
23
24 function rowId(Row $row, $check = false) {
25 try {
26 $identity = $row->getIdentity();
27 } catch (OutOfBoundsException $e) {
28 return false;
29 }
30 return $this->serializeRowId($identity, $check);
31 }
32
33 function objectId($object) {
34 return spl_object_hash($object);
35 }
36
37 function extractRowId($object) {
38 $id = [];
39 foreach ($this->map->getGateway()->getIdentity() as $col) {
40 foreach ($this->map->getProperties() as $property) {
41 if ($property->exposes($col)) {
42 $id[$col] = $property->extract($object);
43 }
44 }
45 }
46 return $this->serializeRowId($id, true);
47 }
48
49 function serializeRowId($identity, $check = false) {
50 if (is_scalar($identity)) {
51 return $identity;
52 }
53
54 if ($check && !isset($identity)) {
55 return false;
56 }
57
58 if (is_array($identity)) {
59 if ($check && array_search(null, $identity, true)) {
60 return false;
61 }
62 /* one level is better than no level */
63 asort($identity);
64 }
65 return json_encode($identity);
66 }
67
68 function hasObject($row_id) {
69 return isset($this->obj[$row_id]);
70 }
71
72 function createObject(Row $row) {
73 $rid = $this->rowId($row);
74 $cls = $this->map->getClass();
75 $obj = new $cls;
76 $oid = $this->objectId($obj);
77 $this->obj[$rid] = $obj;
78 $this->row[$oid] = $row;
79 return $obj;
80 }
81
82 function resetObject(Row $row) {
83 unset($this->obj[$this->rowId($row)]);
84 }
85
86 function getObject(Row $row) {
87 $id = $this->rowId($row);
88 return $this->getObjectById($id);
89 }
90
91 function getObjectById($row_id) {
92 if (!$this->hasObject($row_id)) {
93 throw new BadMethodCallException("Object of row with id $row_id does not exist");
94 }
95 return $this->obj[$row_id];
96 }
97
98 function asObject(Row $row){
99 return $this->hasObject($this->rowId($row))
100 ? $this->getObject($row)
101 : $this->createObject($row);
102 }
103
104 function hasRow($obj_id) {
105 return isset($this->row[$obj_id]);
106 }
107
108 function createRow($object) {
109 $oid = $this->objectId($object);
110 $row = new Row($this->map->getGateway());
111 $this->row[$oid] = $row;
112 return $row;
113 }
114
115 function resetRow($object) {
116 unset($this->row [$this->objectId($object)]);
117 }
118
119 function getRow($object) {
120 $id = $this->objectId($object);
121
122 if (!$this->hasRow($id)) {
123 throw new BadMethodCallException("Row for object with id $id does not exist");
124 }
125 return $this->row[$id];
126 }
127
128 function asRow($object) {
129 return $this->hasRow($this->objectId($object))
130 ? $this->getRow($object)
131 : $this->createRow($object);
132 }
133 }