5 use \pq\Query\Writer
as QueryWriter
;
6 use \pq\Query\Executor
as QueryExecutor
;
13 public static $defaultConnection;
18 public static $defaultResolver;
21 * @var \pq\Gateway\Table\CacheInterface
23 public static $defaultMetadataCache;
38 protected $rowset = "\\pq\\Gateway\\Rowset";
41 * @var \pq\Query\WriterIterface
46 * @var \pq\Query\ExecutorInterface
51 * @var \pq\Gateway\Table\Identity
56 * @var \pq\Gateway\Table\Relations
61 * @var \pq\Gateway\Table\CacheInterface
63 protected $metadataCache;
66 * @var \pq\Gateway\Table\LockInterface
71 * @param string $table
72 * @return \pq\Gateway\Table
74 public static function resolve($table) {
75 if ($table instanceof Table
) {
78 if (is_callable(static::$defaultResolver)) {
79 if (($resolved = call_user_func(static::$defaultResolver, $table))) {
83 return new Table($table);
88 * @param \pq\Connection $conn
89 * @param array $dependents
91 function __construct($name, \pq\Connection
$conn = null) {
93 $this->conn
= $conn ?
: static::$defaultConnection ?
: new \pq\Connection
;
97 * Get the complete PostgreSQL connection string
100 function __toString() {
101 return sprintf("postgresql://%s:%s@%s:%d/%s?%s#%s",
107 $this->conn
->options
,
113 * Set the rowset prototype
114 * @param mixed $rowset
115 * @return \pq\Gateway\Table
117 function setRowsetPrototype($rowset) {
118 $this->rowset
= $rowset;
123 * Get the rowset prototype
126 function getRowsetPrototype() {
127 return $this->rowset
;
131 * Set the query writer
132 * @param \pq\Query\WriterInterface $query
133 * @return \pq\Gateway\Table
135 function setQueryWriter(\pq\Query\WriterInterface
$query) {
136 $this->query
= $query;
141 * Get the query writer
142 * @return \pq\Query\WriterInterface
144 function getQueryWriter() {
146 $this->query
= new QueryWriter
;
152 * Set the query executor
153 * @param \pq\Query\ExecutorInterface $exec
154 * @return \pq\Gateway\Table
156 function setQueryExecutor(\pq\Query\ExecutorInterface
$exec) {
162 * Get the query executor
163 * @return \pq\Query\ExecutorInterface
165 function getQueryExecutor() {
167 $this->exec
= new QueryExecutor($this->conn
);
173 * Get the metadata cache
174 * @return \pq\Gateway\Table\CacheInterface
176 function getMetadataCache() {
177 if (!isset($this->metadatCache
)) {
178 $this->metadataCache
= static::$defaultMetadataCache ?
: new Table\StaticCache
;
180 return $this->metadataCache
;
184 * Set the metadata cache
185 * @param \pq\Gateway\Table\CacheInterface $cache
187 function setMetadataCache(Table\CacheInterface
$cache) {
188 $this->metadataCache
= $cache;
193 * Get the primary key
194 * @return \pq\Gateway\Table\Identity
196 function getIdentity() {
197 if (!isset($this->identity
)) {
198 $this->identity
= new Table\
Identity($this);
200 return $this->identity
;
204 * Get foreign key relations
205 * @param string $to fkey
206 * @return \pq\Gateway\Table\Relations|stdClass
208 function getRelations($to = null) {
209 if (!isset($this->relations
)) {
210 $this->relations
= new Table\
Relations($this);
213 if (!isset($this->relations
->$to)) {
216 return $this->relations
->$to;
218 return $this->relations
;
222 * Check whether a certain relation exists
223 * @param string $name
224 * @param string $table
227 function hasRelation($name, $table = null) {
228 if (!($rel = $this->getRelations($name))) {
231 if (!isset($table)) {
234 return isset($rel->$table);
238 * @return \pq\Connection
240 function getConnection() {
252 * Set a lock provider
253 * @param \pq\Gateway\Table\LockInterface $lock
254 * @return \pq\Gateway\Table
256 function setLock(Table\LockInterface
$lock) {
262 * Get any set lock provider
263 * @return \pq\Gateway\Table\LockIntferace
271 * @param \pq\Query\WriterInterface $query
274 protected function execute(QueryWriter
$query) {
275 return $this->getQueryExecutor()->execute($query, array($this, "onResult"));
279 * Retreives the result of an executed query
280 * @param \pq\Result $result
283 public function onResult(\pq\Result
$result = null) {
284 if ($result && $result->status
!= \pq\Result
::TUPLES_OK
) {
288 $rowset = $this->getRowsetPrototype();
289 if (is_callable($rowset)) {
290 return $rowset($result);
292 return new $rowset($this, $result);
299 * Find rows in the table
300 * @param array $where
301 * @param array|string $order
304 * @param string $lock
307 function find(array $where = null, $order = null, $limit = 0, $offset = 0, $lock = null) {
308 $query = $this->getQueryWriter()->reset();
309 $query->write("SELECT * FROM", $this->conn
->quoteName($this->name
));
311 $query->write("WHERE")->criteria($where);
314 $query->write("ORDER BY", $order);
317 $query->write("LIMIT", $limit);
320 $query->write("OFFSET", $offset);
323 $query->write("FOR", $lock);
325 return $this->execute($query);
329 * Get the child rows of a row by foreign key
330 * @param \pq\Gateway\Row $foreign
331 * @param string $name optional fkey name
332 * @param string $order
337 function of(Row
$foreign, $name = null, $order = null, $limit = 0, $offset = 0) {
338 // select * from $this where $this->$foreignColumn = $foreign->$referencedColumn
341 $name = $foreign->getTable()->getName();
344 if (!$foreign->getTable()->hasRelation($name, $this->getName())) {
345 return $this->onResult(null);
347 $rel = $foreign->getTable()->getRelations($name)->{$this->getName()};
350 array($rel->foreignColumn
. "=" => $foreign->{$rel->referencedColumn
}),
351 $order, $limit, $offset
356 * Get the parent rows of a row by foreign key
357 * @param \pq\Gateway\Row $me
358 * @param string $foreign
359 * @param string $order
364 function by(Row
$me, $foreign, $order = null, $limit = 0, $offset = 0) {
365 // select * from $foreign where $foreign->$referencedColumn = $me->$foreignColumn
367 if (!$this->hasRelation($foreign, $this->getName())) {
368 return $this->onResult(null);
370 $rel = $this->getRelations($foreign)->{$this->getName()};
372 return static::resolve($rel->referencedTable
)->find(
373 array($rel->referencedColumn
. "=" => $me->{$rel->foreignColumn
}),
374 $order, $limit, $offset
379 * Insert a row into the table
381 * @param string $returning
384 function create(array $data = null, $returning = "*") {
385 $query = $this->getQueryWriter()->reset();
386 $query->write("INSERT INTO", $this->conn
->quoteName($this->name
));
390 foreach ($data as $key => $val) {
391 $query->write($first ?
"(" : ",", $key);
392 $params[] = $query->param($val);
393 $first and $first = false;
395 $query->write(") VALUES (", $params, ")");
397 $query->write("DEFAULT VALUES");
400 if (strlen($returning)) {
401 $query->write("RETURNING", $returning);
403 return $this->execute($query);
407 * Update rows in the table
408 * @param array $where
410 * @param string $returning
413 function update(array $where, array $data, $returning = "*") {
414 $query = $this->getQueryWriter()->reset();
415 $query->write("UPDATE", $this->conn
->quoteName($this->name
));
417 foreach ($data as $key => $val) {
418 $query->write($first ?
"SET" : ",", $key, "=", $query->param($val));
419 $first and $first = false;
421 $query->write("WHERE")->criteria($where);
422 if (strlen($returning)) {
423 $query->write("RETURNING", $returning);
425 return $this->execute($query);
429 * Delete rows from the table
430 * @param array $where
431 * @param string $returning
434 function delete(array $where, $returning = null) {
435 $query = $this->getQueryWriter()->reset();
436 $query->write("DELETE FROM", $this->conn
->quoteName($this->name
));
437 $query->write("WHERE")->criteria($where);
438 if (strlen($returning)) {
439 $query->write("RETURNING", $returning);
441 return $this->execute($query);