flush
authorMichael Wallner <mike@php.net>
Sat, 9 Mar 2013 22:15:36 +0000 (23:15 +0100)
committerMichael Wallner <mike@php.net>
Sat, 9 Mar 2013 22:15:49 +0000 (23:15 +0100)
lib/pq/Gateway/Cell.php
lib/pq/Gateway/Table.php
lib/pq/Query/Executor.php [new file with mode: 0644]
lib/pq/Query/Executor/Async.php [new file with mode: 0644]
lib/pq/Query/ExecutorInterface.php [new file with mode: 0644]
lib/pq/Query/Expressible.php [new file with mode: 0644]
lib/pq/Query/ExpressibleInterface.php [new file with mode: 0644]
lib/pq/Query/Writer.php
lib/pq/Query/WriterInterface.php

index b284b75a7d98b7205f70bf3c54f1fc3487e7cf76..efa5fcbb3cd1154ecd99321bdddaf9e093a7a5c2 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace pq\Gateway;
 
-use \pq\Query\Expr;
+use \pq\Query\Expressible;
 
-class Cell
+class Cell extends Expressible
 {
        /**
         * @var \pq\Gateway\Row
@@ -16,11 +16,6 @@ class Cell
         */
        protected $name;
        
-       /**
-        * @var mixed
-        */
-       protected $data;
-       
        /**
         * @var bool
         */
@@ -33,28 +28,12 @@ class Cell
         * @param bool $dirty
         */
        function __construct(Row $row, $name, $data, $dirty = false) {
+               parent::__construct($data);
                $this->row = $row;
                $this->name = $name;
-               $this->data = $data;
                $this->dirty = $dirty;
        }
        
-       /**
-        * Get value as string
-        * @return string
-        */
-       function __toString() {
-               return (string) $this->data;
-       }
-       
-       /**
-        * Test whether the value is an unevaluated expression
-        * @return bool
-        */
-       function isExpr() {
-               return $this->data instanceof Expr;
-       }
-       
        /**
         * Check whether the cell has been modified
         * @return bool
@@ -64,46 +43,26 @@ class Cell
        }
        
        /**
-        * Get value
-        * @return mixed
-        */
-       function get() {
-               return $this->data;
-       }
-       
-       /**
-        * Modify the value in this cell
+        * Set the value
         * @param mixed $data
-        * @param string $op a specific operator
         * @return \pq\Gateway\Cell
         */
-       function mod($data, $op = null) {
-               if (!($this->data instanceof Expr)) {
-                       $this->data = new Expr($this->name);
-               }
-               
-               if ($data instanceof Expr) {
-                       $this->data->add($data);
-               } elseif (!isset($op) && is_numeric($data)) {
-                       $this->data->add(new Expr("+ $data"));
-               } else {
-                       $data = $this->row->getTable()->getConnection()->quote($data);
-                       $this->data->add(new Expr("%s %s", isset($op) ? $op : "||", $data));
-               }
-               
+       function set($data) {
+               parent::set($data);
                $this->dirty = true;
-               
                return $this;
        }
        
        /**
-        * Set the value in this cell
+        * Modify the value in this cell
         * @param mixed $data
+        * @param string $op a specific operator
         * @return \pq\Gateway\Cell
         */
-       function set($data) {
-               $this->data = $data;
+       function mod($data, $op = null) {
+               parent::mod($data, $op);
                $this->dirty = true;
                return $this;
        }
+       
 }
index ebab838bf672b8c01f2229720644a617038a17f0..2e82a214b37d89c90815aded33d340616f222005 100644 (file)
@@ -3,6 +3,7 @@
 namespace pq\Gateway;
 
 use \pq\Query\Writer as QueryWriter;
+use \pq\Query\Executor as QueryExecutor;
 
 class Table
 {
@@ -27,9 +28,14 @@ class Table
        protected $rowset = "\\pq\\Gateway\\Rowset";
        
        /**
-        * @var \pq\Query\Writer
+        * @var \pq\Query\WriterIterface
         */
        protected $query;
+       
+       /**
+        * @var \pq\Query\ExecutorInterface
+        */
+       protected $exec;
 
        /**
         * @param string $name
@@ -73,7 +79,31 @@ class Table
         * @return \pq\Query\WriterInterface
         */
        function getQueryWriter() {
-               return $this->query ?: new QueryWriter;
+               if (!$this->query) {
+                       $this->query = new QueryWriter;
+               }
+               return $this->query;
+       }
+       
+       /**
+        * Set the query executor
+        * @param \pq\Query\ExecutorInterface $exec
+        * @return \pq\Gateway\Table
+        */
+       function setQueryExecutor(\pq\Query\ExecutorInterface $exec) {
+               $this->exec = $exec;
+               return $this;
+       }
+       
+       /**
+        * Get the query executor
+        * @return \pq\Query\ExecutorInterface
+        */
+       function getQueryExecutor() {
+               if (!$this->exec) {
+                       $this->exec = new QueryExecutor($this->conn);
+               }
+               return $this->exec;
        }
        
        /**
@@ -92,12 +122,19 @@ class Table
 
        /**
         * Execute the query
-        * @param \pq\Query\Writer $query
+        * @param \pq\Query\WriterInterface $query
         * @return mixed
         */
        protected function execute(QueryWriter $query) {
-               $result = $query->exec($this->conn);
-               
+               return $this->getQueryExecutor()->execute($query, array($this, "onResult"));
+       }
+
+       /**
+        * Retreives the result of an executed query
+        * @param \pq\Result $result
+        * @return mixed
+        */
+       public function onResult(\pq\Result $result) {
                if ($result->status != \pq\Result::TUPLES_OK) {
                        return $result;
                }
@@ -111,14 +148,14 @@ class Table
                
                return $result;
        }
-
+       
        /**
         * Find rows in the table
         * @param array $where
         * @param array|string $order
         * @param int $limit
         * @param int $offset
-        * @return \pq\Result
+        * @return mixed
         */
        function find(array $where = null, $order = null, $limit = 0, $offset = 0) {
                $query = $this->getQueryWriter()->reset();
@@ -140,7 +177,7 @@ class Table
         * Insert a row into the table
         * @param array $data
         * @param string $returning
-        * @return \pq\Result
+        * @return mixed
         */
        function create(array $data = null, $returning = "*") {
                $query = $this->getQueryWriter()->reset();
@@ -169,7 +206,7 @@ class Table
         * @param array $where
         * @param array $data
         * @param string $returning
-        * @retunr \pq\Result
+        * @retunr mixed
         */
        function update(array $where, array $data, $returning = "*") {
                $query = $this->getQueryWriter()->reset();
@@ -190,7 +227,7 @@ class Table
         * Delete rows from the table
         * @param array $where
         * @param string $returning
-        * @return pq\Result
+        * @return mixed
         */
        function delete(array $where, $returning = null) {
                $query = $this->getQueryWriter()->reset();
diff --git a/lib/pq/Query/Executor.php b/lib/pq/Query/Executor.php
new file mode 100644 (file)
index 0000000..a01580a
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+namespace pq\Query;
+
+/**
+ * A synchronous query executor
+ */
+class Executor implements ExecutorInterface
+{
+       /**
+        * @var \pq\Connection
+        */
+       protected $conn;
+       
+       /**
+        * Create a synchronous query executor
+        * @param \pq\Connection $conn
+        */
+       function __construct(\pq\Connection $conn) {
+               $this->conn = $conn;
+       }
+       
+       /**
+        * @inheritdoc
+        * @return \pq\Connection
+        */
+       function getConnection() {
+               return $this->conn;
+       }
+       
+       /**
+        * @inheritdoc
+        * @param \pq\Connection $conn
+        * @return \pq\Query\Executor
+        */
+       function setConnection(\pq\Connection $conn) {
+               $this->conn = $conn;
+               return $this;
+       }
+       
+       /**
+        * Execute the query synchronously through \pq\Connection::execParams()
+        * @param \pq\Query\WriterInterface $query
+        * @param callable $callback
+        * @return mixed
+        */
+       function execute(WriterInterface $query, callable $callback) {
+               return $callback($this->getConnection()->execParams($query, $query->getParams(), $query->getTypes()));
+       }
+}
diff --git a/lib/pq/Query/Executor/Async.php b/lib/pq/Query/Executor/Async.php
new file mode 100644 (file)
index 0000000..d41f53e
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace pq\Query\Executor;
+
+use \pq\Query\ExecutorInterface;
+use \pq\Query\WriterInterface;
+
+use \React\Promise\Deferred;
+
+/**
+ * An asynchronous query executor
+ */
+class Async implements ExecutorInterface
+{
+       protected $conn;
+       
+       /**
+        * Create a asynchronous query exectuor
+        * @param \pq\Connection $conn
+        */
+       function __construct(\pq\Connection $conn) {
+               $this->conn = $conn;
+       }
+       
+       /**
+        * Get the connection
+        * @return \pq\Connection
+        */
+       function getConnection() {
+               return $this->conn;
+       }
+       
+       /**
+        * Set the connection
+        * @param \pq\Connection $conn
+        * @return \pq\Query\Executor\Async
+        */
+       function setConnection(\pq\Connection $conn) {
+               $this->conn = $conn;
+               return $this;
+       }
+       
+       /**
+        * Execute the query asynchronously through \pq\Connection::execParamsAsync()
+        * @param \pq\Query\WriterInterface $query
+        * @param callable $callback
+        * @return \React\Promise\DeferredPromise
+        */
+       function execute(WriterInterface $query, callable $callback) {
+               $deferred = new Deferred; // FIXME
+               $this->getConnection()->execParamsAsync($query, $query->getParams(), $query->getTypes(), 
+                       array($deferred->resolver(), "resolve"));
+               return $deferred->then($callback);
+       }
+}
diff --git a/lib/pq/Query/ExecutorInterface.php b/lib/pq/Query/ExecutorInterface.php
new file mode 100644 (file)
index 0000000..141ac23
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+namespace pq\Query;
+
+/**
+ * An executor of \pq\Query\Writer queries
+ */
+interface ExecutorInterface
+{
+       /**
+        * Get the connection
+        * @return \pq\Connection
+        */
+       function getConnection();
+       
+       /**
+        * Set the connection
+        * @param \pq\Connection $conn
+        * @return \pq\Query\ExecutorInterface
+        */
+       function setConnection(\pq\Connection $conn);
+       
+       /**
+        * Execute the query and return the \pq\Result through $callback
+        * @param \pq\Query\WriterInterface $query
+        * @param callable $callback
+        * @return mixed the result of the callback
+        */
+       function execute(WriterInterface $query, callable $callback);
+}
diff --git a/lib/pq/Query/Expressible.php b/lib/pq/Query/Expressible.php
new file mode 100644 (file)
index 0000000..ffcf7c2
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+namespace pq\Query;
+
+class Expressible implements ExpressibleInterface
+{
+       /**
+        * @var mixed
+        */
+       protected $data;
+       
+       function __construct($data) {
+               $this->data = $data;
+       }
+       
+       /**
+        * Get value as string
+        * @return string
+        */
+       function __toString() {
+               return (string) $this->data;
+       }
+       
+       /**
+        * Test whether the value is an unevaluated expression
+        * @return bool
+        */
+       function isExpr() {
+               return $this->data instanceof Expr;
+       }
+
+       /**
+        * Get value
+        * @return mixed
+        */
+       function get() {
+               return $this->data;
+       }
+       
+       /**
+        * Set the value
+        * @param mixed $data
+        * @return \pq\Query\Expressible
+        */
+       function set($data) {
+               $this->data = $data;
+               return $this;
+       }
+       
+       /**
+        * Modify the data
+        * @param mixed $data
+        * @param string $op a specific operator
+        * @return \pq\Query\Expressible
+        */
+       function mod($data, $op = null) {
+               if (!($this->data instanceof Expr)) {
+                       $this->data = new Expr($this->name);
+               }
+               
+               if ($data instanceof Expr) {
+                       $this->data->add($data);
+               } elseif (!isset($op) && is_numeric($data)) {
+                       $this->data->add(new Expr("+ $data"));
+               } else {
+                       $data = $this->row->getTable()->getConnection()->quote($data);
+                       $this->data->add(new Expr("%s %s", isset($op) ? $op : "||", $data));
+               }
+               
+               return $this;
+       }               
+}
\ No newline at end of file
diff --git a/lib/pq/Query/ExpressibleInterface.php b/lib/pq/Query/ExpressibleInterface.php
new file mode 100644 (file)
index 0000000..1009583
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+namespace pq\Query;
+
+interface ExpressibleInterface
+{
+       /**
+        * Get the contained value as string
+        * @return string
+        */
+       function __toString();
+       
+       /**
+        * Test whether we are an expression
+        * @return bool
+        */
+       function isExpr();
+       
+       /**
+        * Get the literal value or the expression
+        * @return mixed
+        */
+       function get();
+       
+       /**
+        * Set the contained value
+        * @param mixed $data
+        * @return \pq\Query\ExpressibleInterface
+        */
+       function set($data);
+       
+       /**
+        * Modify the data
+        * @param mixed $data
+        * @param string $op a specific operator
+        * @return \pq\Query\ExpressibleInterface
+        */
+       function mod($data, $op = null);
+
+}
index fd5e51aab692e42ec3995869b9321e863a645053..6e069450d046332460cae6becb0b71444186ed6d 100644 (file)
@@ -94,7 +94,7 @@ class Writer implements WriterInterface
         * @return string
         */
        function param($param, $type = null) {
-               if ($param instanceof \pq\Gateway\Cell) {
+               if ($param instanceof ExpressibleInterface) {
                        $param = $param->get();
                }
                if ($param instanceof Expr) {
@@ -132,13 +132,4 @@ class Writer implements WriterInterface
                }
                return $this;
        }
-
-       /**
-        * 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->getParams(), $this->getTypes());
-       }
 }
index 32e133baaa905c1e85d8f21ded78f653f37308f4..885d4ca8db00a0003ec4f03597cee20e40a8658e 100644 (file)
@@ -2,14 +2,49 @@
 
 namespace pq\Query;
 
+/**
+ * A query writer which supports easily constructing queries for \pq\Connection::execParams()
+ */
 interface WriterInterface
 {
+       /**
+        * Returns the plain constructed query as string
+        * @return string
+        */
        function __toString();
+       
+       /**
+        * Returns a list of parameters as array
+        * @return array
+        */
        function getParams();
+       
+       /**
+        * Returns a list any types associated with the params
+        */
        function getTypes();
+       
+       /**
+        * Reset the state of the query writer
+        */
+       function reset();
+       
+       /**
+        * Write plain SQL to the query
+        * @param mixed $arg variable list of arguments, arrays will be imploded to a comm separated list
+        */
        function write(/*...*/);
+       
+       /**
+        * Remember the parameter with any associated type and return $N to be written to the query string
+        * @param mixed $param a literal parameter, a \pq\Gateway\Table\Cell or a \pq\Query\Expr
+        * @param int $type the oid of the type of the param
+        */
        function param($param, $type = null);
+       
+       /**
+        * An array of AND/OR criteria
+        * @param array $criteria
+        */
        function criteria(array $criteria);
-       function reset();
-       function exec(\pq\Connection $c);
 }