storage enhancements
[m6w6/pq-gateway] / lib / pq / Mapper / Storage.php
index 8e0fcb4df7b20f8b8347e8e241e3c9626f180820..042b6947874b0addc923f1f39684d14d1139f8a6 100644 (file)
 
 namespace pq\Mapper;
 
+use InvalidArgumentException;
+use pq\Connection;
+use pq\Gateway\Table;
+use pq\Transaction;
+
 class Storage implements StorageInterface
 {
        /**
-        *
-        * @var pq\Mapper\MapInterface
+        * The mapping of this storage
+        * @var MapInterface
         */
        private $map;
 
        /**
-        * @var \pq\Gateway\Table
+        * The mapper
+        * @var Mapper
+        */
+       private $mapper;
+
+       /**
+        * The underlying table gateway
+        * @var Table
         */
        private $gateway;
-       
-       function __construct(MapInterface $map) {
-               $this->map = $map;
-               $this->gateway = $map->getGateway();
+
+       /**
+        * Create a storage for $map
+        * @param Mapper $mapper
+        * @param string $class
+        */
+       function __construct(Mapper $mapper, $class) {
+               $this->mapper = $mapper;
+               $this->map = $mapper->mapOf($class);
+               $this->gateway = $this->map->getGateway();
        }
-       
+
+       /**
+        * Find by PK
+        * @param mixed $pk
+        * @return object
+        */
+       function get($pk) {
+               $id = $this->gateway->getIdentity();
+               if (count($id) == 1 && is_scalar($pk)) {
+                       $vals = [$pk];
+               } elseif (is_array($pk) && count($pk) === count($id)) {
+                       $vals = $pk;
+               } else {
+                       throw InvalidArgumentException(
+                               "Insufficient identity provided; not all fields of %s are provided in %s",
+                               json_encode($id->getColumns()), json_encode($pk));
+               }
+
+               $keys = array_map(function($v) {
+                       return "$v=";
+               }, $id->getColumns());
+
+               $rowset = $this->gateway->find(array_combine($keys, $vals));
+               
+               return $this->map->map($rowset->current());
+       }
+
+       /**
+        * Find
+        * @param array $where
+        * @param string $order
+        * @param int $limit
+        * @param int $offset
+        * @return object[]
+        */
        function find($where = [], $order = null, $limit = null, $offset = null) {
                /* @var pq\Gateway\Rowset $rowset */
                $rowset = $this->gateway->find($where, $order, $limit, $offset);
                return $this->map->mapAll($rowset);
        }
-       
+
+       /**
+        * Find parent
+        * @param object $object
+        * @param string $refName
+        * @return object
+        */
+       function by($object, $refName) {
+               $row = $this->mapper->mapOf($object)->getObjects()->getRow($object);
+               $this->map->refOf($row, $refName, $objects);
+               return current($objects);
+       }
+
+       /**
+        * Find childs
+        * @param object $object
+        * @param string $refName
+        * @return array
+        */
+       function of($object, $refName) {
+               $row = $this->mapper->mapOf($object)->getObjects()->getRow($object);
+               $this->map->allOf($row, $refName, $objects);
+               return $objects;
+       }
+
+       /**
+        * Delete
+        * @param object $object
+        */
        function delete($object) {
                $cache = $this->map->getObjects();
                $row = $cache->asRow($object)->delete();
                $cache->resetObject($row);
                $cache->resetRow($object);
        }
-       
+
+       /**
+        * Save
+        * @param object $object
+        */
        function save($object) {
                $this->map->unmap($object);
        }
-       
-}
\ No newline at end of file
+
+       /**
+        * Buffer in a transaction
+        */
+       function buffer() {
+               switch ($this->gateway->getConnection()->transactionStatus) {
+               case Connection::TRANS_INTRANS:
+                       break;
+               default:
+                       $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("START TRANSACTION"));
+               }
+       }
+
+       /**
+        * Commit
+        */
+       function flush() {
+               switch ($this->gateway->getConnection()->transactionStatus) {
+               case Connection::TRANS_IDLE:
+                       break;
+               default:
+                       $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("COMMIT"));
+               }
+       }
+
+       /**
+        * Rollback
+        */
+       function discard() {
+               switch ($this->gateway->getConnection()->transactionStatus) {
+               case Connection::TRANS_IDLE:
+                       break;
+               default:
+                       $this->gateway->getQueryExecutor()->execute(new \pq\Query\Writer("ROLLBACK"));
+               }
+               $this->map->getObjects()->reset();
+       }
+}