diff --git a/config/config.php b/config/config.php index 0b1579e..9821bbd 100644 --- a/config/config.php +++ b/config/config.php @@ -56,6 +56,16 @@ */ 'use_column_types' => true, + /* + * If you want to ignore specific columns in specific tables you can specify them here. + * Use the dot notation to specify the table and the column : table.column + * This option only apply when 'use_db_schema' is set to true. + */ + 'ignore_columns' => [ + // 'users.lastname', + // 'posts.description', + ], + /* * These colors will be used in the table representation for each entity in * your graph. diff --git a/src/GraphBuilder.php b/src/GraphBuilder.php index 0f4730d..3932ca6 100644 --- a/src/GraphBuilder.php +++ b/src/GraphBuilder.php @@ -3,11 +3,11 @@ namespace BeyondCode\ErdGenerator; use Illuminate\Database\Eloquent\Relations\BelongsToMany; -use Illuminate\Support\Facades\Schema; use phpDocumentor\GraphViz\Graph; use Illuminate\Support\Collection; use phpDocumentor\GraphViz\Node; use \Illuminate\Database\Eloquent\Model as EloquentModel; +use Illuminate\Support\Facades\Schema; class GraphBuilder { @@ -55,13 +55,10 @@ public function generateStructuredTextRepresentation(Collection $models) : strin if (count($columns) > 0) { $output .= "#### Attributes:\n\n"; foreach ($columns as $column) { - if (is_object($column)) { - $name = $column->getName(); - $typeName = $column->getType()->getName(); - } else { - $name = $column['name'] ?? ''; - $typeName = $column['type_name'] ?? ''; - } + + $name = isset($column['name']) ? $column['name'] : ''; + $typeName = isset($column['type_name']) ? $column['type_name'] : ''; + $columnType = config('erd-generator.use_column_types') ? ' (' . $typeName . ')' : ''; $output .= "- `" . $name . "`" . $columnType . "\n"; } @@ -104,23 +101,19 @@ protected function getTableColumnsFromModel(EloquentModel $model) { try { - $table = $model->getConnection()->getTablePrefix() . $model->getTable(); - $schema = $model->getConnection()->getDoctrineSchemaManager($table); - $databasePlatform = $schema->getDatabasePlatform(); - $databasePlatform->registerDoctrineTypeMapping('enum', 'string'); - - $database = null; - - if (strpos($table, '.')) { - list($database, $table) = explode('.', $table); + $table = $model->getTable(); + $columns = Schema::getColumns($table); + if (config('erd-generator.ignore_columns')) { + $columns = collect($columns)->filter(function($column) use($table) { + if (isset($column['name'])){ + return !in_array($table.'.'.$column['name'],config('erd-generator.ignore_columns')); + } + return false; + }); } - return $schema->listTableColumns($table, $database); - } catch (\Throwable $e) { - } + return $columns; - try { - return Schema::getColumns($model->getTable()); } catch (\Throwable $e) { } @@ -136,18 +129,15 @@ protected function getModelLabel(EloquentModel $model, string $label) if (config('erd-generator.use_db_schema')) { $columns = $this->getTableColumnsFromModel($model); foreach ($columns as $column) { - if (is_object($column)) { - $name = $column->getName(); - $typeName = $column->getType()->getName(); - } else { // it's an array! - $name = $column['name'] ?? ''; - $typeName = $column['type_name'] ?? ''; - } - $label = $name; - if (config('erd-generator.use_column_types')) { - $label .= ' ('. $typeName .')'; + + if (isset($column['name'])) { + $label = $column['name']; + if (config('erd-generator.use_column_types') && isset($column['type'])) { + $label .= ' ('.$column['type'].')'; + } + $table .= '' . $label . '' . PHP_EOL; } - $table .= '' . $label . '' . PHP_EOL; + } } diff --git a/tests/GenerationTest.php b/tests/GenerationTest.php index f70e5f4..126b1f4 100644 --- a/tests/GenerationTest.php +++ b/tests/GenerationTest.php @@ -47,6 +47,23 @@ public function it_generated_graphviz_for_test_models_with_db_columns() $this->assertMatchesSnapshot(Artisan::output()); } + /** @test */ + public function it_generated_graphviz_for_test_models_with_db_columns_with_some_excluded_on_config() + { + $this->app['config']->set('erd-generator.use_column_types', false); + $this->app['config']->set('erd-generator.directories', [__DIR__ . '/Models']); + $this->app['config']->set('erd-generator.ignore_columns', [ + 'users.email', + 'posts.body' + ]); + + Artisan::call('generate:erd', [ + '--format' => 'text' + ]); + + $this->assertMatchesSnapshot(Artisan::output()); + } + /** @test */ public function it_generated_graphviz_in_jpeg_format() { @@ -63,68 +80,68 @@ public function it_generated_graphviz_in_jpeg_format() public function it_generates_text_output_file_with_text_output_option() { $this->app['config']->set('erd-generator.directories', [__DIR__ . '/Models']); - + $outputFile = __DIR__ . '/output_test.txt'; - + // Make sure the file doesn't exist before the test if (file_exists($outputFile)) { unlink($outputFile); } - + Artisan::call('generate:erd', [ 'filename' => $outputFile, '--text-output' => true ]); - + $this->assertFileExists($outputFile); $this->assertStringContainsString('Wrote text diagram to ' . $outputFile, Artisan::output()); - + // Check if the file contains GraphViz DOT content $fileContent = file_get_contents($outputFile); $this->assertStringContainsString('digraph', $fileContent); - + // Clean up if (file_exists($outputFile)) { unlink($outputFile); } } - + /** @test */ public function it_generates_structured_text_output_for_txt_extension() { $this->app['config']->set('erd-generator.directories', [__DIR__ . '/Models']); - + $outputFile = __DIR__ . '/structured_test.txt'; - + // Make sure the file doesn't exist before the test if (file_exists($outputFile)) { unlink($outputFile); } - + Artisan::call('generate:erd', [ 'filename' => $outputFile ]); - + $this->assertFileExists($outputFile); $this->assertStringContainsString('Wrote structured ER diagram to ' . $outputFile, Artisan::output()); - + // Check if the file contains structured Markdown content $fileContent = file_get_contents($outputFile); $this->assertStringContainsString('# Entity Relationship Diagram', $fileContent); $this->assertStringContainsString('## Entities', $fileContent); $this->assertStringContainsString('## Relationships', $fileContent); - + // Clean up if (file_exists($outputFile)) { unlink($outputFile); } } - + /** @test */ public function it_generates_structured_text_output_with_correct_content() { $this->app['config']->set('erd-generator.directories', [__DIR__ . '/Models']); - + // Get the structured text output directly from the GraphBuilder $models = $this->app->make('BeyondCode\ErdGenerator\ModelFinder') ->getModelsInDirectory(__DIR__ . '/Models') @@ -135,10 +152,10 @@ public function it_generates_structured_text_output_with_correct_content() $this->app->make('BeyondCode\ErdGenerator\RelationFinder')->getModelRelations($model) ); }); - + $structuredOutput = $this->app->make('BeyondCode\ErdGenerator\GraphBuilder') ->generateStructuredTextRepresentation($models); - + // Assert the structured output matches the snapshot $this->assertMatchesSnapshot($structuredOutput); }