Index: branches/2.5/prototype/services/PostgreSQL.php
===================================================================
--- branches/2.5/prototype/services/PostgreSQL.php	(revision 7673)
+++ branches/2.5/prototype/services/PostgreSQL.php	(revision 7961)
@@ -47,23 +47,70 @@
     private $config; //Configuração
     public  $error = false; //Armazena um erro caso ocorra
-    
-    public function find ( $uri, $justthese = false, $criteria = false ){
-                   
-        $map =  Config::get($uri['concept'], 'PostgreSQL.mapping');
-        
-    $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map) : '';
-
-    $justthese = self::parseJustthese($justthese, $map);
-
-    return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .' '.$criteria );
-    }
-
-   public function read ( $uri, $justthese = false , $criteria = false){
-   
-      $map =  Config::get($uri['concept'], 'PostgreSQL.mapping');   
-      $justthese = self::parseJustthese($justthese, $map);
-      $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\'';
-   
-      return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .$criteria , true );
+    private $maps; //Cache de maps 
+    private $tables; 
+ 
+    public function find ( $uri, $justthese = false, $criteria = false ) 
+    { 
+        $condition = ''; 
+ 
+        if(!isset($this->maps[$uri['concept']]) || !isset($this->tables[$uri['concept']])) 
+        { 
+            $this->maps[$uri['concept']] = Config::get($uri['concept'], 'PostgreSQL.mapping'); 
+            $this->tables[$uri['concept']] =  Config::get($uri['concept'],'PostgreSQL.concept'); 
+        } 
+ 
+        $tables = $this->tables[$uri['concept']]; 
+ 
+        $justthese = self::parseJustthese($justthese, $this->maps[$uri['concept']] , $this->tables[$uri['concept']]); 
+ 
+        if(isset($criteria['condition'])) 
+        { 
+            $pc = $this->parseCondition($criteria['condition']); 
+ 
+            if(is_array($pc)) 
+            { 
+                if(!in_array($this->tables[$uri['concept']], $pc['tables'])) 
+                    $pc['tables'][] = $this->tables[$uri['concept']]; 
+ 
+                $tables = implode(',', $pc['tables'] ); 
+                $condition .= ' WHERE ' . $pc['conditions']; 
+            } 
+ 
+        } 
+ 
+        $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $this->maps[$uri['concept']] , $condition , $this->tables[$uri['concept']]) : $condition; 
+ 
+        return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. $tables .' '.$criteria ); 
+    } 
+ 
+   public function read ( $uri, $justthese = false , $criteria = false) 
+   { 
+       if(!isset($this->maps[$uri['concept']]) || !isset($this->tables[$uri['concept']])) 
+       { 
+           $this->maps[$uri['concept']] = Config::get($uri['concept'], 'PostgreSQL.mapping'); 
+           $this->tables[$uri['concept']] =  Config::get($uri['concept'],'PostgreSQL.concept'); 
+       } 
+ 
+       $condition = ' WHERE '.$this->tables[$uri['concept']].'.'.$this->maps[$uri['concept']]['id'].' = \''.addslashes( $uri['id'] ).'\''; 
+       $justthese = self::parseJustthese($justthese, $this->maps[$uri['concept']] , $this->tables[$uri['concept']]); 
+       $tables = $this->tables[$uri['concept']]; 
+ 
+       if(isset($criteria['condition'])) 
+       { 
+           $pc = $this->parseCondition($criteria['condition']); 
+ 
+           if(is_array($pc)) 
+           { 
+               if(!in_array($this->tables[$uri['concept']], $pc['tables'])) 
+                   $pc['tables'][] = $this->tables[$uri['concept']]; 
+ 
+               $tables = implode(',', $pc['tables'] ); 
+               $condition .= ' AND ' .  $pc['conditions']; 
+           } 
+       } 
+ 
+       $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $this->maps[$uri['concept']] , $condition , $this->tables[$uri['concept']]) : $condition; 
+ 
+       return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. $tables . ' ' . $criteria , true ); 
     }
     
@@ -85,8 +132,9 @@
         return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).' '.self::parseCriteria($criteria , $map));
     }
-        
+ 
     public function update ( $uri,  $data, $criteria = false ){
             $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
-        $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\'';
+        $criteria = ($criteria !== false) ? 
+            $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.pg_escape_string( $uri['id'] ).'\''; 
 
         return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).$criteria);
@@ -204,5 +252,5 @@
     
     private static function parseUpdateData( $data , &$map){
-                                        
+ 
         $d = array();
         foreach ($data as $i => $v)
@@ -216,5 +264,5 @@
     }
 
