fix nested queries.
This commit is contained in:
parent
97761f08f1
commit
9718d5cd0d
|
@ -38,7 +38,7 @@ class Query {
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new query instance for a model.
|
* Creat a new query instance for a model.
|
||||||
*
|
*
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
* @return void
|
* @return void
|
||||||
|
@ -118,7 +118,7 @@ public function hydrate($model, $results)
|
||||||
$new = new $class(array(), true);
|
$new = new $class(array(), true);
|
||||||
|
|
||||||
// We need to set the attributes manually in case the accessible property is
|
// We need to set the attributes manually in case the accessible property is
|
||||||
// set on the array which will prevent the mass assignment of attributes if
|
// set on the array which will prevent the mass assignemnt of attributes if
|
||||||
// we were to pass them in using the constructor or fill methods.
|
// we were to pass them in using the constructor or fill methods.
|
||||||
$new->fill_raw($result);
|
$new->fill_raw($result);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public function hydrate($model, $results)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The many to many relationships may have pivot table columns on them
|
// The many to many relationships may have pivot table column on them
|
||||||
// so we will call the "clean" method on the relationship to remove
|
// so we will call the "clean" method on the relationship to remove
|
||||||
// any pivot columns that are on the model.
|
// any pivot columns that are on the model.
|
||||||
if ($this instanceof Relationships\Has_Many_And_Belongs_To)
|
if ($this instanceof Relationships\Has_Many_And_Belongs_To)
|
||||||
|
@ -199,7 +199,7 @@ protected function nested_includes($relationship)
|
||||||
foreach ($this->model_includes() as $include => $constraints)
|
foreach ($this->model_includes() as $include => $constraints)
|
||||||
{
|
{
|
||||||
// To get the nested includes, we want to find any includes that begin
|
// To get the nested includes, we want to find any includes that begin
|
||||||
// the relationship with a dot, then we will strip off the leading
|
// the relationship and a dot, then we will strip off the leading
|
||||||
// nesting indicator and set the include in the array.
|
// nesting indicator and set the include in the array.
|
||||||
if (starts_with($include, $relationship.'.'))
|
if (starts_with($include, $relationship.'.'))
|
||||||
{
|
{
|
||||||
|
@ -217,23 +217,22 @@ protected function nested_includes($relationship)
|
||||||
*/
|
*/
|
||||||
protected function model_includes()
|
protected function model_includes()
|
||||||
{
|
{
|
||||||
$relationships = array_keys($this->model->includes);
|
$includes = array();
|
||||||
$implicits = array();
|
|
||||||
|
|
||||||
foreach ($relationships as $relationship)
|
foreach ($this->model->includes as $relationship => $constraints)
|
||||||
{
|
{
|
||||||
$parts = explode('.', $relationship);
|
// When eager loading relationships, constraints may be set on the eager
|
||||||
|
// load definition; however, is none are set, we need to swap the key
|
||||||
$prefix = '';
|
// and the value of the array since there are no constraints.
|
||||||
foreach ($parts as $part)
|
if (is_numeric($relationship))
|
||||||
{
|
{
|
||||||
$implicits[$prefix.$part] = NULL;
|
list($relationship, $constraints) = array($constraints, null);
|
||||||
$prefix .= $part.'.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$includes[$relationship] = $constraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all implicit includes to the explicit ones
|
return $includes;
|
||||||
return $this->model->includes + $implicits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,4 +277,4 @@ public function __call($method, $parameters)
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Laravel\Database;
|
use Laravel\Database;
|
||||||
use Paginator;
|
use Laravel\Paginator;
|
||||||
use Laravel\Database\Query\Grammars\Postgres;
|
use Laravel\Database\Query\Grammars\Postgres;
|
||||||
use Laravel\Database\Query\Grammars\SQLServer;
|
use Laravel\Database\Query\Grammars\SQLServer;
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ public function distinct()
|
||||||
*/
|
*/
|
||||||
public function select($columns = array('*'))
|
public function select($columns = array('*'))
|
||||||
{
|
{
|
||||||
$this->selects = is_array($columns) ? $columns : array($columns);
|
$this->selects = (array) $columns;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ public function join($table, $column1, $operator = null, $column2 = null, $type
|
||||||
{
|
{
|
||||||
// If the "column" is really an instance of a Closure, the developer is
|
// If the "column" is really an instance of a Closure, the developer is
|
||||||
// trying to create a join with a complex "ON" clause. So, we will add
|
// trying to create a join with a complex "ON" clause. So, we will add
|
||||||
// the join, and then call the Closure with the join.
|
// the join, and then call the Closure with the join/
|
||||||
if ($column1 instanceof Closure)
|
if ($column1 instanceof Closure)
|
||||||
{
|
{
|
||||||
$this->joins[] = new Query\Join($type, $table);
|
$this->joins[] = new Query\Join($type, $table);
|
||||||
|
@ -168,7 +168,7 @@ public function join($table, $column1, $operator = null, $column2 = null, $type
|
||||||
|
|
||||||
// If the column is just a string, we can assume that the join just
|
// If the column is just a string, we can assume that the join just
|
||||||
// has a simple on clause, and we'll create the join instance and
|
// has a simple on clause, and we'll create the join instance and
|
||||||
// add the clause automatically for the developer.
|
// add the clause automatically for the develoepr.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$join = new Query\Join($type, $table);
|
$join = new Query\Join($type, $table);
|
||||||
|
@ -283,7 +283,7 @@ public function or_where($column, $operator = null, $value = null)
|
||||||
*/
|
*/
|
||||||
public function or_where_id($value)
|
public function or_where_id($value)
|
||||||
{
|
{
|
||||||
return $this->or_where('id', '=', $value);
|
return $this->or_where('id', '=', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -395,7 +395,7 @@ public function or_where_not_null($column)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add nested constraints to the query.
|
* Add a nested where condition to the query.
|
||||||
*
|
*
|
||||||
* @param Closure $callback
|
* @param Closure $callback
|
||||||
* @param string $connector
|
* @param string $connector
|
||||||
|
@ -403,7 +403,24 @@ public function or_where_not_null($column)
|
||||||
*/
|
*/
|
||||||
public function where_nested($callback, $connector = 'AND')
|
public function where_nested($callback, $connector = 'AND')
|
||||||
{
|
{
|
||||||
call_user_func($callback, $this);
|
$type = 'where_nested';
|
||||||
|
|
||||||
|
// To handle a nested where statement, we will actually instantiate a new
|
||||||
|
// Query instance and run the callback over that instance, which will
|
||||||
|
// allow the developer to have a fresh query instance
|
||||||
|
$query = new Query($this->connection, $this->grammar, $this->from);
|
||||||
|
|
||||||
|
call_user_func($callback, $query);
|
||||||
|
|
||||||
|
// Once the callback has been run on the query, we will store the nested
|
||||||
|
// query instance on the where clause array so that it's passed to the
|
||||||
|
// query's query grammar instance when building.
|
||||||
|
if ($query->wheres !== null)
|
||||||
|
{
|
||||||
|
$this->wheres[] = compact('type', 'query', 'connector');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->bindings = array_merge($this->bindings, $query->bindings);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -436,7 +453,7 @@ private function dynamic_where($method, $parameters)
|
||||||
|
|
||||||
foreach ($segments as $segment)
|
foreach ($segments as $segment)
|
||||||
{
|
{
|
||||||
// If the segment is not a boolean connector, we can assume it is
|
// If the segment is not a boolean connector, we can assume it it is
|
||||||
// a column name, and we'll add it to the query as a new constraint
|
// a column name, and we'll add it to the query as a new constraint
|
||||||
// of the query's where clause and keep iterating the segments.
|
// of the query's where clause and keep iterating the segments.
|
||||||
if ($segment != '_and_' and $segment != '_or_')
|
if ($segment != '_and_' and $segment != '_or_')
|
||||||
|
@ -475,7 +492,6 @@ public function group_by($column)
|
||||||
* @param string $column
|
* @param string $column
|
||||||
* @param string $operator
|
* @param string $operator
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return Query
|
|
||||||
*/
|
*/
|
||||||
public function having($column, $operator, $value)
|
public function having($column, $operator, $value)
|
||||||
{
|
{
|
||||||
|
@ -660,7 +676,7 @@ public function get($columns = array('*'))
|
||||||
public function aggregate($aggregator, $columns)
|
public function aggregate($aggregator, $columns)
|
||||||
{
|
{
|
||||||
// We'll set the aggregate value so the grammar does not try to compile
|
// We'll set the aggregate value so the grammar does not try to compile
|
||||||
// a SELECT clause on the query. If an aggregator is present, its own
|
// a SELECT clause on the query. If an aggregator is present, it's own
|
||||||
// grammar function will be used to build the SQL syntax.
|
// grammar function will be used to build the SQL syntax.
|
||||||
$this->aggregate = compact('aggregator', 'columns');
|
$this->aggregate = compact('aggregator', 'columns');
|
||||||
|
|
||||||
|
@ -687,7 +703,7 @@ public function paginate($per_page = 20, $columns = array('*'))
|
||||||
{
|
{
|
||||||
// Because some database engines may throw errors if we leave orderings
|
// Because some database engines may throw errors if we leave orderings
|
||||||
// on the query when retrieving the total number of records, we'll drop
|
// on the query when retrieving the total number of records, we'll drop
|
||||||
// all of the orderings and put them back on the query.
|
// all of the ordreings and put them back on the query.
|
||||||
list($orderings, $this->orderings) = array($this->orderings, null);
|
list($orderings, $this->orderings) = array($this->orderings, null);
|
||||||
|
|
||||||
$total = $this->count(reset($columns));
|
$total = $this->count(reset($columns));
|
||||||
|
@ -714,12 +730,12 @@ public function insert($values)
|
||||||
{
|
{
|
||||||
// Force every insert to be treated like a batch insert to make creating
|
// Force every insert to be treated like a batch insert to make creating
|
||||||
// the binding array simpler since we can just spin through the inserted
|
// the binding array simpler since we can just spin through the inserted
|
||||||
// rows as if there was more than one every time.
|
// rows as if there/ was more than one every time.
|
||||||
if ( ! is_array(reset($values))) $values = array($values);
|
if ( ! is_array(reset($values))) $values = array($values);
|
||||||
|
|
||||||
$bindings = array();
|
$bindings = array();
|
||||||
|
|
||||||
// We need to merge the insert values into the array of the query
|
// We need to merge the the insert values into the array of the query
|
||||||
// bindings so that they will be bound to the PDO statement when it
|
// bindings so that they will be bound to the PDO statement when it
|
||||||
// is executed by the database connection.
|
// is executed by the database connection.
|
||||||
foreach ($values as $value)
|
foreach ($values as $value)
|
||||||
|
@ -820,7 +836,7 @@ public function update($values)
|
||||||
/**
|
/**
|
||||||
* Execute the query as a DELETE statement.
|
* Execute the query as a DELETE statement.
|
||||||
*
|
*
|
||||||
* Optionally, an ID may be passed to the method to delete a specific row.
|
* Optionally, an ID may be passed to the method do delete a specific row.
|
||||||
*
|
*
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @return int
|
* @return int
|
||||||
|
@ -837,7 +853,7 @@ public function delete($id = null)
|
||||||
|
|
||||||
$sql = $this->grammar->delete($this);
|
$sql = $this->grammar->delete($this);
|
||||||
|
|
||||||
return $this->connection->query($sql, $this->bindings);
|
return $this->connection->query($sql, $this->bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -853,7 +869,7 @@ public function __call($method, $parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// All of the aggregate methods are handled by a single method, so we'll
|
// All of the aggregate methods are handled by a single method, so we'll
|
||||||
// catch them all here and then pass them off to the aggregate method
|
// catch them all here and then pass them off to the agregate method
|
||||||
// instead of creating methods for each one of them.
|
// instead of creating methods for each one of them.
|
||||||
if (in_array($method, array('count', 'min', 'max', 'avg', 'sum')))
|
if (in_array($method, array('count', 'min', 'max', 'avg', 'sum')))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,8 @@ # Laravel Change Log
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
- [Develop](#develop)
|
- [Laravel 3.2.5](#3.2.5)
|
||||||
|
- [Upgrading From 3.2.4](#upgrade-3.2.5)
|
||||||
- [Laravel 3.2.4](#3.2.4)
|
- [Laravel 3.2.4](#3.2.4)
|
||||||
- [Upgrading From 3.2.3](#upgrade-3.2.4)
|
- [Upgrading From 3.2.3](#upgrade-3.2.4)
|
||||||
- [Laravel 3.2.3](#3.2.3)
|
- [Laravel 3.2.3](#3.2.3)
|
||||||
|
@ -34,11 +35,14 @@ ## Contents
|
||||||
- [Laravel 3.1](#3.1)
|
- [Laravel 3.1](#3.1)
|
||||||
- [Upgrading From 3.0](#upgrade-3.1)
|
- [Upgrading From 3.0](#upgrade-3.1)
|
||||||
|
|
||||||
<a name="develop"></a>
|
<a name="3.2.5"></a>
|
||||||
## Develop
|
|
||||||
|
|
||||||
- Added Turkish language files.
|
- Revert nested where code back to 3.2.3 tag.
|
||||||
- Changed jQuery '$' to 'jQuery' in the Profiler.
|
|
||||||
|
<a name="upgrade-3.2.5"></a>
|
||||||
|
## Upgrading From 3.2.4
|
||||||
|
|
||||||
|
- Replace the **laravel** folder.
|
||||||
|
|
||||||
<a name="3.2.4"></a>
|
<a name="3.2.4"></a>
|
||||||
## Laravel 3.2.4
|
## Laravel 3.2.4
|
||||||
|
|
Loading…
Reference in New Issue