flush
authorMichael Wallner <mike@php.net>
Tue, 12 Mar 2013 07:35:49 +0000 (08:35 +0100)
committerMichael Wallner <mike@php.net>
Tue, 12 Mar 2013 07:35:49 +0000 (08:35 +0100)
lib/pq/Gateway/Cell.php
lib/pq/Gateway/Row.php
lib/pq/Gateway/Table.php

index efa5fcbb3cd1154ecd99321bdddaf9e093a7a5c2..33f94c8fe609a47aa204027d0fbe13e3a13b5be1 100644 (file)
@@ -48,6 +48,14 @@ class Cell extends Expressible
         * @return \pq\Gateway\Cell
         */
        function set($data) {
+               if ($data instanceof Row) {
+                       $this->row->__set($data->getTable()->getName() . "_id", $data->id);
+                       $this->row->__unset($this->name);
+                       return $this;
+               }
+               if ($data instanceof Cell) {
+                       $data = $data->get();
+               }
                parent::set($data);
                $this->dirty = true;
                return $this;
index e408430c736293fa3750ce810f31600500db1169..5b438e564d80ca994088bca2d1585477b7c5a9d2 100644 (file)
@@ -43,13 +43,40 @@ class Row implements \JsonSerializable
                $that->data = $data;
                return $that->prime();
        }
+
+       /**
+        * Export current state as an array
+        * @return array
+        * @throws \UnexpectedValueException if a cell has been modified by an expression
+        */
+       function export() {
+               $export = array_merge($this->data, $this->cell);
+               foreach ($export as &$val) {
+                       if ($val instanceof Cell) {
+                               if ($val->isExpr()) {
+                                       throw new \UnexpectedValueException("Cannot export an SQL expression");
+                               }
+                               $val = $val->get();
+                       }
+               }
+               return $export;
+       }
        
+       /**
+        * Export current state with security sensitive data removed. You should override that, just
+        * calls export() by default.
+        * @return array
+        */
+       function exportPublic() {
+               return $this->export();
+       }
+
        /**
         * @implements JsonSerializable
         * @return array
         */
        function jsonSerialize() {
-               return $this->data;
+               return $this->exportPublic();
        }
        
        /**
@@ -126,9 +153,13 @@ class Row implements \JsonSerializable
        /**
         * Get a cell
         * @param string $p
-        * @return \pq\Gateway\Cell
+        * @return \pq\Gateway\Cell|\pq\Gateway\Rowset
         */
        function __get($p) {
+               if (isset($this->data["{$p}_id"])) {
+                       // FIXME cache
+                       return $this->getTable()->by($this, $p);
+               }
                if (!isset($this->cell[$p])) {
                        $this->cell[$p] = new Cell($this, $p, isset($this->data[$p]) ? $this->data[$p] : null);
                }
@@ -141,7 +172,16 @@ class Row implements \JsonSerializable
         * @param mixed $v
         */
        function __set($p, $v) {
-               $this->__get($p)->set(($v instanceof Cell) ? $v->get() : $v);
+               $this->__get($p)->set($v);
+       }
+       
+       function __unset($p) {
+               unset($this->data[$p]);
+               unset($this->cell[$p]);
+       }
+       
+       function __isset($p) {
+               return isset($this->data[$p]) || isset($this->cell[$p]);
        }
        
        /**
index 2e82a214b37d89c90815aded33d340616f222005..79669115471813dd4bc3828f4089c4d7543ef4e3 100644 (file)
@@ -37,13 +37,20 @@ class Table
         */
        protected $exec;
 
+       /**
+        * @var array
+        */
+       protected $dependents;
+       
        /**
         * @param string $name
         * @param \pq\Connection $conn
+        * @param array $dependents
         */
-       function __construct($name, \pq\Connection $conn = null) {
+       function __construct($name, \pq\Connection $conn = null, array $dependents = array()) {
                $this->name = $name;
                $this->conn = $conn ?: static::$defaultConnection ?: new \pq\Connection;
+               $this->dependents = $dependents;
        }
        
        /**
@@ -172,6 +179,43 @@ class Table
                $query->write("OFFSET", $offset);
                return $this->execute($query);
        }
+       
+       /**
+        * Get the parent row of a row by foreign key
+        * @param \pq\Gateway\Row $dependent
+        * @param string $name optional fkey name
+        * @param string $order
+        * @param int $limit
+        * @param int $offset
+        * @return mixed
+        */
+       function of(Row $dependent, $name = null, $order = null, $limit = 0, $offset = 0) {
+               if (!$name) {
+                       $name = $dependent->getTable()->getName();
+               }
+               return $this->find(array("{$name}_id=" => $dependent->id),
+                       $order, $limit, $offset);
+       }
+       
+       /**
+        * Get the child rows of a row by foreign key
+        * @param \pq\Gateway\Row $me
+        * @param string $dependent
+        * @param string $order
+        * @param int $limit
+        * @param int $offset
+        * @return mixed
+        * @throws \LogicException
+        */
+       function by(Row $me, $dependent, $order = null, $limit = 0, $offset = 0) {
+               if (!isset($this->dependents[$dependent])) {
+                       throw new \LogicException("Unknown dependent table $dependent");
+               }
+               
+               $dependentClass = $this->dependents[$dependent];
+               $dependentModel = new $dependentClass($this->conn);
+               return $dependentModel->of($me, null, $order, $limit, $offset);
+       }
 
        /**
         * Insert a row into the table