mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENH Refactor eagerloading fetch into separate methods
It is hard to work with the current structure - having each relation type in its own method makes it way easier to see where my concerns start and end with a given relation. This also reduces the chance of variable bleed-over, where the value in a variable in the first loop (in the same or other relation type) could bleed into the next iteration of the loop.
This commit is contained in:
parent
60ca35c02d
commit
85e503d012
@ -1099,6 +1099,60 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
}
|
||||
// has_one
|
||||
if ($hasOneIDField) {
|
||||
list($prevRelationArray, $ids) = $this->fetchEagerLoadHasOne(
|
||||
$query,
|
||||
$prevRelationArray,
|
||||
$hasOneIDField,
|
||||
$relationDataClass,
|
||||
$eagerLoadRelation,
|
||||
$relation,
|
||||
$dataClass,
|
||||
$dataClasses
|
||||
);
|
||||
// belongs_to
|
||||
} elseif ($belongsToIDField) {
|
||||
list($prevRelationArray, $ids) = $this->fetchEagerLoadBelongsTo(
|
||||
$ids,
|
||||
$belongsToIDField,
|
||||
$relationDataClass,
|
||||
$eagerLoadRelation,
|
||||
$relation
|
||||
);
|
||||
// has_many
|
||||
} elseif ($hasManyIDField) {
|
||||
list($prevRelationArray, $ids) = $this->fetchEagerLoadHasMany(
|
||||
$ids,
|
||||
$hasManyIDField,
|
||||
$relationDataClass,
|
||||
$eagerLoadRelation,
|
||||
$relation
|
||||
);
|
||||
// many_many + belongs_many_many & many_many_through
|
||||
} elseif ($manyManyLastComponent) {
|
||||
list($prevRelationArray, $ids) = $this->fetchEagerLoadManyMany(
|
||||
$manyManyLastComponent,
|
||||
$ids,
|
||||
$relationDataClass,
|
||||
$eagerLoadRelation,
|
||||
$relation
|
||||
);
|
||||
} else {
|
||||
throw new LogicException('Something went wrong with the eager loading');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fetchEagerLoadHasOne(
|
||||
Query $query,
|
||||
array $prevRelationArray,
|
||||
string $hasOneIDField,
|
||||
string $relationDataClass,
|
||||
string $eagerLoadRelation,
|
||||
string $relation,
|
||||
string $dataClass,
|
||||
array $dataClasses
|
||||
): array
|
||||
{
|
||||
$itemArray = [];
|
||||
$relationItemIDs = [];
|
||||
if ($dataClass === $dataClasses[0]) {
|
||||
@ -1127,10 +1181,17 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
}
|
||||
}
|
||||
}
|
||||
$prevRelationArray = $relationArray;
|
||||
$ids = $relationItemIDs;
|
||||
// belongs_to
|
||||
} elseif ($belongsToIDField) {
|
||||
return [$relationArray, $relationItemIDs];
|
||||
}
|
||||
|
||||
private function fetchEagerLoadBelongsTo(
|
||||
array $ids,
|
||||
string $belongsToIDField,
|
||||
string $relationDataClass,
|
||||
string $eagerLoadRelation,
|
||||
string $relation
|
||||
): array
|
||||
{
|
||||
$relationArray = DataObject::get($relationDataClass)->filter([$belongsToIDField => $ids])->toArray();
|
||||
$relationItemIDs = [];
|
||||
foreach ($relationArray as $relationItem) {
|
||||
@ -1138,10 +1199,17 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
$eagerLoadID = $relationItem->$belongsToIDField;
|
||||
$this->eagerLoadedData[$eagerLoadRelation][$eagerLoadID][$relation] = $relationItem;
|
||||
}
|
||||
$prevRelationArray = $relationArray;
|
||||
$ids = $relationItemIDs;
|
||||
// has_many
|
||||
} elseif ($hasManyIDField) {
|
||||
return [$relationArray, $relationItemIDs];
|
||||
}
|
||||
|
||||
private function fetchEagerLoadHasMany(
|
||||
array $ids,
|
||||
string $hasManyIDField,
|
||||
string $relationDataClass,
|
||||
string $eagerLoadRelation,
|
||||
string $relation
|
||||
): array
|
||||
{
|
||||
$relationArray = DataObject::get($relationDataClass)->filter([$hasManyIDField => $ids])->toArray();
|
||||
$relationItemIDs = [];
|
||||
foreach ($relationArray as $relationItem) {
|
||||
@ -1154,10 +1222,17 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
}
|
||||
$this->eagerLoadedData[$eagerLoadRelation][$eagerLoadID][$relation]->push($relationItem);
|
||||
}
|
||||
$prevRelationArray = $relationArray;
|
||||
$ids = $relationItemIDs;
|
||||
// many_many + belongs_many_many & many_many_through
|
||||
} elseif ($manyManyLastComponent) {
|
||||
return [$relationArray, $relationItemIDs];
|
||||
}
|
||||
|
||||
private function fetchEagerLoadManyMany(
|
||||
array $manyManyLastComponent,
|
||||
array $ids,
|
||||
string $relationDataClass,
|
||||
string $eagerLoadRelation,
|
||||
string $relation
|
||||
): array
|
||||
{
|
||||
$parentField = $manyManyLastComponent['parentField'];
|
||||
$childField = $manyManyLastComponent['childField'];
|
||||
// $join will either be:
|
||||
@ -1202,12 +1277,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
}))[0];
|
||||
$this->eagerLoadedData[$eagerLoadRelation][$eagerLoadID][$relation]->push($relationItem);
|
||||
}
|
||||
$prevRelationArray = $relationArray;
|
||||
$ids = $relationItemIDs;
|
||||
} else {
|
||||
throw new LogicException('Something went wrong with the eager loading');
|
||||
}
|
||||
}
|
||||
return [$relationArray, $relationItemIDs];
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user