From 079f80a5afda7e709482a87ed2f264a33bcb4a1b Mon Sep 17 00:00:00 2001 From: Abdellah EL KADIRI Date: Thu, 17 Apr 2025 15:55:53 +0200 Subject: [PATCH 1/4] fix: prevent schema relation infinite loop during CRUD generation --- src/ModelGenerator.php | 58 ++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php index 33a9a49..70305bf 100644 --- a/src/ModelGenerator.php +++ b/src/ModelGenerator.php @@ -127,36 +127,50 @@ protected function getBelongsTo(): array protected function getOtherRelations(): array { - $tables = Schema::getTableListing(); - $eloquent = []; + try { + $tables = Schema::getTableListing(); + $eloquent = []; - foreach ($tables as $table) { - $relations = Schema::getForeignKeys($table); - $indexes = collect(Schema::getIndexes($table)); + $startTime = microtime(true); + $timeout = 10; - foreach ($relations as $relation) { - if ($relation['foreign_table'] != $this->table) { - continue; + foreach ($tables as $table) { + // Check for timeout + if (microtime(true) - $startTime > $timeout) { + break; } - if (count($relation['foreign_columns']) != 1 || count($relation['columns']) != 1) { + try { + $relations = Schema::getForeignKeys($table); + $indexes = collect(Schema::getIndexes($table)); + + foreach ($relations as $relation) { + if ($relation['foreign_table'] != $this->table) { + continue; + } + if (count($relation['foreign_columns']) != 1 || count($relation['columns']) != 1) { + continue; + } + $isUniqueColumn = $this->getUniqueIndex($indexes, $relation['columns'][0]); + $foreignTable = $this->extractTableName($table); + $eloquent[] = [ + 'name' => $isUniqueColumn ? 'hasOne' : 'hasMany', + 'relation_name' => Str::camel($isUniqueColumn ? Str::singular($foreignTable) : Str::plural($foreignTable)), + 'class' => Str::studly(Str::singular($foreignTable)), + 'foreign_key' => $relation['foreign_columns'][0], + 'owner_key' => $relation['columns'][0], + ]; + } + } catch (\Exception $e) { + \Log::error("Error processing table $table: " . $e->getMessage()); continue; } - - $isUniqueColumn = $this->getUniqueIndex($indexes, $relation['columns'][0]); - $foreignTable = $this->extractTableName($table); - - $eloquent[] = [ - 'name' => $isUniqueColumn ? 'hasOne' : 'hasMany', - 'relation_name' => Str::camel($isUniqueColumn ? Str::singular($foreignTable) : Str::plural($foreignTable)), - 'class' => Str::studly(Str::singular($foreignTable)), - 'foreign_key' => $relation['foreign_columns'][0], - 'owner_key' => $relation['columns'][0], - ]; } + return $eloquent; + } catch (\Exception $e) { + \Log::error("Error in getOtherRelations: " . $e->getMessage()); + return []; } - - return $eloquent; } private function getUniqueIndex($indexes, $column): bool From f128dddd7c84bd5dc3af63c5904c2f4c54ccbcc5 Mon Sep 17 00:00:00 2001 From: Abdellah EL KADIRI Date: Thu, 17 Apr 2025 16:00:19 +0200 Subject: [PATCH 2/4] cleanup --- src/ModelGenerator.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php index 70305bf..45140fe 100644 --- a/src/ModelGenerator.php +++ b/src/ModelGenerator.php @@ -19,9 +19,9 @@ class ModelGenerator /** * ModelGenerator constructor. * - * @param string $table - * @param string $properties - * @param string $modelNamespace + * @param string $table + * @param string $properties + * @param string $modelNamespace */ public function __construct(string $table, string $properties, string $modelNamespace) { @@ -86,7 +86,7 @@ private function _getTableRelations(): array /** * Extract the table name from a fully qualified table name (e.g., database.table). - * @param string $foreignTable + * @param string $foreignTable * @return string */ protected function extractTableName(string $foreignTable): string @@ -114,11 +114,11 @@ protected function getBelongsTo(): array $foreignTable = $this->extractTableName($relation['foreign_table']); $eloquent[] = [ - 'name' => 'belongsTo', + 'name' => 'belongsTo', 'relation_name' => Str::camel(Str::singular($foreignTable)), - 'class' => Str::studly(Str::singular($foreignTable)), - 'foreign_key' => $relation['columns'][0], - 'owner_key' => $relation['foreign_columns'][0], + 'class' => Str::studly(Str::singular($foreignTable)), + 'foreign_key' => $relation['columns'][0], + 'owner_key' => $relation['foreign_columns'][0], ]; } @@ -132,7 +132,7 @@ protected function getOtherRelations(): array $eloquent = []; $startTime = microtime(true); - $timeout = 10; + $timeout = 10; foreach ($tables as $table) { // Check for timeout @@ -154,21 +154,21 @@ protected function getOtherRelations(): array $isUniqueColumn = $this->getUniqueIndex($indexes, $relation['columns'][0]); $foreignTable = $this->extractTableName($table); $eloquent[] = [ - 'name' => $isUniqueColumn ? 'hasOne' : 'hasMany', + 'name' => $isUniqueColumn ? 'hasOne' : 'hasMany', 'relation_name' => Str::camel($isUniqueColumn ? Str::singular($foreignTable) : Str::plural($foreignTable)), - 'class' => Str::studly(Str::singular($foreignTable)), - 'foreign_key' => $relation['foreign_columns'][0], - 'owner_key' => $relation['columns'][0], + 'class' => Str::studly(Str::singular($foreignTable)), + 'foreign_key' => $relation['foreign_columns'][0], + 'owner_key' => $relation['columns'][0], ]; } } catch (\Exception $e) { - \Log::error("Error processing table $table: " . $e->getMessage()); + \Log::error("Error processing table $table: ".$e->getMessage()); continue; } } return $eloquent; } catch (\Exception $e) { - \Log::error("Error in getOtherRelations: " . $e->getMessage()); + \Log::error("Error in getOtherRelations: ".$e->getMessage()); return []; } } From d2e5c8d44eadb4c75f655d5b87df0e679b23df9d Mon Sep 17 00:00:00 2001 From: Abdellah EL KADIRI Date: Thu, 17 Apr 2025 16:01:58 +0200 Subject: [PATCH 3/4] cleanup 2 --- src/ModelGenerator.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php index 45140fe..74c48ff 100644 --- a/src/ModelGenerator.php +++ b/src/ModelGenerator.php @@ -86,7 +86,9 @@ private function _getTableRelations(): array /** * Extract the table name from a fully qualified table name (e.g., database.table). + * * @param string $foreignTable + * * @return string */ protected function extractTableName(string $foreignTable): string @@ -166,9 +168,10 @@ protected function getOtherRelations(): array continue; } } + return $eloquent; } catch (\Exception $e) { - \Log::error("Error in getOtherRelations: ".$e->getMessage()); + \Log::error('Error in getOtherRelations: '.$e->getMessage()); return []; } } From 5f84839ed1fcef56bd769be65c932b57cb7b4af5 Mon Sep 17 00:00:00 2001 From: Abdellah EL KADIRI Date: Thu, 17 Apr 2025 16:03:11 +0200 Subject: [PATCH 4/4] remove spaces --- src/ModelGenerator.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php index 74c48ff..a5fa164 100644 --- a/src/ModelGenerator.php +++ b/src/ModelGenerator.php @@ -86,9 +86,9 @@ private function _getTableRelations(): array /** * Extract the table name from a fully qualified table name (e.g., database.table). - * + * * @param string $foreignTable - * + * * @return string */ protected function extractTableName(string $foreignTable): string @@ -172,6 +172,7 @@ protected function getOtherRelations(): array return $eloquent; } catch (\Exception $e) { \Log::error('Error in getOtherRelations: '.$e->getMessage()); + return []; } }