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\Relations
56 * @var \pq\Gateway\Table\CacheInterface
58 protected $metadataCache;
61 * @param string $table
62 * @return \pq\Gateway\Table
64 public static function resolve($table) {
65 if ($table instanceof Table
) {
68 if (is_callable(static::$defaultResolver)) {
69 if (($resolved = call_user_func(static::$defaultResolver, $table))) {
73 return new Table($table);
78 * @param \pq\Connection $conn
79 * @param array $dependents
81 function __construct($name, \pq\Connection
$conn = null) {
83 $this->conn
= $conn ?
: static::$defaultConnection ?
: new \pq\Connection
;
87 * Get the complete PostgreSQL connection string
90 function __toString() {
91 return sprintf("postgresql://%s:%s@%s:%d/%s?%s#%s",
103 * Set the rowset prototype
104 * @param mixed $rowset
105 * @return \pq\Gateway\Table
107 function setRowsetPrototype($rowset) {
108 $this->rowset
= $rowset;
113 * Get the rowset prototype
116 function getRowsetPrototype() {
117 return $this->rowset
;
121 * Set the query writer
122 * @param \pq\Query\WriterInterface $query
123 * @return \pq\Gateway\Table
125 function setQueryWriter(\pq\Query\WriterInterface
$query) {
126 $this->query
= $query;
131 * Get the query writer
132 * @return \pq\Query\WriterInterface
134 function getQueryWriter() {
136 $this->query
= new QueryWriter
;
142 * Set the query executor
143 * @param \pq\Query\ExecutorInterface $exec
144 * @return \pq\Gateway\Table
146 function setQueryExecutor(\pq\Query\ExecutorInterface
$exec) {
152 * Get the query executor
153 * @return \pq\Query\ExecutorInterface
155 function getQueryExecutor() {
157 $this->exec
= new QueryExecutor($this->conn
);
163 * Get the metadata cache
164 * @return \pq\Gateway\Table\CacheInterface
166 function getMetadataCache() {
167 if (!isset($this->metadatCache
)) {
168 $this->metadataCache
= static::$defaultMetadataCache ?
: new Table\StaticCache
;
170 return $this->metadataCache
;
174 * Set the metadata cache
175 * @param \pq\Gateway\Table\CacheInterface $cache
177 function setMetadataCache(Table\CacheInterface
$cache) {
178 $this->metadataCache
= $cache;
183 * Get foreign key relations
184 * @param string $to fkey
185 * @return \pq\Gateway\Table\Relations|stdClass
187 function getRelations($to = null) {
188 if (!isset($this->relations
)) {
189 $this->relations
= new Table\
Relations($this);
192 if (!isset($this->relations
->$to)) {
195 return $this->relations
->$to;
197 return $this->relations
;
201 * Check whether a certain relation exists
202 * @param string $name
203 * @param string $table
206 function hasRelation($name, $table = null) {
207 if (!($rel = $this->getRelations($name))) {
210 if (!isset($table)) {
213 return isset($rel->$table);
217 * @return \pq\Connection
219 function getConnection() {
232 * @param \pq\Query\WriterInterface $query
235 protected function execute(QueryWriter
$query) {
236 return $this->getQueryExecutor()->execute($query, array($this, "onResult"));
240 * Retreives the result of an executed query
241 * @param \pq\Result $result
244 public function onResult(\pq\Result
$result = null) {
245 if ($result && $result->status
!= \pq\Result
::TUPLES_OK
) {
249 $rowset = $this->getRowsetPrototype();
250 if (is_callable($rowset)) {
251 return $rowset($result);
253 return new $rowset($this, $result);
260 * Find rows in the table
261 * @param array $where
262 * @param array|string $order
267 function find(array $where = null, $order = null, $limit = 0, $offset = 0) {
268 $query = $this->getQueryWriter()->reset();
269 $query->write("SELECT * FROM", $this->conn
->quoteName($this->name
));
271 $query->write("WHERE")->criteria($where);
274 $query->write("ORDER BY", $order);
277 $query->write("LIMIT", $limit);
279 $query->write("OFFSET", $offset);
280 return $this->execute($query);
284 * Get the child rows of a row by foreign key
285 * @param \pq\Gateway\Row $foreign
286 * @param string $name optional fkey name
287 * @param string $order
292 function of(Row
$foreign, $name = null, $order = null, $limit = 0, $offset = 0) {
293 // select * from $this where $this->$foreignColumn = $foreign->$referencedColumn
296 $name = $this->getName();
299 if (!$foreign->getTable()->hasRelation($name, $this->getName())) {
300 return $this->onResult(null);
302 $rel = $foreign->getTable()->getRelations($name)->{$this->getName()};
305 array($rel->foreignColumn
. "=" => $foreign->{$rel->referencedColumn
}),
306 $order, $limit, $offset
311 * Get the parent rows of a row by foreign key
312 * @param \pq\Gateway\Row $me
313 * @param string $foreign
314 * @param string $order
319 function by(Row
$me, $foreign, $order = null, $limit = 0, $offset = 0) {
320 // select * from $foreign where $foreign->$referencedColumn = $me->$foreignColumn
322 if (!$this->hasRelation($foreign, $this->getName())) {
323 return $this->onResult(null);
325 $rel = $this->getRelations($foreign)->{$this->getName()};
327 return static::resolve($rel->referencedTable
)->find(
328 array($rel->referencedColumn
. "=" => $me->{$rel->foreignColumn
}),
329 $order, $limit, $offset
334 * Insert a row into the table
336 * @param string $returning
339 function create(array $data = null, $returning = "*") {
340 $query = $this->getQueryWriter()->reset();
341 $query->write("INSERT INTO", $this->conn
->quoteName($this->name
));
345 foreach ($data as $key => $val) {
346 $query->write($first ?
"(" : ",", $key);
347 $params[] = $query->param($val);
348 $first and $first = false;
350 $query->write(") VALUES (", $params, ")");
352 $query->write("DEFAULT VALUES");
355 if (strlen($returning)) {
356 $query->write("RETURNING", $returning);
358 return $this->execute($query);
362 * Update rows in the table
363 * @param array $where
365 * @param string $returning
368 function update(array $where, array $data, $returning = "*") {
369 $query = $this->getQueryWriter()->reset();
370 $query->write("UPDATE", $this->conn
->quoteName($this->name
));
372 foreach ($data as $key => $val) {
373 $query->write($first ?
"SET" : ",", $key, "=", $query->param($val));
374 $first and $first = false;
376 $query->write("WHERE")->criteria($where);
377 if (strlen($returning)) {
378 $query->write("RETURNING", $returning);
380 return $this->execute($query);
384 * Delete rows from the table
385 * @param array $where
386 * @param string $returning
389 function delete(array $where, $returning = null) {
390 $query = $this->getQueryWriter()->reset();
391 $query->write("DELETE FROM", $this->conn
->quoteName($this->name
));
392 $query->write("WHERE")->criteria($where);
393 if (strlen($returning)) {
394 $query->write("RETURNING", $returning);
396 return $this->execute($query);