Commit 084f71e4 authored by Jens Segers's avatar Jens Segers

Modified the compilation of wheres, fixes #216

parent d849f112
......@@ -667,29 +667,30 @@ class Builder extends \Illuminate\Database\Query\Builder {
*/
protected function compileWheres()
{
if (!$this->wheres) return array();
// The where's to compile.
$wheres = $this->wheres ?: array();
// The new list of compiled wheres
$wheres = array();
// We will add all compiled wheres to this array.
$compiled = array();
foreach ($this->wheres as $i => &$where)
foreach ($wheres as $i => &$where)
{
// Make sure the operator is in lowercase
// Make sure the operator is in lowercase.
if (isset($where['operator']))
{
$where['operator'] = strtolower($where['operator']);
// Fix elemMatch
// Fix elemMatch.
if ($where['operator'] == 'elemmatch')
{
$where['operator'] = 'elemMatch';
}
}
// Convert id's
// Convert id's.
if (isset($where['column']) && $where['column'] == '_id')
{
// Multiple values
// Multiple values.
if (isset($where['values']))
{
foreach ($where['values'] as &$value)
......@@ -697,48 +698,57 @@ class Builder extends \Illuminate\Database\Query\Builder {
$value = $this->convertKey($value);
}
}
// Single value
elseif (isset($where['value']))
// Single value.
else if (isset($where['value']))
{
$where['value'] = $this->convertKey($where['value']);
}
}
// Convert dates
// Convert DateTime values to MongoDate.
if (isset($where['value']) && $where['value'] instanceof DateTime)
{
$where['value'] = new MongoDate($where['value']->getTimestamp());
}
// First item of chain
if ($i == 0 && count($this->wheres) > 1 && $where['boolean'] == 'and')
// The next item in a "chain" of wheres devices the boolean of the
// first item. So if we see that there are multiple wheres, we will
// use the operator of the next where.
if ($i == 0 and count($wheres) > 1 and $where['boolean'] == 'and')
{
// Copy over boolean value of next item in chain
$where['boolean'] = $this->wheres[$i+1]['boolean'];
$where['boolean'] = $wheres[$i+1]['boolean'];
}
// Delegate
// We use different methods to compile different wheres.
$method = "compileWhere{$where['type']}";
$compiled = $this->{$method}($where);
$result = $this->{$method}($where);
// Check for or
// Wrap the where with an $or operator.
if ($where['boolean'] == 'or')
{
$compiled = array('$or' => array($compiled));
$result = array('$or' => array($result));
}
// If there are multiple wheres, we will wrap it with $and. This is needed
// to make nested wheres work.
else if (count($wheres) > 1)
{
$result = array('$and' => array($result));
}
// Merge compiled where
$wheres = array_merge_recursive($wheres, $compiled);
// Merge the compiled where with the others.
$compiled = array_merge_recursive($compiled, $result);
}
return $wheres;
return $compiled;
}
protected function compileWhereBasic($where)
{
extract($where);
// Replace like with MongoRegex
// Replace like with a MongoRegex instance.
if ($operator == 'like')
{
$operator = '=';
......@@ -751,7 +761,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
$value = new MongoRegex("/$regex/i");
}
if (!isset($operator) || $operator == '=')
if ( ! isset($operator) or $operator == '=')
{
$query = array($column => $value);
}
......
......@@ -255,4 +255,29 @@ class QueryTest extends TestCase {
$this->assertEquals(6, count($users));
}
public function testMultipleOr()
{
$users = User::where(function($query)
{
$query->where('age', 35)->orWhere('age', 33);
})
->where(function($query)
{
$query->where('name', 'John Doe')->orWhere('name', 'Jane Doe');
})->get();
$this->assertEquals(2, count($users));
$users = User::where(function($query)
{
$query->orWhere('age', 35)->orWhere('age', 33);
})
->where(function($query)
{
$query->orWhere('name', 'John Doe')->orWhere('name', 'Jane Doe');
})->get();
$this->assertEquals(2, count($users));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment