Author: guilhermeblanco
Date: 2008-08-27 09:40:39 +0100 (Wed, 27 Aug 2008)
New Revision: 4848

Modified:
   branches/1.0/lib/Doctrine/Query.php
   branches/1.0/lib/Doctrine/Query/Abstract.php
   branches/1.0/tests/QueryTestCase.php
Log:
fixes #1331. Added andWhere, andWhereIn, andWhereNotIn, orWhere, orWhereIn, 
orWhereNotIn support to 1.0. Added some coverage to this support.

Modified: branches/1.0/lib/Doctrine/Query/Abstract.php
===================================================================
--- branches/1.0/lib/Doctrine/Query/Abstract.php        2008-08-27 06:46:28 UTC 
(rev 4847)
+++ branches/1.0/lib/Doctrine/Query/Abstract.php        2008-08-27 08:40:39 UTC 
(rev 4848)
@@ -338,7 +338,7 @@
         $q = '';
         $q .= ( ! empty($this->_dqlParts['select']))?  'SELECT '    . 
implode(', ', $this->_dqlParts['select']) : '';
         $q .= ( ! empty($this->_dqlParts['from']))?    ' FROM '     . 
implode(' ', $this->_dqlParts['from']) : '';
-        $q .= ( ! empty($this->_dqlParts['where']))?   ' WHERE '    . 
implode(' AND ', $this->_dqlParts['where']) : '';
+        $q .= ( ! empty($this->_dqlParts['where']))?   ' WHERE '    . 
implode(' ', $this->_dqlParts['where']) : '';
         $q .= ( ! empty($this->_dqlParts['groupby']))? ' GROUP BY ' . 
implode(', ', $this->_dqlParts['groupby']) : '';
         $q .= ( ! empty($this->_dqlParts['having']))?  ' HAVING '   . 
implode(' AND ', $this->_dqlParts['having']) : '';
         $q .= ( ! empty($this->_dqlParts['orderby']))? ' ORDER BY ' . 
implode(', ', $this->_dqlParts['orderby']) : '';
@@ -1190,14 +1190,42 @@
      */
     public function addWhere($where, $params = array())
     {
+        return $this->andWhere($where, $params);
+    }
+    
+    
+    public function andWhere($where, $params = array())
+    {
         if (is_array($params)) {
             $this->_params['where'] = array_merge($this->_params['where'], 
$params);
         } else {
             $this->_params['where'][] = $params;
         }
+        
+        if ($this->_hasDqlQueryPart('where')) {
+            $this->_addDqlQueryPart('where', 'AND', true);
+        }
+
         return $this->_addDqlQueryPart('where', $where, true);
     }
+    
+    
+    public function orWhere($where, $params = array())
+    {
+        if (is_array($params)) {
+            $this->_params['where'] = array_merge($this->_params['where'], 
$params);
+        } else {
+            $this->_params['where'][] = $params;
+        }
+        
+        if ($this->_hasDqlQueryPart('where')) {
+            $this->_addDqlQueryPart('where', 'OR', true);
+        }
 
+        return $this->_addDqlQueryPart('where', $where, true);
+    }
+
+
     /**
      * whereIn
      * adds IN condition to the query WHERE part
@@ -1209,6 +1237,51 @@
      */
     public function whereIn($expr, $params = array(), $not = false)
     {
+        return $this->andWhereIn($expr, $params, $not);
+    }
+
+
+    /**
+     * Adds IN condition to the query WHERE part
+     *
+     * @param string $expr The operand of the IN
+     * @param mixed $params An array of parameters or a simple scalar
+     * @param boolean $not Whether or not to use NOT in front of IN 
+     * @return Doctrine_Query
+     */
+    public function andWhereIn($expr, $params = array(), $not = false)
+    {
+        if ($this->_hasDqlQueryPart('where')) {
+            $this->_addDqlQueryPart('where', 'AND', true);
+        }
+
+        return $this->_addDqlQueryPart('where', $this->_processWhereIn($expr, 
$params, $not), true);
+    }
+
+
+    /**
+     * Adds IN condition to the query WHERE part
+     *
+     * @param string $expr The operand of the IN
+     * @param mixed $params An array of parameters or a simple scalar
+     * @param boolean $not Whether or not to use NOT in front of IN
+     * @return Doctrine_Query
+     */
+    public function orWhereIn($expr, $params = array(), $not = false)
+    {
+        if ($this->_hasDqlQueryPart('where')) {
+            $this->_addDqlQueryPart('where', 'OR', true);
+        }
+
+        return $this->_addDqlQueryPart('where', $this->_processWhereIn($expr, 
$params, $not), true);
+    }
+    
+
+    /**
+     * @nodoc
+     */
+    protected function _processWhereIn($expr, $params = array(), $not = false)
+    {
         $params = (array) $params;
 
         // if there's no params, return (else we'll get a WHERE IN (), invalid 
SQL)
@@ -1229,11 +1302,10 @@
 
         $this->_params['where'] = array_merge($this->_params['where'], 
$params);
 
