Factories
2 weeks ago
Migrations
2 weeks ago
Seeds
2 weeks ago
DatabaseInspectionCommand.php
2 weeks ago
DbCommand.php
2 weeks ago
DumpCommand.php
2 weeks ago
MonitorCommand.php
2 weeks ago
PruneCommand.php
2 weeks ago
ShowCommand.php
2 weeks ago
TableCommand.php
2 weeks ago
WipeCommand.php
2 weeks ago
ShowCommand.php
140 lines
| 1 | <?php |
| 2 | |
| 3 | namespace IAWPSCOPED\Illuminate\Database\Console; |
| 4 | |
| 5 | use IAWPSCOPED\Doctrine\DBAL\Schema\AbstractSchemaManager; |
| 6 | use IAWPSCOPED\Doctrine\DBAL\Schema\Table; |
| 7 | use IAWPSCOPED\Doctrine\DBAL\Schema\View; |
| 8 | use IAWPSCOPED\Illuminate\Database\ConnectionInterface; |
| 9 | use IAWPSCOPED\Illuminate\Database\ConnectionResolverInterface; |
| 10 | use IAWPSCOPED\Illuminate\Support\Arr; |
| 11 | use IAWPSCOPED\Symfony\Component\Console\Attribute\AsCommand; |
| 12 | /** @internal */ |
| 13 | #[AsCommand(name: 'db:show')] |
| 14 | class ShowCommand extends DatabaseInspectionCommand |
| 15 | { |
| 16 | /** |
| 17 | * The name and signature of the console command. |
| 18 | * |
| 19 | * @var string |
| 20 | */ |
| 21 | protected $signature = 'db:show {--database= : The database connection} |
| 22 | {--json : Output the database information as JSON} |
| 23 | {--counts : Show the table row count <bg=red;options=bold> Note: This can be slow on large databases </>}; |
| 24 | {--views : Show the database views <bg=red;options=bold> Note: This can be slow on large databases </>}'; |
| 25 | /** |
| 26 | * The console command description. |
| 27 | * |
| 28 | * @var string |
| 29 | */ |
| 30 | protected $description = 'Display information about the given database'; |
| 31 | /** |
| 32 | * Execute the console command. |
| 33 | * |
| 34 | * @param \Illuminate\Database\ConnectionResolverInterface $connections |
| 35 | * @return int |
| 36 | */ |
| 37 | public function handle(ConnectionResolverInterface $connections) |
| 38 | { |
| 39 | if (!$this->ensureDependenciesExist()) { |
| 40 | return 1; |
| 41 | } |
| 42 | $connection = $connections->connection($database = $this->input->getOption('database')); |
| 43 | $schema = $connection->getDoctrineSchemaManager(); |
| 44 | $this->registerTypeMappings($schema->getDatabasePlatform()); |
| 45 | $data = ['platform' => ['config' => $this->getConfigFromDatabase($database), 'name' => $this->getPlatformName($schema->getDatabasePlatform(), $database), 'open_connections' => $this->getConnectionCount($connection)], 'tables' => $this->tables($connection, $schema)]; |
| 46 | if ($this->option('views')) { |
| 47 | $data['views'] = $this->collectViews($connection, $schema); |
| 48 | } |
| 49 | $this->display($data); |
| 50 | return 0; |
| 51 | } |
| 52 | /** |
| 53 | * Get information regarding the tables within the database. |
| 54 | * |
| 55 | * @param \Illuminate\Database\ConnectionInterface $connection |
| 56 | * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema |
| 57 | * @return \Illuminate\Support\Collection |
| 58 | */ |
| 59 | protected function tables(ConnectionInterface $connection, AbstractSchemaManager $schema) |
| 60 | { |
| 61 | return \IAWPSCOPED\collect($schema->listTables())->map(fn(Table $table, $index) => ['table' => $table->getName(), 'size' => $this->getTableSize($connection, $table->getName()), 'rows' => $this->option('counts') ? $connection->table($table->getName())->count() : null, 'engine' => rescue(fn() => $table->getOption('engine'), null, \false), 'comment' => $table->getComment()]); |
| 62 | } |
| 63 | /** |
| 64 | * Get information regarding the views within the database. |
| 65 | * |
| 66 | * @param \Illuminate\Database\ConnectionInterface $connection |
| 67 | * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema |
| 68 | * @return \Illuminate\Support\Collection |
| 69 | */ |
| 70 | protected function collectViews(ConnectionInterface $connection, AbstractSchemaManager $schema) |
| 71 | { |
| 72 | return \IAWPSCOPED\collect($schema->listViews())->reject(fn(View $view) => str($view->getName())->startsWith(['pg_catalog', 'information_schema', 'spt_']))->map(fn(View $view) => ['view' => $view->getName(), 'rows' => $connection->table($view->getName())->count()]); |
| 73 | } |
| 74 | /** |
| 75 | * Render the database information. |
| 76 | * |
| 77 | * @param array $data |
| 78 | * @return void |
| 79 | */ |
| 80 | protected function display(array $data) |
| 81 | { |
| 82 | $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data); |
| 83 | } |
| 84 | /** |
| 85 | * Render the database information as JSON. |
| 86 | * |
| 87 | * @param array $data |
| 88 | * @return void |
| 89 | */ |
| 90 | protected function displayJson(array $data) |
| 91 | { |
| 92 | $this->output->writeln(\json_encode($data)); |
| 93 | } |
| 94 | /** |
| 95 | * Render the database information formatted for the CLI. |
| 96 | * |
| 97 | * @param array $data |
| 98 | * @return void |
| 99 | */ |
| 100 | protected function displayForCli(array $data) |
| 101 | { |
| 102 | $platform = $data['platform']; |
| 103 | $tables = $data['tables']; |
| 104 | $views = $data['views'] ?? null; |
| 105 | $this->newLine(); |
| 106 | $this->components->twoColumnDetail('<fg=green;options=bold>' . $platform['name'] . '</>'); |
| 107 | $this->components->twoColumnDetail('Database', Arr::get($platform['config'], 'database')); |
| 108 | $this->components->twoColumnDetail('Host', Arr::get($platform['config'], 'host')); |
| 109 | $this->components->twoColumnDetail('Port', Arr::get($platform['config'], 'port')); |
| 110 | $this->components->twoColumnDetail('Username', Arr::get($platform['config'], 'username')); |
| 111 | $this->components->twoColumnDetail('URL', Arr::get($platform['config'], 'url')); |
| 112 | $this->components->twoColumnDetail('Open Connections', $platform['open_connections']); |
| 113 | $this->components->twoColumnDetail('Tables', $tables->count()); |
| 114 | if ($tableSizeSum = $tables->sum('size')) { |
| 115 | $this->components->twoColumnDetail('Total Size', \number_format($tableSizeSum / 1024 / 1024, 2) . 'MiB'); |
| 116 | } |
| 117 | $this->newLine(); |
| 118 | if ($tables->isNotEmpty()) { |
| 119 | $this->components->twoColumnDetail('<fg=green;options=bold>Table</>', 'Size (MiB)' . ($this->option('counts') ? ' <fg=gray;options=bold>/</> <fg=yellow;options=bold>Rows</>' : '')); |
| 120 | $tables->each(function ($table) { |
| 121 | if ($tableSize = $table['size']) { |
| 122 | $tableSize = \number_format($tableSize / 1024 / 1024, 2); |
| 123 | } |
| 124 | $this->components->twoColumnDetail($table['table'] . ($this->output->isVerbose() ? ' <fg=gray>' . $table['engine'] . '</>' : null), ($tableSize ? $tableSize : '—') . ($this->option('counts') ? ' <fg=gray;options=bold>/</> <fg=yellow;options=bold>' . \number_format($table['rows']) . '</>' : '')); |
| 125 | if ($this->output->isVerbose()) { |
| 126 | if ($table['comment']) { |
| 127 | $this->components->bulletList([$table['comment']]); |
| 128 | } |
| 129 | } |
| 130 | }); |
| 131 | $this->newLine(); |
| 132 | } |
| 133 | if ($views && $views->isNotEmpty()) { |
| 134 | $this->components->twoColumnDetail('<fg=green;options=bold>View</>', '<fg=green;options=bold>Rows</>'); |
| 135 | $views->each(fn($view) => $this->components->twoColumnDetail($view['view'], \number_format($view['rows']))); |
| 136 | $this->newLine(); |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 |