From 5986370cd48e5130382e7d3255c246eb3f348bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Mon, 1 May 2023 14:29:11 +0200 Subject: [PATCH] make it possible to use the same table in multiple joins --- src/PersistentData/PersistentDataManager.php | 32 ++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/PersistentData/PersistentDataManager.php b/src/PersistentData/PersistentDataManager.php index f87f022..42182dc 100644 --- a/src/PersistentData/PersistentDataManager.php +++ b/src/PersistentData/PersistentDataManager.php @@ -150,7 +150,8 @@ class PersistentDataManager implements IPersistentDataManager $columns = array_merge($columns, $this->getRelationColumns($relations, $withRelations)); - $this->leftJoinRelations($select, $table, $relations, $withRelations); + $alreadyUsedTableAliases = [$table => true]; + $this->leftJoinRelations($select, $table, $relations, $withRelations, $alreadyUsedTableAliases); $select->columns($columns); } else { $select->columns($columns); @@ -179,20 +180,39 @@ class PersistentDataManager implements IPersistentDataManager return $columns; } - private function leftJoinRelations(Select $select, string $table, array $relations, array $withRelations): void + private function leftJoinRelations(Select $select, string $table, array $relations, array $withRelations, array &$alreadyUsedTableAliases): void { foreach ($relations as $relation => $relationType) { - $relationTable = call_user_func([$relationType, 'getTable']); + $relationTable = $this->generateTableAlias($select, call_user_func([$relationType, 'getTable']), $alreadyUsedTableAliases); $select->leftJoin($relationTable, [$relationTable, 'id'], '=', [$table, $relation . '_id']); - $nextOrderRelations = call_user_func([$relationType, 'getRelations']); + $relationsOfRelation = call_user_func([$relationType, 'getRelations']); if (count($withRelations)) { - $nextOrderRelations = array_intersect_key($nextOrderRelations, array_flip($withRelations)); + $relationsOfRelation = array_intersect_key($relationsOfRelation, array_flip($withRelations)); } - $this->leftJoinRelations($select, $relationTable, $nextOrderRelations, $withRelations); + $this->leftJoinRelations($select, $relationTable, $relationsOfRelation, $withRelations, $alreadyUsedTableAliases); } } + private function generateTableAlias(Select $select, string $table, array &$alreadyUsedTableAliases) + { + if (!isset($alreadyUsedTableAliases[$table])) { + $alreadyUsedTableAliases[$table] = true; + return $table; + } + + $i = 2; + do { + $alias = $table[0] . $i; + $i++; + } while (isset($alreadyUsedTableAliases[$alias])); + + $select->setTableAliases([$alias => $table]); + $alreadyUsedTableAliases[$alias] = true; + + return $alias; + } + private function fillWithData(array &$data, Model $model, array $withRelations = [], ?string $modelKey = null): void { $relations = $model::getRelations();