|
@@ -1,5 +1,7 @@
|
|
|
<?php namespace System\DB\Eloquent;
|
|
|
|
|
|
+use System\DB\Eloquent;
|
|
|
+
|
|
|
class Hydrator {
|
|
|
|
|
|
|
|
@@ -11,7 +13,7 @@ class Hydrator {
|
|
|
public static function hydrate($eloquent)
|
|
|
{
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
$results = static::base(get_class($eloquent), $eloquent->query->get());
|
|
|
|
|
@@ -27,7 +29,7 @@ class Hydrator {
|
|
|
throw new \Exception("Attempting to eager load [$include], but the relationship is not defined.");
|
|
|
}
|
|
|
|
|
|
- static::eagerly($eloquent, $include, $results);
|
|
|
+ static::eagerly($eloquent, $results, $include);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -47,16 +49,14 @@ class Hydrator {
|
|
|
|
|
|
foreach ($results as $result)
|
|
|
{
|
|
|
- $model = new $class;
|
|
|
+ $model = new $class((array) $result);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- $model->attributes = (array) $result;
|
|
|
$model->exists = true;
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
$models[$model->id] = $model;
|
|
|
}
|
|
@@ -68,140 +68,157 @@ class Hydrator {
|
|
|
* Eagerly load a relationship.
|
|
|
*
|
|
|
* @param object $eloquent
|
|
|
+ * @param array $parents
|
|
|
* @param string $include
|
|
|
- * @param array $results
|
|
|
* @return void
|
|
|
*/
|
|
|
- private static function eagerly($eloquent, $include, &$results)
|
|
|
+ private static function eagerly($eloquent, &$parents, $include)
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
|
|
|
$eloquent->attributes[$spoof = $include.'_id'] = 0;
|
|
|
|
|
|
- $model = $eloquent->$include();
|
|
|
+ $relationship = $eloquent->$include();
|
|
|
|
|
|
unset($eloquent->attributes[$spoof]);
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
- $model->query->where = 'WHERE 1 = 1';
|
|
|
- $model->query->bindings = array();
|
|
|
+ $relationship->query->where = 'WHERE 1 = 1';
|
|
|
+ $relationship->query->bindings = array();
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- foreach ($results as &$result)
|
|
|
+ foreach ($parents as &$parent)
|
|
|
{
|
|
|
- $result->ignore[$include] = (strpos($eloquent->relating, 'has_many') === 0) ? array() : null;
|
|
|
+ $parent->ignore[$include] = (strpos($eloquent->relating, 'has_many') === 0) ? array() : null;
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- if ($eloquent->relating == 'has_one' or $eloquent->relating == 'has_many')
|
|
|
+ if ($eloquent->relating == 'has_one')
|
|
|
{
|
|
|
- static::eagerly_load_one_or_many($eloquent->relating_key, $eloquent->relating, $include, $model, $results);
|
|
|
+ static::eagerly_load_one($relationship, $parents, $eloquent->relating_key, $include);
|
|
|
+ }
|
|
|
+ elseif ($eloquent->relating == 'has_many')
|
|
|
+ {
|
|
|
+ static::eagerly_load_many($relationship, $parents, $eloquent->relating_key, $include);
|
|
|
}
|
|
|
elseif ($eloquent->relating == 'belongs_to')
|
|
|
{
|
|
|
- static::eagerly_load_belonging($eloquent->relating_key, $include, $model, $results);
|
|
|
+ static::eagerly_load_belonging($relationship, $parents, $eloquent->relating_key, $include);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- static::eagerly_load_many_to_many($eloquent->relating_key, $eloquent->relating_table, strtolower(get_class($eloquent)).'_id', $include, $model, $results);
|
|
|
+ static::eagerly_load_many_to_many($relationship, $parents, $eloquent->relating_key, $eloquent->relating_table, $include);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
- * Eagerly load a 1:1 or 1:* relationship.
|
|
|
+ * Eagerly load a 1:1 relationship.
|
|
|
*
|
|
|
+ * @param object $relationship
|
|
|
+ * @param array $parents
|
|
|
* @param string $relating_key
|
|
|
* @param string $relating
|
|
|
* @param string $include
|
|
|
- * @param object $model
|
|
|
- * @param array $results
|
|
|
* @return void
|
|
|
*/
|
|
|
- private static function eagerly_load_one_or_many($relating_key, $relating, $include, $model, &$results)
|
|
|
+ private static function eagerly_load_one($relationship, &$parents, $relating_key, $include)
|
|
|
{
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- $inclusions = $model->where_in($relating_key, array_keys($results))->get();
|
|
|
+ foreach ($relationship->where_in($relating_key, array_keys($parents))->get() as $key => $child)
|
|
|
+ {
|
|
|
+ $parents[$child->$relating_key]->ignore[$include] = $child;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- foreach ($inclusions as $key => $inclusion)
|
|
|
+
|
|
|
+ * Eagerly load a 1:* relationship.
|
|
|
+ *
|
|
|
+ * @param object $relationship
|
|
|
+ * @param array $parents
|
|
|
+ * @param string $relating_key
|
|
|
+ * @param string $relating
|
|
|
+ * @param string $include
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ private static function eagerly_load_many($relationship, &$parents, $relating_key, $include)
|
|
|
+ {
|
|
|
+ foreach ($relationship->where_in($relating_key, array_keys($parents))->get() as $key => $child)
|
|
|
{
|
|
|
- if ($relating == 'has_one')
|
|
|
- {
|
|
|
- $results[$inclusion->$relating_key]->ignore[$include] = $inclusion;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $results[$inclusion->$relating_key]->ignore[$include][$inclusion->id] = $inclusion;
|
|
|
- }
|
|
|
+ $parents[$child->$relating_key]->ignore[$include][$child->id] = $child;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
* Eagerly load a 1:1 belonging relationship.
|
|
|
*
|
|
|
+ * @param object $relationship
|
|
|
+ * @param array $parents
|
|
|
* @param string $relating_key
|
|
|
* @param string $include
|
|
|
- * @param object $model
|
|
|
- * @param array $results
|
|
|
* @return void
|
|
|
*/
|
|
|
- private static function eagerly_load_belonging($relating_key, $include, $model, &$results)
|
|
|
+ private static function eagerly_load_belonging($relationship, &$parents, $relating_key, $include)
|
|
|
{
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
$keys = array();
|
|
|
|
|
|
- foreach ($results as &$result)
|
|
|
+ foreach ($parents as &$parent)
|
|
|
{
|
|
|
- $keys[] = $result->$relating_key;
|
|
|
+ $keys[] = $parent->$relating_key;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- $inclusions = $model->where_in('id', array_unique($keys))->get();
|
|
|
+ $children = $relationship->where_in('id', array_unique($keys))->get();
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- foreach ($results as &$result)
|
|
|
+ foreach ($parents as &$parent)
|
|
|
{
|
|
|
- $result->ignore[$include] = $inclusions[$result->$relating_key];
|
|
|
+ $parent->ignore[$include] = $children[$parent->$relating_key];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
* Eagerly load a many-to-many relationship.
|
|
|
*
|
|
|
+ * @param object $relationship
|
|
|
+ * @param array $parents
|
|
|
* @param string $relating_key
|
|
|
* @param string $relating_table
|
|
|
- * @param string $foreign_key
|
|
|
* @param string $include
|
|
|
- * @param object $model
|
|
|
- * @param array $results
|
|
|
+ *
|
|
|
* @return void
|
|
|
*/
|
|
|
- private static function eagerly_load_many_to_many($relating_key, $relating_table, $foreign_key, $include, $model, &$results)
|
|
|
+ private static function eagerly_load_many_to_many($relationship, &$parents, $relating_key, $relating_table, $include)
|
|
|
{
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- $model->query->select = null;
|
|
|
+ $relationship->query->select = null;
|
|
|
|
|
|
|
|
|
|
|
@@ -209,38 +226,31 @@ class Hydrator {
|
|
|
|
|
|
|
|
|
|
|
|
- $inclusions = $model->query
|
|
|
- ->where_in($relating_key, array_keys($results))
|
|
|
- ->get(\System\DB\Eloquent::table(get_class($model)).'.*', $relating_table.'.'.$foreign_key);
|
|
|
+ $children = $relationship->query
|
|
|
+ ->where_in($relating_table.'.'.$relating_key, array_keys($parents))
|
|
|
+ ->get(Eloquent::table(get_class($relationship)).'.*', $relating_table.'.'.$relating_key);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- $class = get_class($model);
|
|
|
+ $class = get_class($relationship);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- foreach ($inclusions as $inclusion)
|
|
|
+ foreach ($children as $child)
|
|
|
{
|
|
|
- $related = new $class;
|
|
|
+ $related = new $class((array) $child);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
$related->exists = true;
|
|
|
- $related->attributes = (array) $inclusion;
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- unset($related->attributes[$foreign_key]);
|
|
|
+ unset($related->attributes[$relating_key]);
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- $results[$inclusion->$foreign_key]->ignore[$include][$inclusion->id] = $related;
|
|
|
+ $parents[$child->$relating_key]->ignore[$include][$child->id] = $related;
|
|
|
}
|
|
|
}
|
|
|
|