Changeset 4848

Show
Ignore:
Timestamp:
08/27/08 08:40:39 (10 months ago)
Author:
guilhermeblanco
Message:

fixes #1331. Added andWhere, andWhereIn, andWhereNotIn, orWhere, orWhereIn, orWhereNotIn support to 1.0. Added some coverage to this support.

Location:
branches/1.0
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/1.0/lib/Doctrine/Query.php

    r4839 r4848  
    11031103        // apply inheritance to WHERE part 
    11041104        if ( ! empty($string)) { 
     1105            if (count($this->_sqlParts['where']) > 0) { 
     1106                $this->_sqlParts['where'][] = 'AND'; 
     1107            } 
     1108 
    11051109            if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') { 
    11061110                $this->_sqlParts['where'][] = $string; 
     
    11331137                // only append the subquery if it actually contains something 
    11341138                if ($subquery !== '') { 
     1139                    if (count($this->_sqlParts['where']) > 0) { 
     1140                        array_unshift($this->_sqlParts['where'], 'AND'); 
     1141                    } 
     1142 
    11351143                    array_unshift($this->_sqlParts['where'], $this->_conn->quoteIdentifier($field) . ' IN (' . $subquery . ')'); 
    11361144                } 
     
    11391147        } 
    11401148 
    1141         $q .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . implode(' AND ', $this->_sqlParts['where']) : ''; 
     1149        $q .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . implode(' ', $this->_sqlParts['where']) : ''; 
    11421150        $q .= ( ! empty($this->_sqlParts['groupby']))? ' GROUP BY ' . implode(', ', $this->_sqlParts['groupby'])  : ''; 
    11431151        $q .= ( ! empty($this->_sqlParts['having']))?  ' HAVING '   . implode(' AND ', $this->_sqlParts['having']): ''; 
     
    11521160        // return to the previous state 
    11531161        if ( ! empty($string)) { 
     1162            // We need to double pop if > 2 
     1163            if (count($this->_sqlParts['where']) > 2) { 
     1164                array_pop($this->_sqlParts['where']); 
     1165            } 
     1166 
    11541167            array_pop($this->_sqlParts['where']); 
    11551168        } 
     1169 
    11561170        if ($needsSubQuery) { 
     1171            // We need to double shift if > 2 
     1172            if (count($this->_sqlParts['where']) > 2) { 
     1173                array_shift($this->_sqlParts['where']); 
     1174            } 
     1175 
    11571176            array_shift($this->_sqlParts['where']); 
    11581177        } 
     1178 
    11591179        $this->_sql = $q; 
    11601180 
     
    12411261 
    12421262        // all conditions must be preserved in subquery 
    1243         $subquery .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . implode(' AND ', $this->_sqlParts['where'])  : ''; 
     1263        $subquery .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . implode(' ', $this->_sqlParts['where'])  : ''; 
    12441264        $subquery .= ( ! empty($this->_sqlParts['groupby']))? ' GROUP BY ' . implode(', ', $this->_sqlParts['groupby'])   : ''; 
    12451265        $subquery .= ( ! empty($this->_sqlParts['having']))?  ' HAVING '   . implode(' AND ', $this->_sqlParts['having']) : ''; 
     
    17981818 
    17991819        if ( ! empty($string)) { 
     1820            if (count($where) > 0) { 
     1821                $where[] = 'AND'; 
     1822            } 
     1823             
    18001824            $where[] = $string; 
    18011825        } 
    18021826 
    18031827        // append conditions 
    1804         $q .= ( ! empty($where)) ?  ' WHERE '  . implode(' AND ', $where) : ''; 
     1828        $q .= ( ! empty($where)) ?  ' WHERE '  . implode(' ', $where) : ''; 
    18051829 
    18061830        if ( ! empty($groupby)) { 
  • branches/1.0/lib/Doctrine/Query/Abstract.php

    r4847 r4848  
    339339        $q .= ( ! empty($this->_dqlParts['select']))?  'SELECT '    . implode(', ', $this->_dqlParts['select']) : ''; 
    340340        $q .= ( ! empty($this->_dqlParts['from']))?    ' FROM '     . implode(' ', $this->_dqlParts['from']) : ''; 
    341         $q .= ( ! empty($this->_dqlParts['where']))?   ' WHERE '    . implode(' AND ', $this->_dqlParts['where']) : ''; 
     341        $q .= ( ! empty($this->_dqlParts['where']))?   ' WHERE '    . implode(' ', $this->_dqlParts['where']) : ''; 
    342342        $q .= ( ! empty($this->_dqlParts['groupby']))? ' GROUP BY ' . implode(', ', $this->_dqlParts['groupby']) : ''; 
    343343        $q .= ( ! empty($this->_dqlParts['having']))?  ' HAVING '   . implode(' AND ', $this->_dqlParts['having']) : ''; 
     
    11911191    public function addWhere($where, $params = array()) 
    11921192    { 
     1193        return $this->andWhere($where, $params); 
     1194    } 
     1195     
     1196     
     1197    public function andWhere($where, $params = array()) 
     1198    { 
    11931199        if (is_array($params)) { 
    11941200            $this->_params['where'] = array_merge($this->_params['where'], $params); 
     
    11961202            $this->_params['where'][] = $params; 
    11971203        } 
     1204         
     1205        if ($this->_hasDqlQueryPart('where')) { 
     1206            $this->_addDqlQueryPart('where', 'AND', true); 
     1207        } 
     1208 
    11981209        return $this->_addDqlQueryPart('where', $where, true); 
    11991210    } 
     1211     
     1212     
     1213    public function orWhere($where, $params = array()) 
     1214    { 
     1215        if (is_array($params)) { 
     1216            $this->_params['where'] = array_merge($this->_params['where'], $params); 
     1217        } else { 
     1218            $this->_params['where'][] = $params; 
     1219        } 
     1220         
     1221        if ($this->_hasDqlQueryPart('where')) { 
     1222            $this->_addDqlQueryPart('where', 'OR', true); 
     1223        } 
     1224 
     1225        return $this->_addDqlQueryPart('where', $where, true); 
     1226    } 
     1227 
    12001228 
    12011229    /** 
     
    12091237     */ 
    12101238    public function whereIn($expr, $params = array(), $not = false) 
     1239    { 
     1240        return $this->andWhereIn($expr, $params, $not); 
     1241    } 
     1242 
     1243 
     1244    /** 
     1245     * Adds IN condition to the query WHERE part 
     1246     * 
     1247     * @param string $expr The operand of the IN 
     1248     * @param mixed $params An array of parameters or a simple scalar 
     1249     * @param boolean $not Whether or not to use NOT in front of IN  
     1250     * @return Doctrine_Query 
     1251     */ 
     1252    public function andWhereIn($expr, $params = array(), $not = false) 
     1253    { 
     1254        if ($this->_hasDqlQueryPart('where')) { 
     1255            $this->_addDqlQueryPart('where', 'AND', true); 
     1256        } 
     1257 
     1258        return $this->_addDqlQueryPart('where', $this->_processWhereIn($expr, $params, $not), true); 
     1259    } 
     1260 
     1261 
     1262    /** 
     1263     * Adds IN condition to the query WHERE part 
     1264     * 
     1265     * @param string $expr The operand of the IN 
     1266     * @param mixed $params An array of parameters or a simple scalar 
     1267     * @param boolean $not Whether or not to use NOT in front of IN 
     1268     * @return Doctrine_Query 
     1269     */ 
     1270    public function orWhereIn($expr, $params = array(), $not = false) 
     1271    { 
     1272        if ($this->_hasDqlQueryPart('where')) { 
     1273            $this->_addDqlQueryPart('where', 'OR', true); 
     1274        } 
     1275 
     1276        return $this->_addDqlQueryPart('where', $this->_processWhereIn($expr, $params, $not), true); 
     1277    } 
     1278     
     1279 
     1280    /** 
     1281     * @nodoc 
     1282     */ 
     1283    protected function _processWhereIn($expr, $params = array(), $not = false) 
    12111284    { 
    12121285        $params = (array) $params; 
     
    12301303        $this->_params['where'] = array_merge($this->_params['where'], $params); 
    12311304 
    1232         $where = $expr . ($not === true ? ' NOT ':'') . ' IN (' . implode(', ', $a) . ')'; 
    1233  
    1234         return $this->_addDqlQueryPart('where', $where, true); 
    1235     } 
     1305        return $expr . ($not === true ? ' NOT ':'') . ' IN (' . implode(', ', $a) . ')'; 
     1306    } 
     1307 
    12361308 
    12371309    /** 
     
    12461318    { 
    12471319        return $this->whereIn($expr, $params, true); 
     1320    } 
     1321     
     1322 
     1323    /** 
     1324     * Adds NOT IN condition to the query WHERE part 
     1325     * 
     1326     * @param string $expr The operand of the NOT IN 
     1327     * @param mixed $params An array of parameters or a simple scalar 
     1328     * @return Doctrine_Query 
     1329     */ 
     1330    public function andWhereNotIn($expr, $params = array()) 
     1331    { 
     1332        return $this->andWhereIn($expr, $params, true); 
     1333    } 
     1334     
     1335 
     1336    /** 
     1337     * Adds NOT IN condition to the query WHERE part 
     1338     * 
     1339     * @param string $expr The operand of the NOT IN 
     1340     * @param mixed $params An array of parameters or a simple scalar 
     1341     * @return Doctrine_Query 
     1342     */ 
     1343    public function orWhereNotIn($expr, $params = array()) 
     1344    { 
     1345        return $this->orWhereIn($expr, $params, true); 
    12481346    } 
    12491347 
     
    14511549    { 
    14521550        $this->_params['where'] = array(); 
     1551 
    14531552        if (is_array($params)) { 
    14541553            $this->_params['where'] = $params; 
     
    18141913        return $this->_conn; 
    18151914    } 
     1915     
     1916    /** 
     1917     * Checks if there's at least one DQL part defined to the internal parts collection. 
     1918     * 
     1919     * @param string $queryPartName  The name of the query part. 
     1920     * @return boolean 
     1921     */ 
     1922    protected function _hasDqlQueryPart($queryPartName) 
     1923    { 
     1924        return count($this->_dqlParts[$queryPartName]) > 0; 
     1925    } 
     1926 
    18161927 
    18171928    /** 
  • branches/1.0/tests/QueryTestCase.php

    r4274 r4848  
    176176        } 
    177177    } 
     178     
     179     
     180    public function testOrQuerySupport() 
     181    { 
     182        $q1 = Doctrine_Query::create() 
     183            ->select('u.id') 
     184            ->from('User u') 
     185            ->leftJoin('u.Phonenumber p') 
     186            ->where('u.name = ?') 
     187            ->orWhere('u.loginname = ?'); 
     188             
     189        $q2 = Doctrine_Query::create() 
     190            ->select('u.id') 
     191            ->from('User u') 
     192            ->leftJoin('u.Phonenumber p') 
     193            ->where('u.name = ? OR u.loginname = ?'); 
     194 
     195        $this->assertEqual( 
     196            $q1->getSqlQuery(), 
     197            'SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id ' . 
     198            'WHERE e.name = ? OR e.loginname = ? AND (e.type = 0)' 
     199        ); 
     200         
     201        $items1 = $q1->execute(array('zYne', 'jwage'), Doctrine::HYDRATE_ARRAY); 
     202        $items2 = $q2->execute(array('zYne', 'jwage'), Doctrine::HYDRATE_ARRAY); 
     203 
     204        $this->assertEqual(count($items1), count($items2)); 
     205         
     206        $q1->free(); 
     207        $q2->free(); 
     208    } 
     209 
     210 
     211    public function testOrQuerySupport2() 
     212    { 
     213        $q1 = Doctrine_Query::create() 
     214            ->select('u.id') 
     215            ->from('User u') 
     216            ->leftJoin('u.Phonenumber p') 
     217            ->where('u.name = ?') 
     218            ->andWhere('u.loginname = ?') 
     219            ->orWhere('u.id = ?'); 
     220             
     221        $q2 = Doctrine_Query::create() 
     222            ->select('u.id') 
     223            ->from('User u') 
     224            ->leftJoin('u.Phonenumber p') 
     225            ->where('(u.name = ? AND u.loginname = ?) OR (u.id = ?)'); 
     226 
     227        $this->assertEqual( 
     228            $q1->getSqlQuery(), 
     229            'SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id ' . 
     230            'WHERE e.name = ? AND e.loginname = ? OR e.id = ? AND (e.type = 0)' 
     231        ); 
     232         
     233        $items1 = $q1->execute(array('jon', 'jwage', 4), Doctrine::HYDRATE_ARRAY); 
     234        $items2 = $q2->execute(array('jon', 'jwage', 4), Doctrine::HYDRATE_ARRAY); 
     235 
     236        $this->assertEqual(count($items1), count($items2)); 
     237 
     238        $q1->free(); 
     239        $q2->free(); 
     240    } 
     241     
     242     
     243    public function testOrQuerySupport3() 
     244    { 
     245        $q1 = Doctrine_Query::create() 
     246            ->select('u.id') 
     247            ->from('User u') 
     248            ->leftJoin('u.Phonenumber p') 
     249            ->where("u.name = 'jon'") 
     250            ->andWhere("u.loginname = 'jwage'") 
     251            ->orWhere("u.id = 4") 
     252            ->orWhere("u.id = 5") 
     253            ->andWhere("u.name LIKE 'Arnold%'"); 
     254             
     255        $q2 = Doctrine_Query::create() 
     256            ->select('u.id') 
     257            ->from('User u') 
     258            ->leftJoin('u.Phonenumber p') 
     259            ->where("((u.name = 'jon' AND u.loginname = 'jwage') OR (u.id = 4 OR (u.id = 5 AND u.name LIKE 'Arnold%')))"); 
     260 
     261        $this->assertEqual( 
     262            $q1->getSqlQuery(), 
     263            "SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id " . 
     264            "WHERE e.name = 'jon' AND e.loginname = 'jwage' OR e.id = 4 OR e.id = 5 AND e.name LIKE 'Arnold%' AND (e.type = 0)" 
     265        ); 
     266         
     267        $items1 = $q1->execute(array(), Doctrine::HYDRATE_ARRAY); 
     268        $items2 = $q2->execute(array(), Doctrine::HYDRATE_ARRAY); 
     269 
     270        $this->assertEqual(count($items1), count($items2)); 
     271 
     272        $q1->free(); 
     273        $q2->free(); 
     274    } 
    178275} 
    179276