bba7c09c07642c90fe1d877f18c7462da40e7bfe
5 use \pq\Query\Expr
as QueryExpr
;
7 class Row
implements \JsonSerializable
10 * @var \pq\Gateway\Table
22 protected $cell = array();
25 * @param \pq\Gateway\Table $table
27 * @param bool $prime whether to mark all columns as modified
29 function __construct(Table
$table, array $data = null, $prime = false) {
30 $this->table
= $table;
31 $this->data
= (array) $data;
41 * @return \pq\Gateway\Row
43 function __invoke(array $data) {
46 return $that->prime();
50 * Export current state as an array
52 * @throws \UnexpectedValueException if a cell has been modified by an expression
55 $export = array_merge($this->data
, $this->cell
);
56 foreach ($export as &$val) {
57 if ($val instanceof Cell
) {
59 throw new \
UnexpectedValueException("Cannot export an SQL expression");
68 * Export current state with security sensitive data removed. You should override that, just
69 * calls export() by default.
72 function exportPublic() {
73 return $this->export();
77 * @implements JsonSerializable
80 function jsonSerialize() {
81 return $this->exportPublic();
85 * @return \pq\Gateway\Table
99 * Get all column/value pairs to possibly uniquely identify this row
101 * @throws \OutOfBoundsException if any primary key column is not present in the row
103 function getIdentity() {
105 if (count($identity = $this->getTable()->getIdentity())) {
106 foreach ($identity as $col) {
107 if (!array_key_exists($col, $this->data
)) {
108 throw new \
OutOfBoundsException(
109 sprintf("Column '%s' does not exist in row of table '%s'",
110 $col, $this->getTable()->getName()
114 $cols[$col] = $this->data
[$col];
123 * Check whether the row contains modifications
127 foreach ($this->cell
as $cell) {
128 if ($cell->isDirty()) {
136 * Refresh the rows data
137 * @return \pq\Gateway\Row
140 $this->data
= $this->table
->find($this->criteria(), null, 1, 0)->current()->data
;
141 $this->cell
= array();
146 * Fill modified cells
147 * @return \pq\Gateway\Row
149 protected function prime() {
150 $this->cell
= array();
151 foreach ($this->data
as $key => $val) {
152 $this->cell
[$key] = new Cell($this, $key, $val, true);
158 * Transform the row's identity to where criteria
161 protected function criteria() {
163 foreach ($this->getIdentity() as $col => $val) {
165 $where["$col="] = $val;
167 $where["$col IS"] = new QueryExpr("NULL");
171 if (($lock = $this->getTable()->getLock())) {
172 $lock->criteria($this, $where);
178 * Get an array of changed properties
181 protected function changes() {
183 foreach ($this->cell
as $name => $cell) {
184 if ($cell->isDirty()) {
185 $changes[$name] = $cell->get();
192 * Get a cell or parent rows
194 * @return \pq\Gateway\Cell|\pq\Gateway\Rowset
197 if ($this->table
->hasRelation($p)) {
198 return $this->table
->by($this, $p);
200 if (!isset($this->cell
[$p])) {
201 $this->cell
[$p] = new Cell($this, $p, isset($this->data
[$p]) ?
$this->data
[$p] : null);
203 return $this->cell
[$p];
211 function __set($p, $v) {
212 $this->__get($p)->set($v);
219 function __unset($p) {
220 unset($this->data
[$p]);
221 unset($this->cell
[$p]);
225 * Check if a cell isset
229 function __isset($p) {
230 return isset($this->data
[$p]) ||
isset($this->cell
[$p]);
234 * Get child rows of this row by foreign key
235 * @see \pq\Gateway\Table::of()
236 * @param string $foreign
237 * @param array $args [order, limit, offset]
238 * @return \pq\Gateway\Rowset
240 function __call($foreign, array $args) {
241 array_unshift($args, $this);
242 $table = forward_static_call(array(get_class($this->getTable()), "resolve"), $foreign);
243 return call_user_func_array(array($table, "of"), $args);
247 * Create this row in the database
248 * @return \pq\Gateway\Row
251 $rowset = $this->table
->create($this->changes());
252 if (!count($rowset)) {
253 throw new \
UnexpectedValueException("No row created");
255 $this->data
= $rowset->current()->data
;
256 $this->cell
= array();
261 * Update this row in the database
262 * @return \pq\Gateway\Row
265 $rowset = $this->table
->update($this->criteria(), $this->changes());
266 if (!count($rowset)) {
267 throw new \
UnexpectedValueException("No row updated");
269 $this->data
= $rowset->current()->data
;
270 $this->cell
= array();
275 * Delete this row in the database
276 * @return \pq\Gateway\Row
279 $rowset = $this->table
->delete($this->criteria(), "*");
280 if (!count($rowset)) {
281 throw new \
UnexpectedValueException("No row deleted");
283 $this->data
= $rowset->current()->data
;
284 return $this->prime();