X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fpq-gateway;a=blobdiff_plain;f=lib%2Fpq%2FGateway%2FTable.php;h=e365e3772f836ce19a58bc8f2e7a788b07a4f4ee;hp=a25b2ad3fd6e07008bf59f27caa56239293756ac;hb=d3a497c12f60567cbb20ea626fd909f94955ebac;hpb=3c8b32baaac62855e2c9f5bfdb5ede9685ce2b76 diff --git a/lib/pq/Gateway/Table.php b/lib/pq/Gateway/Table.php index a25b2ad..e365e37 100644 --- a/lib/pq/Gateway/Table.php +++ b/lib/pq/Gateway/Table.php @@ -6,7 +6,7 @@ use \pq\Query\Expr as QueryExpr; use \pq\Query\Writer as QueryWriter; use \pq\Query\Executor as QueryExecutor; -class Table +class Table implements \SplSubject { /** * @var \pq\Connection @@ -53,6 +53,11 @@ class Table */ protected $identity; + /** + * @var \pq\Gateway\Table\Attributes + */ + protected $attributes; + /** * @var \pq\Gateway\Table\Relations */ @@ -64,9 +69,9 @@ class Table protected $metadataCache; /** - * @var \pq\Gateway\Table\LockInterface + * @var \SplObjectStorage */ - protected $lock; + protected $observers; /** * @param string $table @@ -96,6 +101,7 @@ class Table throw new \InvalidArgumentException("Table must have a name"); } $this->conn = $conn ?: static::$defaultConnection ?: new \pq\Connection; + $this->observers = new \SplObjectStorage; } /** @@ -103,13 +109,12 @@ class Table * @return string */ function __toString() { - return sprintf("postgresql://%s:%s@%s:%d/%s?%s#%s", + return (string) sprintf("postgresql://%s:%s@%s:%d/%s#%s", $this->conn->user, $this->conn->pass, $this->conn->host, $this->conn->port, $this->conn->db, - $this->conn->options, $this->getName() ); } @@ -205,38 +210,36 @@ class Table return $this->identity; } + /** + * Get the table attribute definition (column list) + * @return \pq\Table\Attributes + */ + function getAttributes() { + if (!isset($this->attributes)) { + $this->attributes = new Table\Attributes($this); + } + return $this->attributes; + } + /** * Get foreign key relations - * @param string $to fkey - * @return \pq\Gateway\Table\Relations|stdClass + * @return \pq\Gateway\Table\Relations */ - function getRelations($to = null) { + function getRelations() { if (!isset($this->relations)) { $this->relations = new Table\Relations($this); } - if (isset($to)) { - if (!isset($this->relations->$to)) { - return null; - } - return $this->relations->$to; - } return $this->relations; } /** - * Check whether a certain relation exists - * @param string $name + * Get a foreign key relation * @param string $table - * @return bool + * @param string $ref + * @return \pq\Gateway\Table\Reference */ - function hasRelation($name, $table = null) { - if (!($rel = $this->getRelations($name))) { - return false; - } - if (!isset($table)) { - return true; - } - return isset($rel->$table); + function getRelation($table, $ref = null) { + return $this->getRelations()->getReference($table, $ref); } /** @@ -254,21 +257,32 @@ class Table } /** - * Set a lock provider - * @param \pq\Gateway\Table\LockInterface $lock + * Attach an observer + * @param \SplObserver * @return \pq\Gateway\Table */ - function setLock(Table\LockInterface $lock) { - $this->lock = $lock; + function attach(\SplObserver $observer) { + $this->observers->attach($observer); return $this; } /** - * Get any set lock provider - * @return \pq\Gateway\Table\LockIntferace + * Detach an observer + * @param \SplObserver + * @return \pq\Gateway\Table */ - function getLock() { - return $this->lock; + function detach(\SplObserver $observer) { + $this->observers->attach($observer); + return $this; + } + + /** + * Implements \SplSubject + */ + function notify(\pq\Gateway\Row $row = null, $event = null, array &$where = null) { + foreach ($this->observers as $observer) { + $observer->update($this, $row, $event, $where); + } } /** @@ -333,51 +347,45 @@ class Table /** * Get the child rows of a row by foreign key * @param \pq\Gateway\Row $foreign - * @param string $name optional fkey name + * @param string $ref optional fkey name * @param string $order * @param int $limit * @param int $offset * @return mixed */ - function of(Row $foreign, $name = null, $order = null, $limit = 0, $offset = 0) { + function of(Row $foreign, $ref = null, $order = null, $limit = 0, $offset = 0) { // select * from $this where $this->$foreignColumn = $foreign->$referencedColumn - if (!isset($name)) { - $name = $foreign->getTable()->getName(); + if (!($rel = $this->getRelation($foreign->getTable()->getName(), $ref))) { + return $this->onResult(null); } - if (!$foreign->getTable()->hasRelation($name, $this->getName())) { - return $this->onResult(null); + $where = array(); + foreach ($rel as $key => $ref) { + $where["$key="] = $foreign->$ref; } - $rel = $foreign->getTable()->getRelations($name)->{$this->getName()}; - return $this->find( - array($rel->foreignColumn . "=" => $foreign->{$rel->referencedColumn}), - $order, $limit, $offset - ); + return $this->find($where, $order, $limit, $offset); } /** * Get the parent rows of a row by foreign key - * @param \pq\Gateway\Row $me - * @param string $foreign - * @param string $order - * @param int $limit - * @param int $offset + * @param \pq\Gateway\Row $foreign + * @param string $ref * @return mixed */ - function by(Row $me, $foreign, $order = null, $limit = 0, $offset = 0) { - // select * from $foreign where $foreign->$referencedColumn = $me->$foreignColumn + function by(Row $foreign, $ref = null) { + // select * from $this where $this->$referencedColumn = $me->$foreignColumn - if (!$this->hasRelation($foreign, $this->getName())) { + if (!($rel = $foreign->getTable()->getRelation($this->getName(), $ref))) { return $this->onResult(null); } - $rel = $this->getRelations($foreign)->{$this->getName()}; - return static::resolve($rel->referencedTable)->find( - array($rel->referencedColumn . "=" => $me->{$rel->foreignColumn}), - $order, $limit, $offset - ); + $where = array(); + foreach ($rel as $key => $ref) { + $where["$ref="] = $foreign->$key; + } + return $this->find($where); } /** @@ -394,12 +402,18 @@ class Table $query = $this->getQueryWriter()->reset(); $query->write("SELECT", "$qthis.*", "FROM", $qthis); foreach ($relations as $relation) { - $query->write("JOIN", $relation->foreignTable)->write("ON")->criteria( - array( - "{$relation->referencedTable}.{$relation->referencedColumn}=" => - new QueryExpr("{$relation->foreignTable}.{$relation->foreignColumn}") - ) - ); + if (!($relation instanceof Table\Reference)) { + $relation = static::resolve($relation)->getRelation($this->getName()); + } + $query->write("JOIN", $relation->foreignTable)->write("ON"); + foreach ($relation as $key => $ref) { + $query->criteria( + array( + "{$relation->referencedTable}.{$ref}=" => + new QueryExpr("{$relation->foreignTable}.{$key}") + ) + ); + } } if ($where) { $query->write("WHERE")->criteria($where); @@ -430,7 +444,7 @@ class Table $params = array(); foreach ($data as $key => $val) { $query->write($first ? "(" : ",", $key); - $params[] = $query->param($val); + $params[] = $query->param($val, $this->getAttributes()->getColumn($key)->type); $first and $first = false; } $query->write(") VALUES (", $params, ")"); @@ -456,7 +470,8 @@ class Table $query->write("UPDATE", $this->conn->quoteName($this->name)); $first = true; foreach ($data as $key => $val) { - $query->write($first ? "SET" : ",", $key, "=", $query->param($val)); + $query->write($first ? "SET" : ",", $key, "=", + $query->param($val, $this->getAttributes()->getColumn($key)->type)); $first and $first = false; } $query->write("WHERE")->criteria($where);