134 lines
4.3 KiB
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;
|
|
}
|
|
}
|