more versatile transaction handling
[m6w6/pq-gateway] / lib / pq / Gateway / Rowset.php
index d6134caaa314de1bfee7ba4a620fd98322cacd26..15352591e282a95f5aac57177b1908d1855da5be 100644 (file)
@@ -38,7 +38,7 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
         * @param \pq\Result $result
         * @return \pq\Gateway\Rowset
         */
-       function __invoke(\pq\Result $result) {
+       function __invoke(\pq\Result $result = null) {
                $that = clone $this;
                $that->hydrate($result);
                return $that;
@@ -54,7 +54,7 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
                $this->rows  = array();
                
                if ($result) {
-                       $row = $this->row;
+                       $row = $this->getRowPrototype();
 
                        if (is_callable($row)) {
                                while (($data = $result->fetchRow(\pq\Result::FETCH_ASSOC))) {
@@ -82,6 +82,14 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
                return $this;
        }
        
+       /**
+        * Get the row prototype
+        * @return mixed
+        */
+       function getRowPrototype() {
+               return $this->row;
+       }
+       
        /**
         * @return \pq\Gateway\Table
         */
@@ -91,12 +99,14 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
        
        /**
         * Create all rows of this rowset
-        * @param bool $txn
+        * @param mixed $txn
         * @return \pq\Gateway\Rowset
         * @throws Exception
         */
        function create($txn = true) {
-               $txn = $txn ? $this->table->getConnection()->startTransaction() : false;
+               if ($txn && !($txn instanceof pq\Transaction)) {
+                       $txn = $this->table->getConnection()->startTransaction();
+               }
                try {
                        foreach ($this->rows as $row) {
                                $row->create();
@@ -115,12 +125,14 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
        
        /**
         * Update all rows of this rowset
-        * @param bool $txn
+        * @param mixed $txn
         * @return \pq\Gateway\Rowset
         * @throws \Exception
         */
        function update($txn = true) {
-               $txn = $txn ? $this->table->getConnection()->startTransaction() : false;
+               if ($txn && !($txn instanceof pq\Transaction)) {
+                       $txn = $this->table->getConnection()->startTransaction();
+               }
                try {
                        foreach ($this->rows as $row) {
                                $row->update();
@@ -139,12 +151,14 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
        
        /**
         * Delete all rows of this rowset
-        * @param type $txn
+        * @param mixed $txn
         * @return \pq\Gateway\Rowset
         * @throws \Exception
         */
        function delete($txn = true) {
-               $txn = $txn ? $this->table->getConnection()->startTransaction() : false;
+               if ($txn && !($txn instanceof pq\Transaction)) {
+                       $txn = $this->table->getConnection()->startTransaction();
+               }
                try {
                        foreach ($this->rows as $row) {
                                $row->delete();
@@ -176,12 +190,14 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
        function rewind() {
                $this->index = 0;
        }
+       
        /**
         * @implements \Iterator
         */
        function next() {
                ++$this->index;
        }
+       
        /**
         * @implements \Iterator
         * @return bool
@@ -189,13 +205,18 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
        function valid() {
                return $this->index < count($this->rows);
        }
+       
        /**
         * @implements \Iterator
         * @return \pq\Gateway\Row
         */
        function current() {
+               if (!$this->valid()) {
+                       throw new \OutOfBoundsException("Invalid row index {$this->index}");
+               }
                return $this->rows[$this->index];
        }
+       
        /**
         * @implements \Iterator
         * @return int
@@ -252,6 +273,7 @@ class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
         */
        function filter(callable $cb) {
                $rowset = clone $this;
+               $rowset->index = 0;
                $rowset->rows = array_filter($this->rows, $cb);
                return $rowset;
        }