Files
go-no-go/app/Console/Commands/GenerateSchemaCommand.php

134 lines
4.3 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class GenerateSchemaCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:schema-generate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate a schema.md file documenting all database tables';
/**
* Execute the console command.
*/
public function handle(): int
{
$this->info('Generating database schema documentation...');
// Get all tables
$tables = DB::select('SHOW TABLES');
$tableKey = 'Tables_in_'.DB::getDatabaseName();
$tableNames = [];
foreach ($tables as $table) {
$tableNames[] = $table->$tableKey;
}
// Sort tables alphabetically
sort($tableNames);
// Build markdown content
$markdown = "# Database Schema Documentation\n\n";
$markdown .= '> Generated: '.date('Y-m-d H:i:s')."\n";
$markdown .= '> Database: '.DB::getDatabaseName()."\n";
$markdown .= '> Total Tables: '.count($tableNames)."\n\n";
$markdown .= "## Table of Contents\n\n";
// Add table of contents
foreach ($tableNames as $tableName) {
$markdown .= "- [{$tableName}](#{$tableName})\n";
}
$markdown .= "\n---\n\n";
// Process each table
foreach ($tableNames as $tableName) {
$this->line("Processing table: {$tableName}");
$markdown .= "## {$tableName}\n\n";
// Get columns
$columns = DB::select("SHOW COLUMNS FROM `{$tableName}`");
// Get foreign keys
$foreignKeys = DB::select('
SELECT
CONSTRAINT_NAME,
COLUMN_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
TABLE_NAME = ?
AND TABLE_SCHEMA = DATABASE()
AND REFERENCED_TABLE_NAME IS NOT NULL
', [$tableName]);
// Build FK lookup array
$fkLookup = [];
foreach ($foreignKeys as $fk) {
$fkLookup[$fk->COLUMN_NAME] = [
'table' => $fk->REFERENCED_TABLE_NAME,
'column' => $fk->REFERENCED_COLUMN_NAME,
'constraint' => $fk->CONSTRAINT_NAME,
];
}
// Build columns table
$markdown .= "| Field | Type | Null | Key | Default | Extra | Foreign Key |\n";
$markdown .= "|-------|------|------|-----|---------|-------|-------------|\n";
foreach ($columns as $column) {
$fkInfo = '';
if (isset($fkLookup[$column->Field])) {
$fk = $fkLookup[$column->Field];
$fkInfo = "{$fk['table']}.{$fk['column']}";
}
$markdown .= "| {$column->Field} | {$column->Type} | {$column->Null} | {$column->Key} | ";
$markdown .= ($column->Default === null ? 'NULL' : $column->Default).' | ';
$markdown .= "{$column->Extra} | {$fkInfo} |\n";
}
// Add foreign key details if any
if (! empty($foreignKeys)) {
$markdown .= "\n### Foreign Key Constraints\n\n";
foreach ($foreignKeys as $fk) {
$markdown .= "- **{$fk->CONSTRAINT_NAME}**: `{$fk->COLUMN_NAME}` → `{$fk->REFERENCED_TABLE_NAME}.{$fk->REFERENCED_COLUMN_NAME}`\n";
}
}
$markdown .= "\n---\n\n";
}
// Ensure directory exists
$directory = base_path('database');
if (! File::exists($directory)) {
File::makeDirectory($directory, 0755, true);
}
// Write to file
$filePath = $directory.'/schema.md';
File::put($filePath, $markdown);
$this->info('✅ Schema documentation generated successfully!');
$this->line("📄 File saved to: {$filePath}");
return Command::SUCCESS;
}
}