import poc
authorMichael Wallner <mike@php.net>
Mon, 4 Mar 2013 10:39:44 +0000 (11:39 +0100)
committerMichael Wallner <mike@php.net>
Mon, 4 Mar 2013 10:39:44 +0000 (11:39 +0100)
lib/pq/Gateway/Cell.php [new file with mode: 0644]
lib/pq/Gateway/Row.php [new file with mode: 0644]
lib/pq/Gateway/Rowset.php [new file with mode: 0644]
lib/pq/Gateway/Table.php [new file with mode: 0644]
lib/pq/Query/Expr.php [new file with mode: 0644]
lib/pq/Query/Writer.php [new file with mode: 0644]
lib/tmp.php [new file with mode: 0644]

diff --git a/lib/pq/Gateway/Cell.php b/lib/pq/Gateway/Cell.php
new file mode 100644 (file)
index 0000000..1955552
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+namespace pq\Gateway;
+
+class Cell
+{
+}
diff --git a/lib/pq/Gateway/Row.php b/lib/pq/Gateway/Row.php
new file mode 100644 (file)
index 0000000..981a58d
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace pq\Gateway;
+
+class Row
+{
+       /**
+        * @var \pq\Gateway\Table
+        */
+       protected $table;
+       
+       /**
+        * @var array
+        */
+       protected $data;
+       
+       /**
+        * @var array
+        */
+       protected $mods = array();
+       
+       /**
+        * @param \pq\Gateway\Table $table
+        * @param array $data
+        */
+       function __construct(Table $table, array $data = null) {
+               $this->table = $table;
+               $this->data = $data;
+       }
+       
+       function __get($p) {
+               if (!isset($this->mod[$p])) {
+                       $this->mod[$p] = new Cell($this, $p);
+               }
+               return $this->mod[$p];
+       }
+       
+       function create() {
+               $this->data = $this->table->create($this->mods)->getIterator()->current()->data;
+               $this->mods = array();
+               return $this;
+       }
+       
+       function update() {
+               $this->data = $this->table->update($this->data, $this->mods)->getIterator()->current()->data;
+               $this->mods = array();
+               return $this;
+       }
+       
+       function delete() {
+               $this->data = $this->table->delete($this->data, "*")->getIterator()->current()->data;
+               $this->mods = array();
+               return $this;
+       }
+}
diff --git a/lib/pq/Gateway/Rowset.php b/lib/pq/Gateway/Rowset.php
new file mode 100644 (file)
index 0000000..4cf062f
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+namespace pq\Gateway;
+
+class Rowset implements \IteratorAggregate
+{
+       /**
+        * @var \pq\Gateway\Table
+        */
+       protected $table;
+       
+       /**
+        * @var array
+        */
+       protected $rows;
+       
+       /**
+        * @param \pq\Gateway\Table $table
+        * @param \pq\Result $result
+        */
+       function __construct(Table $table, \pq\Result $result, $rowClass = "\\pq\\Gateway\\Row") {
+               $this->table = $table;
+               while (($row = $result->fetchRow(\pq\Result::FETCH_ASSOC))) {
+                       $this->rows[] = new $rowClass($this->table, $row);
+               }
+       }
+       
+       /**
+        * @implements \IteratorAggregate
+        * @return \pq\Gateway\ArrayIterator
+        */
+       function getIterator() {
+               return new \ArrayIterator($this->rows);
+       }
+       
+       /**
+        * Filter by callback
+        * @param callable $cb
+        * @return \pq\Gateway\Rowset
+        */
+       function filter(callable $cb) {
+               $rowset = clone $this;
+               $rowset->rows = array_filter($this->rows, $cb);
+               return $rowset;
+       }
+}
diff --git a/lib/pq/Gateway/Table.php b/lib/pq/Gateway/Table.php
new file mode 100644 (file)
index 0000000..295e7a2
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+namespace pq\Gateway;
+
+use \pq\Query\Writer as QueryWriter;
+
+class Table
+{
+       /**
+        * @var \pq\Connection
+        */
+       protected $connection;
+
+       /**
+        * @var string
+        */
+       protected $name;
+       
+       /**
+        * @var string
+        */
+       protected $rowset;
+
+       /**
+        * @param \pq\Connection $c
+        * @param string $name
+        */
+       function __construct(\pq\Connection $c, $name, $rowset = "\\pq\\Gateway\\Rowset") {
+               $this->connection = $c;
+               $this->name = $name;
+               $this->rowset = $rowset;
+       }
+       
+       /**
+        * Accessor to read-only properties
+        * @param string $p
+        */
+       function __get($p) {
+               return $this->$p;
+       }
+
+       /**
+        * @param \pq\Query\Writer $query
+        * @param array $criteria
+        * @param string $join
+        */
+       protected function criteria(QueryWriter $query, array $criteria, $join = "AND") {
+               $joinable = false;
+               $query->write("(");
+               foreach ($criteria as $lop => $rop) {
+                       if (is_array($rop)) {
+                               if ($joinable) {
+                                       $query->write(")", $join, "(");
+                               }
+                               $this->criteria($query, $rop, is_int($lop) ? "AND" : $lop);
+                       } else {
+                               if ($joinable) {
+                                       $query->write(")", $join, "(");
+                               }
+                               if (!is_int($lop)) {
+                                       $query->write($lop);
+                               }
+                               $query->write($query->param($rop));
+                       }
+                       $joinable or $joinable = true;
+               }
+               $query->write(")");
+       }
+
+       /**
+        * Find rows in the table
+        * @param array $where
+        * @param array|string $order
+        * @param int $limit
+        * @param int $offset
+        * @return \pq\Result
+        */
+       function find(array $where = null, $order = null, $limit = 0, $offset = 0) {
+               $query = new QueryWriter("SELECT * FROM ". $this->connection->quoteName($this->name));
+               if ($where) {
+                       $this->criteria($query->write("WHERE"), $where);
+               }
+               if ($order) {
+                       $query->write("ORDER BY", $order);
+               }
+               if ($limit) {
+                       $query->write("LIMIT", $limit);
+               }
+               $query->write("OFFSET", $offset);
+               return new Rowset($this, $query->exec($this->connection));
+       }
+
+       /**
+        * Insert a row into the table
+        * @param array $data
+        * @param string $returning
+        * @return \pq\Result
+        */
+       function create(array $data, $returning = "*") {
+               $params = array();
+               $query = new QueryWriter("INSERT INTO ".$this->connection->quoteName($this->name)." (");
+               foreach ($data as $key => $val) {
+                       $query->write($key);
+                       $params[] = $query->param($val);
+               }
+               $query->write(") VALUES (", $params, ")");
+               if (strlen($returning)) {
+                       $query->write("RETURNING", $returning);
+               }
+               $result = $query->exec($this->connection);
+               if ($result->status == \pq\Result::TUPLES_OK) {
+                       $rowset = $this->rowset;
+                       return new $rowset($this, $result);
+               }
+               return $result;
+       }
+
+       /**
+        * Update rows in the table
+        * @param array $where
+        * @param array $data
+        * @param string $returning
+        * @retunr \pq\Result
+        */
+       function update(array $where, array $data, $returning = "*") {
+               $query = new QueryWriter("UPDATE ".$this->connection->quoteName($this->name)." SET");
+               foreach ($data as $key => $val) {
+                       $query->write($key, "=", $query->param($val));
+               }
+               $this->criteria($query->write("WHERE"), $where);
+               if (strlen($returning)) {
+                       $query->write("RETURNING", $returning);
+               }
+               $result = $query->exec($this->connection);
+               if ($result->status == \pq\Result::TUPLES_OK) {
+                       $rowset = $this->rowset;
+                       return new $rowset($this, $result);
+               }
+               return $result;
+       }
+
+       /**
+        * Delete rows from the table
+        * @param array $where
+        * @param string $returning
+        * @return pq\Result
+        */
+       function delete(array $where, $returning = null) {
+               $query = new QueryWriter("DELETE FROM ".$this->connection->quoteName($this->name));
+               $this->criteria($query->write("WHERE"), $where);
+               if (strlen($returning)) {
+                       $query->write("RETURNING", $returning);
+               }
+               $result = $query->exec($this->connection);
+               if ($result->status == \pq\Result::TUPLES_OK) {
+                       $rowset = $this->rowset;
+                       return new $rowset($this, $result);
+               }
+               return $result;
+       }
+}
+
diff --git a/lib/pq/Query/Expr.php b/lib/pq/Query/Expr.php
new file mode 100644 (file)
index 0000000..d02b13f
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+namespace pq\Query;
+
+class Expr
+{
+       /**
+        * @var string
+        */
+       protected $expression;
+
+       /**
+        * @param string $e the expression or a format string followed by arguments
+        * @param string ...
+        */
+       function __construct($e) {
+               if (func_num_args() > 1) {
+                       $this->expression = call_user_func_array("sprintf", func_get_args());
+               } else {
+                       $this->expression = $e;
+               }
+       }
+
+       /**
+        * Get the string expression
+        * @return string
+        */
+       function __toString() {
+               return (string) $this->expression;
+       }
+}
diff --git a/lib/pq/Query/Writer.php b/lib/pq/Query/Writer.php
new file mode 100644 (file)
index 0000000..61589c3
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+namespace pq\Query;
+
+/**
+ * A very simple query writer used by \pq\Gateway
+ */
+class Writer
+{
+       /**
+        * @var string
+        */
+       protected $query;
+       
+       /**
+        * @var array
+        */
+       protected $params;
+       
+       /**
+        * @var array
+        */
+       protected $types;
+
+       /**
+        * @param string $query initial query string
+        * @param array $params intial set of params
+        * @param array $types the types of the params
+        */
+       function __construct($query = "", array $params = array(), array $types = array()) {
+               $this->query = $query;
+               $this->params = $params;
+               $this->types = $types;
+       }
+
+       /**
+        * Get the query string
+        * @return string
+        */
+       function __toString() {
+               return $this->query;
+       }
+
+       /**
+        * Get the query params
+        * @return array
+        */
+       function getParams() {
+               return $this->params;
+       }
+
+       /**
+        * Get the param types
+        * @return array
+        */
+       function getTypes() {
+               return $this->types;
+       }
+
+       /**
+        * Reset
+        * @return \pq\Query\Writer
+        */
+       function reset() {
+               $this->query = "";
+               $this->params = array();
+               $this->types = array();
+               return $this;
+       }
+
+       /**
+        * Append to the query string
+        * @return \pq\Query\Writer
+        */
+       function write() {
+               $this->query .= array_reduce(func_get_args(), function($q, $v) {
+                       return $q . " " . (is_array($v) ? implode(", ", $v) : $v);
+               });
+               return $this;
+       }
+
+       /**
+        * Write a param placeholder and push the param onto the param list
+        * @param mixed $param
+        * @param string $type
+        * @return string
+        */
+       function param($param, $type = null) {
+               if ($param instanceof Expr) {
+                       return (string) $param;
+               }
+               $this->params[] = $param;
+               $this->types[] = $type;
+               return "\$".count($this->params);
+       }
+
+       /**
+        * Execute the query through \pq\Connection::execParams($this, $this->params, $this->types)
+        * @param \pq\Connection $c
+        * @return \pq\Result
+        */
+       function exec(\pq\Connection $c) {
+               return $c->execParams($this, $this->params, $this->types);
+       }
+}
diff --git a/lib/tmp.php b/lib/tmp.php
new file mode 100644 (file)
index 0000000..ef50e26
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+require "./pq/Query/Expr.php";
+require "./pq/Query/Writer.php";
+require "./pq/Gateway/Table.php";
+require "./pq/Gateway/Rowset.php";
+require "./pq/Gateway/Row.php";
+require "./pq/Gateway/Cell.php";
+
+class FooModel extends \pq\Gateway\Table {
+       function __construct(\pq\Connection $c) {
+               parent::__construct($c, "foo", "FooCollection");
+       }
+}
+
+class Foo extends \pq\Gateway\Row {
+       
+}
+
+class FooCollection extends \pq\Gateway\Rowset {
+       function __construct(\pq\Gateway\Table $table, \pq\Result $result) {
+               parent::__construct($table, $result, "Foo");
+       }
+}
+
+$conn = new \pq\Connection;
+$types = new \pq\Types($conn);
+$table = new FooModel($conn);
+print_r( $table->find(array("dt" => new \pq\Query\Expr("between %s and %s", $conn->quote("2013-03-01"), $conn->quote("2013-03-04")))) );
+echo PHP_EOL;
+print_r( $table->find(array("id>" => 1, "OR" => array(array("id=" => 1), array("id="=>2)))));
+echo PHP_EOL;
+print_r( $table->find(array("OR" => array("id>" => 1, "OR" => array(array("id=" => 1), array("id="=>2))))));
+echo PHP_EOL;
+print_r( $table->create(array("data" => "blabla")) );
+echo PHP_EOL;
+print_r( $table->create(array("data" => new \pq\Query\Expr("DEFAULT"))) );
+echo PHP_EOL;
+print_r( $table->update(array("id=" => 4), array("data" => "die 4")) );
+echo PHP_EOL;
+print_r( $table->delete(array(new \pq\Query\Expr("data is null"))) );
+echo PHP_EOL;
\ No newline at end of file