refactor relations
[m6w6/pq-gateway] / lib / pq / Gateway / Table / Relations.php
index 3e4d7fbd8280a622d352ff1e9e607c3b3fe74fc9..700f3fcad524829daf7b009632ac6f669ea8a75a 100644 (file)
@@ -4,13 +4,17 @@ namespace pq\Gateway\Table;
 
 use \pq\Gateway\Table;
 
+/*
+ *      case when att1.attname like '%\_'||att2.attname then
+               substring(att1.attname from '^.*(?=_'||att2.attname||'$)')
+        else
+               att1.attname
+        end
+ */
 const RELATION_SQL = <<<SQL
 select
-        case att1.attname
-        when att2.attname
-               then att1.attname
-               else substring(att1.attname from '^.*(?=_'||att2.attname||'$)')
-        end          as "id"
+       regexp_replace(att1.attname, '_'||att2.attname||'$', '')
+                  as "name"
        ,cl1.relname  as "foreignTable"
        ,att1.attname as "foreignColumn"
        ,cl2.relname  as "referencedTable"
@@ -22,54 +26,93 @@ from
     ,pg_attribute  att1
     ,pg_attribute  att2
 where
-       (       cl1.relname = \$1
-       or      cl2.relname = \$1)
+        cl1.relname  = \$1
 and co.confrelid != 0
 and co.conrelid   = cl1.oid
 and co.conkey[1]  = att1.attnum and cl1.oid = att1.attrelid
 and co.confrelid  = cl2.oid
 and co.confkey[1] = att2.attnum and cl2.oid = att2.attrelid
 order by 
-        cl1.relname
-       ,att1.attnum
+       att1.attnum
 SQL;
 
 /**
- * A foreighn key implementation
+ * Foreign key list
  */
-class Relations
+class Relations implements \Countable, \IteratorAggregate
 {
        /**
-        * @var array
+        * @var object
         */
        protected $references;
        
+       /**
+        * @param \pq\Gateway\Table $table
+        */
        function __construct(Table $table) {
                $cache = $table->getMetadataCache();
-               if (!($this->references = $cache->get("$table#relations"))) {
+               if (!($this->references = $cache->get("$table:relations"))) {
                        $table->getQueryExecutor()->execute(
                                new \pq\Query\Writer(RELATION_SQL, array($table->getName())),
                                function($result) use($table, $cache) {
-                                       $this->references = $result->map(array(0,1), array(1,2,3,4), \pq\Result::FETCH_OBJECT);
-                                       $cache->set("$table#relations", $this->references);
+                                       $rel = $result->map([3,0], null, \pq\Result::FETCH_ASSOC);
+                                       foreach ($rel as $table => $reference) {
+                                               foreach ($reference as $name => $ref) {
+                                                       $this->references[$table][$name] = new Reference($ref);
+                                               }
+                                       }
+                                       $cache->set("$table:relations", $this->references);
                                }
                        );
                }
        }
        
        function __isset($r) {
-               return isset($this->references->$r);
+               return isset($this->references[$r]);
        }
        
        function __get($r) {
-               return $this->references->$r;
+               return $this->references[$r];
        }
        
        function __set($r, $v) {
-               $this->references->$r = $v;
+               $this->references[$r] = $v;
        }
        
        function __unset($r){
-               unset($this->references->$r);
+               unset($this->references[$r]);
+       }
+       
+       /**
+        * Get a reference to a table
+        * @param string $table
+        * @param string $ref
+        * @return \pq\Gateway\Table\Reference
+        */
+       function getReference($table, $ref = null) {
+               if (isset($this->references[$table])) {
+                       if (!strlen($ref)) {
+                               return current($this->references[$table]);
+                       }
+                       if (isset($this->references[$table][$ref])) {
+                               return $this->references[$table][$ref];
+                       }
+               }
+       }
+       
+       /**
+        * Implements \Countable
+        * @return int
+        */
+       function count() {
+               return array_sum(array_map("count", $this->references));
+       }
+       
+       /**
+        * Implements \IteratorAggregate
+        * @return \RecursiveArrayIterator
+        */
+       function getIterator() {
+               return new \RecursiveArrayIterator($this->references);
        }
 }