55namespace Laravelcm \DatabaseMigration \Commands ;
66
77use Illuminate \Console \Command ;
8+ use Illuminate \Support \Collection ;
89use Illuminate \Support \Facades \DB ;
9- use Illuminate \Support \Facades \Schema ;
1010
1111final 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