-        $where = $expr . ($not === true ? ' NOT ':'') . ' IN (' . implode(', 
', $a) . ')';
-
-        return $this->_addDqlQueryPart('where', $where, true);
+        return $expr . ($not === true ? ' NOT ':'') . ' IN (' . implode(', ', 
$a) . ')';
     }
 
+
     /**
      * whereNotIn
      * adds NOT IN condition to the query WHERE part
@@ -1246,8 +1318,34 @@
     {
         return $this->whereIn($expr, $params, true);
     }
+    
 
     /**
+     * Adds NOT IN condition to the query WHERE part
+     *
+     * @param string $expr The operand of the NOT IN
+     * @param mixed $params An array of parameters or a simple scalar
+     * @return Doctrine_Query
+     */
+    public function andWhereNotIn($expr, $params = array())
+    {
+        return $this->andWhereIn($expr, $params, true);
+    }
+    
+
+    /**
+     * Adds NOT IN condition to the query WHERE part
+     *
+     * @param string $expr The operand of the NOT IN
+     * @param mixed $params An array of parameters or a simple scalar
+     * @return Doctrine_Query
+     */
+    public function orWhereNotIn($expr, $params = array())
+    {
+        return $this->orWhereIn($expr, $params, true);
+    }
+
+    /**
      * addGroupBy
      * adds fields to the GROUP BY part of the query
      *
@@ -1450,6 +1548,7 @@
     public function where($where, $params = array())
     {
         $this->_params['where'] = array();
+
         if (is_array($params)) {
             $this->_params['where'] = $params;
         } else {
@@ -1813,7 +1912,19 @@
     {
         return $this->_conn;
     }
+    
+    /**
+     * Checks if there's at least one DQL part defined to the internal parts 
collection.
+     *
+     * @param string $queryPartName  The name of the query part.
+     * @return boolean
+     */
+    protected function _hasDqlQueryPart($queryPartName)
+    {
+        return count($this->_dqlParts[$queryPartName]) > 0;
+    }
 
