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:
Guy Sartorelli 2023-07-05 12:48:58 +12:00
parent 60ca35c02d
commit 85e503d012
No known key found for this signature in database
GPG Key ID: F313E3B9504D496A

View File

@ -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];
}
/**