storage enhancements
[m6w6/pq-gateway] / lib / pq / Mapper / Storage.php
1 <?php
2
3 namespace pq\Mapper;
4
5 use InvalidArgumentException;
6 use pq\Connection;
7 use pq\Gateway\Table;
8 use pq\Transaction;
9
10 class Storage implements StorageInterface
11 {
12 /**
13 * The mapping of this storage
14 * @var MapInterface
15 */
16 private $map;
17
18 /**
19 * The mapper
20 * @var Mapper
21 */
22 private $mapper;
23
24 /**
25 * The underlying table gateway
26 * @var Table
27 */
28 private $gateway;
29
30 /**
31 * Create a storage for $map
32 * @param Mapper $mapper
33 * @param string $class
34 */
35 function __construct(Mapper $mapper, $class) {
36 $this->mapper = $mapper;
37 $this->map = $mapper->mapOf($class);
38 $this->gateway = $this->map->getGateway();
39 }
40
41 /**
42 * Find by PK
43 * @param mixed $pk
44 * @return object
45 */
46 function get($pk) {
47 $id = $this->gateway->getIdentity();
48 if (count($id) == 1 && is_scalar($pk)) {
49 $vals = [$pk];
50 } elseif (is_array($pk) && count($pk) === count($id)) {
51 $vals = $pk;
52 } else {
53 throw InvalidArgumentException(
54 "Insufficient identity provided; not all fields of %s are provided in %s",
55 json_encode($id->getColumns()), json_encode($pk));
56 }
57
58 $keys = array_map(function($v) {
59 return "$v=";
60 }, $id->getColumns());
61
62 $rowset = $this->gateway->find(array_combine($keys, $vals));
63
64 return $this->map->map($rowset->current());
65 }
66
67 /**
68 * Find
69 * @param array $where
70 * @param string $order
71 * @param int $limit
72 * @param int $offset
73 * @return object[]
74 */
75 function find($where = [], $order = null, $limit = null, $offset = null) {
76 /* @var pq\Gateway\Rowset $rowset */
77 $rowset = $this->gateway->find($where, $order, $limit, $offset);
78 return $this->map->mapAll($rowset);
79 }
80
81 /**
82 * Find parent
83 * @param object $object
84 * @param string $refName
85 * @return object
86 */
87 function by($object, $refName) {
88 $row = $this->mapper->mapOf($object)->getObjects()->getRow($object);
89 $this->map->refOf($row, $refName, $objects);
90 return current($objects);
91 }
92
93 /**
94 * Find childs
95 * @param object $object
96 * @param string $refName
97 * @return array
98 */
99 function of($object, $refName) {
100 $row = $this->mapper->mapOf($object)->getObjects()->getRow($object);
101 $this->map->allOf($row, $refName, $objects);
102 return $objects;
103 }
104
105 /**
106 * Delete
107 * @param object $object
108 */
109 function delete($object) {
110 $cache = $this->map->getObjects();
111 $row = $cache->asRow($object)->delete();
112 $cache->resetObject($row);
113 $cache->resetRow($object);
114 }
115
116 /**
117 * Save
118 * @param object $object
119 */
120 function save($object) {
121 $this->map->unmap($object);
122 }
123
124 /**
125 * Buffer in a transaction
126 */
127 function buffer() {
128 switch ($this->gateway->getConnection()->transactionStatus) {
129 case Connection::TRANS_INTRANS:
130 break;
131 default:
132 $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("START TRANSACTION"));
133 }
134 }
135
136 /**
137 * Commit
138 */
139 function flush() {
140 switch ($this->gateway->getConnection()->transactionStatus) {
141 case Connection::TRANS_IDLE:
142 break;
143 default:
144 $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("COMMIT"));
145 }
146 }
147
148 /**
149 * Rollback
150 */
151 function discard() {
152 switch ($this->gateway->getConnection()->transactionStatus) {
153 case Connection::TRANS_IDLE:
154 break;
155 default:
156 $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("ROLLBACK"));
157 }
158 $this->map->getObjects()->reset();
159 }
160 }