+
     /**
      * Adds a DQL part to the internal parts collection.
      *

Modified: branches/1.0/lib/Doctrine/Query.php
===================================================================
--- branches/1.0/lib/Doctrine/Query.php 2008-08-27 06:46:28 UTC (rev 4847)
+++ branches/1.0/lib/Doctrine/Query.php 2008-08-27 08:40:39 UTC (rev 4848)
@@ -1102,6 +1102,10 @@
 
         // apply inheritance to WHERE part
         if ( ! empty($string)) {
+            if (count($this->_sqlParts['where']) > 0) {
+                $this->_sqlParts['where'][] = 'AND';
+            }
+
             if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') {
                 $this->_sqlParts['where'][] = $string;
             } else {
@@ -1132,13 +1136,17 @@
 
                 // only append the subquery if it actually contains something
                 if ($subquery !== '') {
+                    if (count($this->_sqlParts['where']) > 0) {
+                        array_unshift($this->_sqlParts['where'], 'AND');
+                    }
+
                     array_unshift($this->_sqlParts['where'], 
$this->_conn->quoteIdentifier($field) . ' IN (' . $subquery . ')');
                 }
 
                 $modifyLimit = false;
         }
 
-        $q .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . 
implode(' AND ', $this->_sqlParts['where']) : '';
+        $q .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . 
implode(' ', $this->_sqlParts['where']) : '';
         $q .= ( ! empty($this->_sqlParts['groupby']))? ' GROUP BY ' . 
implode(', ', $this->_sqlParts['groupby'])  : '';
         $q .= ( ! empty($this->_sqlParts['having']))?  ' HAVING '   . 
implode(' AND ', $this->_sqlParts['having']): '';
         $q .= ( ! empty($this->_sqlParts['orderby']))? ' ORDER BY ' . 
implode(', ', $this->_sqlParts['orderby'])  : '';
@@ -1151,11 +1159,23 @@
 
         // return to the previous state
         if ( ! empty($string)) {
+            // We need to double pop if > 2
+            if (count($this->_sqlParts['where']) > 2) {
+                array_pop($this->_sqlParts['where']);
+            }
+
             array_pop($this->_sqlParts['where']);
         }
+
         if ($needsSubQuery) {
+            // We need to double shift if > 2
+            if (count($this->_sqlParts['where']) > 2) {
+                array_shift($this->_sqlParts['where']);
+            }
+
             array_shift($this->_sqlParts['where']);
         }
+
         $this->_sql = $q;
 
         return $q;
@@ -1240,7 +1260,7 @@
         }
 
         // all conditions must be preserved in subquery
-        $subquery .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . 
implode(' AND ', $this->_sqlParts['where'])  : '';
+        $subquery .= ( ! empty($this->_sqlParts['where']))?   ' WHERE '    . 
implode(' ', $this->_sqlParts['where'])  : '';
         $subquery .= ( ! empty($this->_sqlParts['groupby']))? ' GROUP BY ' . 
implode(', ', $this->_sqlParts['groupby'])   : '';
         $subquery .= ( ! empty($this->_sqlParts['having']))?  ' HAVING '   . 
implode(' AND ', $this->_sqlParts['having']) : '';
         $subquery .= ( ! empty($this->_sqlParts['orderby']))? ' ORDER BY ' . 
implode(', ', $this->_sqlParts['orderby'])   : '';
@@ -1797,11 +1817,15 @@
         $string = $this->getInheritanceCondition($this->getRootAlias());
 
         if ( ! empty($string)) {
+            if (count($where) > 0) {
+                $where[] = 'AND';
+            }
+            
             $where[] = $string;
         }
 
         // append conditions
-        $q .= ( ! empty($where)) ?  ' WHERE '  . implode(' AND ', $where) : '';
+        $q .= ( ! empty($where)) ?  ' WHERE '  . implode(' ', $where) : '';
 
         if ( ! empty($groupby)) {
             // Maintain existing groupby

Modified: branches/1.0/tests/QueryTestCase.php
===================================================================
--- branches/1.0/tests/QueryTestCase.php        2008-08-27 06:46:28 UTC (rev 
4847)
+++ branches/1.0/tests/QueryTestCase.php        2008-08-27 08:40:39 UTC (rev 
4848)
@@ -175,6 +175,103 @@
             $this->pass();
         }
     }
+    
+    
+    public function testOrQuerySupport()
+    {
+        $q1 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where('u.name = ?')
+            ->orWhere('u.loginname = ?');
+            
+        $q2 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where('u.name = ? OR u.loginname = ?');
+
+        $this->assertEqual(
+            $q1->getSqlQuery(),
+            'SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON 
e.id = p.entity_id ' .
+            'WHERE e.name = ? OR e.loginname = ? AND (e.type = 0)'
+        );
+        
+        $items1 = $q1->execute(array('zYne', 'jwage'), 
Doctrine::HYDRATE_ARRAY);
+        $items2 = $q2->execute(array('zYne', 'jwage'), 
Doctrine::HYDRATE_ARRAY);
+
+        $this->assertEqual(count($items1), count($items2));
+        
+        $q1->free();
+        $q2->free();
+    }
+
+
+    public function testOrQuerySupport2()
+    {
+        $q1 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where('u.name = ?')
+            ->andWhere('u.loginname = ?')
+            ->orWhere('u.id = ?');
+            
+        $q2 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where('(u.name = ? AND u.loginname = ?) OR (u.id = ?)');
+
+        $this->assertEqual(
+            $q1->getSqlQuery(),
+            'SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON 
e.id = p.entity_id ' .
+            'WHERE e.name = ? AND e.loginname = ? OR e.id = ? AND (e.type = 0)'
+        );
+        
+        $items1 = $q1->execute(array('jon', 'jwage', 4), 
Doctrine::HYDRATE_ARRAY);
+        $items2 = $q2->execute(array('jon', 'jwage', 4), 
Doctrine::HYDRATE_ARRAY);
+
+        $this->assertEqual(count($items1), count($items2));
+
+        $q1->free();
+        $q2->free();
+    }
+    
+    
+    public function testOrQuerySupport3()
+    {
+        $q1 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where("u.name = 'jon'")
+            ->andWhere("u.loginname = 'jwage'")
+            ->orWhere("u.id = 4")
+            ->orWhere("u.id = 5")
+            ->andWhere("u.name LIKE 'Arnold%'");
+            
+        $q2 = Doctrine_Query::create()
+            ->select('u.id')
+            ->from('User u')
+            ->leftJoin('u.Phonenumber p')
+            ->where("((u.name = 'jon' AND u.loginname = 'jwage') OR (u.id = 4 
OR (u.id = 5 AND u.name LIKE 'Arnold%')))");
+
+        $this->assertEqual(
+            $q1->getSqlQuery(),
+            "SELECT e.id AS e__id FROM entity e LEFT JOIN phonenumber p ON 
e.id = p.entity_id " .
+            "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)"
+        );
+        
+        $items1 = $q1->execute(array(), Doctrine::HYDRATE_ARRAY);
+        $items2 = $q2->execute(array(), Doctrine::HYDRATE_ARRAY);
+
+        $this->assertEqual(count($items1), count($items2));
+
+        $q1->free();
+        $q2->free();
+    }
 }
 
 class MyQuery extends Doctrine_Query


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"doctrine-svn" group.
 To post to this group, send email to [email protected]
 To unsubscribe from this group, send email to [EMAIL PROTECTED]
 For more options, visit this group at 
http://groups.google.co.uk/group/doctrine-svn?hl=en-GB
-~----------~----~----~----~------~----~------~--~---

Reply via email to