-    private static function parseCriteria( $criteria  , &$map , $query = '' ){               
+    private static function parseCriteria( $criteria  , &$map , $query = '' ){
     
         if( isset($criteria["filter"]) && $criteria["filter"] !== NULL )
@@ -230,5 +278,6 @@
           *     array( '=' , 'campo' , 'valor' )
         */
-                $query .= ($query === '') ?  'WHERE ('.self::parseFilter( $criteria['filter'] , $map).')' : ' AND ('.self::parseFilter( $criteria['filter'] , $map).')';
+               if($fc = self::parseFilter( $criteria['filter'] , $map)) 
+                    $query .= ($query === '') ?  'WHERE ('.$fc.')' : ' AND ('.$fc.')'; 
         }
         /*
@@ -324,5 +373,5 @@
     }
     
-    private static function parseJustthese($justthese , &$map)
+    static function parseJustthese($justthese , &$map , $table = '')
     {
                   
@@ -332,4 +381,7 @@
         $return = array();
 
+        if($table) 
+            $table .= '.'; 
+ 
         foreach ($justthese as &$value) 
         {
@@ -339,9 +391,67 @@
                 $return['deepness'][$value] = $map[$value];
             else
-                $return['select'][] = $map[$value] .' as "'. $value. '"';
+                $return['select'][] = $table . $map[$value] .' as "'. $value. '"';
         }
         
         $return['select'] = implode(', ', $return['select']);
-        return $return;  
+        return $return; 
+    } 
+ 
+    private function parseCondition( $condition ) 
+    { 
+        $tables = array(); 
+        $conditions = ''; 
+ 
+            $matches = array(); 
+            if(preg_match_all('/\s*(AND|^)\s*([a-z]+)\.([a-z]+)\s+\=\s+([a-z]+)\.([a-z]+)(\s|$)+/i', $condition ,$matches,PREG_SET_ORDER)) 
+            { 
+               foreach ($matches as $i => $v) 
+               { 
+                   if(!isset($this->maps[$v[2]]) || !isset($this->tables[$v[2]])) 
+                   { 
+                       $this->maps[$v[2]] = Config::get($v[2], 'PostgreSQL.mapping'); 
+                       $this->tables[$v[2]] =  Config::get($v[2],'PostgreSQL.concept'); 
+                   } 
+                   if(!isset($this->maps[$v[4]]) || !isset($this->tables[$v[4]])) 
+                   { 
+                       $this->maps[$v[4]] = Config::get($v[4], 'PostgreSQL.mapping'); 
+                       $this->tables[$v[4]] =  Config::get($v[4],'PostgreSQL.concept'); 
+                   } 
+ 
+                   if(isset($this->maps[$v[2]][$v[3]]) && isset($this->maps[$v[4]][$v[5]])) 
+                       $conditions .= ' '. $v[1] .' '. $this->tables[$v[2]] . '.' . $this->maps[$v[2]][$v[3]] .' = '. $this->tables[$v[4]] . '.' . $this->maps[$v[4]][$v[5]]; 
+                   else 
+                       continue; 
+ 
+                   if(!in_array( $this->tables[$v[2]], $tables)) 
+                       $tables[] = $this->tables[$v[2]]; 
+ 
+                   if(!in_array( $this->tables[$v[4]], $tables)) 
+                       $tables[] = $this->tables[$v[4]]; 
+               } 
+ 
+            } 
+ 
+            if(preg_match_all('/\s*(AND|OR|^)\s*([a-z]+)\.([a-z]+)\s+([\=\>\<\!]+|like)+\s+([a-z0-9\/\+\=]+)(\s|$)+/i', $condition , $matches ,PREG_SET_ORDER)) 
+            { 
+                foreach ($matches as $i => $v) 
+                { 
+                    if(!isset($this->maps[$v[2]]) || !isset($this->tables[$v[2]])) 
+                    { 
+                        $this->maps[$v[2]] = Config::get($v[2], 'PostgreSQL.mapping'); 
+                        $this->tables[$v[2]] =  Config::get($v[2],'PostgreSQL.concept'); 
+                    } 
+ 
+                    if(isset($this->maps[$v[2]][$v[3]])) 
+                        $conditions .= ' '. $v[1] .' '. $this->tables[$v[2]] . '.' . $this->maps[$v[2]][$v[3]] .' '.$v[4].' \''. pg_escape_string(base64_decode($v[5])) .'\''; 
+                    else 
+                        continue; 
+ 
+                    if(!in_array( $this->tables[$v[2]], $tables)) 
+                        $tables[] = $this->tables[$v[2]]; 
+                } 
+            } 
+ 
+        return (count($tables) > 0 && count($conditions ) > 0) ? array('tables' => $tables , 'conditions' => $conditions ) : '' ; 
     }
 
