namespace pq\Gateway;
+use \pq\Query\Expr as QueryExpr;
+
class Row implements \JsonSerializable
{
/**
}
/**
- * Export current state with security sensitive data removed. You should override that, just
- * calls export() by default.
+ * Export current state with security sensitive data removed. You should override that.
+ * Just calls export() by default.
* @return array
*/
function exportPublic() {
return $this->data;
}
+ /**
+ * Get all column/value pairs to possibly uniquely identify this row
+ * @return array
+ * @throws \OutOfBoundsException if any primary key column is not present in the row
+ */
+ function getIdentity() {
+ $cols = array();
+ if (count($identity = $this->getTable()->getIdentity())) {
+ foreach ($identity as $col) {
+ if (!array_key_exists($col, $this->data)) {
+ throw new \OutOfBoundsException(
+ sprintf("Column '%s' does not exist in row of table '%s'",
+ $col, $this->getTable()->getName()
+ )
+ );
+ }
+ $cols[$col] = $this->data[$col];
+ }
+ } else {
+ $cols = $this->data;
+ }
+ return $cols;
+ }
+
/**
* Check whether the row contains modifications
* @return boolean
return false;
}
+ /**
+ * Refresh the rows data
+ * @return \pq\Gateway\Row
+ */
function refresh() {
$this->data = $this->table->find($this->criteria(), null, 1, 0)->current()->data;
$this->cell = array();
}
/**
- * Transform data array to where criteria
+ * Transform the row's identity to where criteria
* @return array
*/
protected function criteria() {
$where = array();
- foreach($this->data as $k => $v) {
- $where["$k="] = $v;
+ foreach ($this->getIdentity() as $col => $val) {
+ if (isset($val)) {
+ $where["$col="] = $val;
+ } else {
+ $where["$col IS"] = new QueryExpr("NULL");
+ }
}
return $where;
}
return $changes;
}
+ /**
+ * Cell accessor
+ * @param string $p column name
+ * @return \pq\Gateway\Cell
+ */
+ protected function cell($p) {
+ if (!isset($this->cell[$p])) {
+ $this->cell[$p] = new Cell($this, $p, isset($this->data[$p]) ? $this->data[$p] : null);
+ }
+ return $this->cell[$p];
+ }
+
/**
* Get a cell or parent rows
* @param string $p
if ($this->table->hasRelation($p)) {
return $this->table->by($this, $p);
}
- if (!isset($this->cell[$p])) {
- $this->cell[$p] = new Cell($this, $p, isset($this->data[$p]) ? $this->data[$p] : null);
- }
- return $this->cell[$p];
+ return $this->cell($p);
}
/**
* @param mixed $v
*/
function __set($p, $v) {
- $this->__get($p)->set($v);
+ $this->cell($p)->set($v);
}
/**
* @return \pq\Gateway\Row
*/
function create() {
- $this->data = $this->table->create($this->changes())->current()->data;
+ $rowset = $this->table->create($this->changes());
+ if (!count($rowset)) {
+ throw new \UnexpectedValueException("No row created");
+ }
+ $this->data = $rowset->current()->data;
$this->cell = array();
return $this;
}
* @return \pq\Gateway\Row
*/
function update() {
- $this->data = $this->table->update($this->criteria(), $this->changes())->current()->data;
+ $criteria = $this->criteria();
+ if (($lock = $this->getTable()->getLock())) {
+ $lock->onUpdate($this, $criteria);
+ }
+ $rowset = $this->table->update($criteria, $this->changes());
+ if (!count($rowset)) {
+ throw new \UnexpectedValueException("No row updated");
+ }
+ $this->data = $rowset->current()->data;
$this->cell = array();
return $this;
}
* @return \pq\Gateway\Row
*/
function delete() {
- $this->data = $this->table->delete($this->criteria(), "*")->current()->data;
+ $rowset = $this->table->delete($this->criteria(), "*");
+ if (!count($rowset)) {
+ throw new \UnexpectedValueException("No row deleted");
+ }
+ $this->data = $rowset->current()->data;
return $this->prime();
}
}