Skip to content

Commit 1711b6a

Browse files
authored
fix: reset posgres sequence command (#413)
1 parent b459fe1 commit 1711b6a

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

app-modules/database-migration/src/Commands/ResetPostgresSequencesCommand.php

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
namespace Laravelcm\DatabaseMigration\Commands;
66

77
use Illuminate\Console\Command;
8+
use Illuminate\Support\Collection;
89
use Illuminate\Support\Facades\DB;
9-
use Illuminate\Support\Facades\Schema;
1010

1111
final class ResetPostgresSequencesCommand extends Command
1212
{
@@ -25,35 +25,38 @@ public function handle(): int
2525
$this->info('🔄 Resetting PostgreSQL sequences...');
2626
$this->newLine();
2727

28-
$tables = collect(Schema::getTableListing())
29-
->filter(fn (string $table): bool => Schema::hasColumn($table, 'id'))
30-
->filter(fn (string $table): bool => $this->hasSequence($table));
28+
$tablesWithSequences = $this->getTablesWithSequences();
3129

32-
if ($tables->isEmpty()) {
30+
if ($tablesWithSequences->isEmpty()) {
3331
$this->warn('❌ No tables with sequences found');
3432

3533
return Command::SUCCESS;
3634
}
3735

38-
$progressBar = $this->output->createProgressBar($tables->count());
36+
$progressBar = $this->output->createProgressBar($tablesWithSequences->count());
3937
$progressBar->start();
4038

4139
$resetCount = 0;
4240
$skipCount = 0;
4341

44-
foreach ($tables as $table) {
42+
foreach ($tablesWithSequences as $sequenceInfo) {
4543
try {
46-
$maxId = DB::table($table)->max('id') ?? 0;
44+
$tableName = $sequenceInfo->table_name;
45+
$sequenceName = $sequenceInfo->sequence_name;
46+
$columnName = $sequenceInfo->column_name;
47+
48+
$maxId = DB::table($tableName)->max($columnName) ?? 0;
49+
$nextVal = $maxId + 1;
4750

4851
if ($isDryRun) {
49-
$this->line("Would reset {$table}_id_seq to {$maxId}");
52+
$this->line("Would reset {$sequenceName} to {$nextVal} (max {$columnName}: {$maxId})");
5053
} else {
51-
DB::statement("SELECT setval('{$table}_id_seq', COALESCE(MAX(id), 1)) FROM {$table};");
54+
DB::statement('SELECT setval(?, GREATEST(?, 1))', [$sequenceName, $nextVal]);
5255
}
5356

5457
$resetCount++;
5558
} catch (\Exception $e) {
56-
$this->line("⚠️ Skipped {$table}: {$e->getMessage()}");
59+
$this->line("⚠️ Skipped {$sequenceInfo->table_name}: {$e->getMessage()}");
5760
$skipCount++;
5861
}
5962

@@ -72,14 +75,31 @@ public function handle(): int
7275
return Command::SUCCESS;
7376
}
7477

75-
private function hasSequence(string $table): bool
78+
private function getTablesWithSequences(): Collection
7679
{
7780
try {
78-
$result = DB::select("SELECT 1 FROM pg_class WHERE relname = '{$table}_id_seq' AND relkind = 'S'");
79-
80-
return ! empty($result);
81-
} catch (\Exception) {
82-
return false;
81+
$result = DB::select("
82+
SELECT
83+
t.relname AS table_name,
84+
a.attname AS column_name,
85+
s.relname AS sequence_name
86+
FROM pg_class s
87+
JOIN pg_depend d ON d.objid = s.oid
88+
JOIN pg_class t ON d.refobjid = t.oid
89+
JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
90+
JOIN pg_namespace n ON n.oid = s.relnamespace
91+
WHERE s.relkind = 'S'
92+
AND d.deptype = 'a'
93+
AND t.relkind = 'r'
94+
AND n.nspname = 'public'
95+
ORDER BY t.relname, a.attname
96+
");
97+
98+
return collect($result);
99+
} catch (\Exception $e) {
100+
$this->warn("Error querying sequences: {$e->getMessage()}");
101+
102+
return collect();
83103
}
84104
}
85105
}

0 commit comments

Comments
 (0)