From 3e9d046ca5f9107d39e98b841c7788babda6135c Mon Sep 17 00:00:00 2001 From: Arthur Monney Date: Wed, 17 Sep 2025 11:16:01 +0200 Subject: [PATCH] fix: reset posgres sequence command --- .../ResetPostgresSequencesCommand.php | 54 +++++++++++++------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/app-modules/database-migration/src/Commands/ResetPostgresSequencesCommand.php b/app-modules/database-migration/src/Commands/ResetPostgresSequencesCommand.php index aa4de67b..89543d35 100644 --- a/app-modules/database-migration/src/Commands/ResetPostgresSequencesCommand.php +++ b/app-modules/database-migration/src/Commands/ResetPostgresSequencesCommand.php @@ -5,8 +5,8 @@ namespace Laravelcm\DatabaseMigration\Commands; use Illuminate\Console\Command; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Schema; final class ResetPostgresSequencesCommand extends Command { @@ -25,35 +25,38 @@ public function handle(): int $this->info('🔄 Resetting PostgreSQL sequences...'); $this->newLine(); - $tables = collect(Schema::getTableListing()) - ->filter(fn (string $table): bool => Schema::hasColumn($table, 'id')) - ->filter(fn (string $table): bool => $this->hasSequence($table)); + $tablesWithSequences = $this->getTablesWithSequences(); - if ($tables->isEmpty()) { + if ($tablesWithSequences->isEmpty()) { $this->warn('❌ No tables with sequences found'); return Command::SUCCESS; } - $progressBar = $this->output->createProgressBar($tables->count()); + $progressBar = $this->output->createProgressBar($tablesWithSequences->count()); $progressBar->start(); $resetCount = 0; $skipCount = 0; - foreach ($tables as $table) { + foreach ($tablesWithSequences as $sequenceInfo) { try { - $maxId = DB::table($table)->max('id') ?? 0; + $tableName = $sequenceInfo->table_name; + $sequenceName = $sequenceInfo->sequence_name; + $columnName = $sequenceInfo->column_name; + + $maxId = DB::table($tableName)->max($columnName) ?? 0; + $nextVal = $maxId + 1; if ($isDryRun) { - $this->line("Would reset {$table}_id_seq to {$maxId}"); + $this->line("Would reset {$sequenceName} to {$nextVal} (max {$columnName}: {$maxId})"); } else { - DB::statement("SELECT setval('{$table}_id_seq', COALESCE(MAX(id), 1)) FROM {$table};"); + DB::statement('SELECT setval(?, GREATEST(?, 1))', [$sequenceName, $nextVal]); } $resetCount++; } catch (\Exception $e) { - $this->line("⚠️ Skipped {$table}: {$e->getMessage()}"); + $this->line("⚠️ Skipped {$sequenceInfo->table_name}: {$e->getMessage()}"); $skipCount++; } @@ -72,14 +75,31 @@ public function handle(): int return Command::SUCCESS; } - private function hasSequence(string $table): bool + private function getTablesWithSequences(): Collection { try { - $result = DB::select("SELECT 1 FROM pg_class WHERE relname = '{$table}_id_seq' AND relkind = 'S'"); - - return ! empty($result); - } catch (\Exception) { - return false; + $result = DB::select(" + SELECT + t.relname AS table_name, + a.attname AS column_name, + s.relname AS sequence_name + FROM pg_class s + JOIN pg_depend d ON d.objid = s.oid + JOIN pg_class t ON d.refobjid = t.oid + JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum) + JOIN pg_namespace n ON n.oid = s.relnamespace + WHERE s.relkind = 'S' + AND d.deptype = 'a' + AND t.relkind = 'r' + AND n.nspname = 'public' + ORDER BY t.relname, a.attname + "); + + return collect($result); + } catch (\Exception $e) { + $this->warn("Error querying sequences: {$e->getMessage()}"); + + return collect(); } } }