5
5
namespace Laravelcm \DatabaseMigration \Commands ;
6
6
7
7
use Illuminate \Console \Command ;
8
+ use Illuminate \Support \Collection ;
8
9
use Illuminate \Support \Facades \DB ;
9
- use Illuminate \Support \Facades \Schema ;
10
10
11
11
final class ResetPostgresSequencesCommand extends Command
12
12
{
@@ -25,35 +25,38 @@ public function handle(): int
25
25
$ this ->info ('🔄 Resetting PostgreSQL sequences... ' );
26
26
$ this ->newLine ();
27
27
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 ();
31
29
32
- if ($ tables ->isEmpty ()) {
30
+ if ($ tablesWithSequences ->isEmpty ()) {
33
31
$ this ->warn ('❌ No tables with sequences found ' );
34
32
35
33
return Command::SUCCESS ;
36
34
}
37
35
38
- $ progressBar = $ this ->output ->createProgressBar ($ tables ->count ());
36
+ $ progressBar = $ this ->output ->createProgressBar ($ tablesWithSequences ->count ());
39
37
$ progressBar ->start ();
40
38
41
39
$ resetCount = 0 ;
42
40
$ skipCount = 0 ;
43
41
44
- foreach ($ tables as $ table ) {
42
+ foreach ($ tablesWithSequences as $ sequenceInfo ) {
45
43
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 ;
47
50
48
51
if ($ isDryRun ) {
49
- $ this ->line ("Would reset {$ table } _id_seq to {$ maxId }" );
52
+ $ this ->line ("Would reset {$ sequenceName } to {$ nextVal } (max { $ columnName } : { $ maxId }) " );
50
53
} else {
51
- DB ::statement (" SELECT setval(' { $ table } _id_seq', COALESCE(MAX(id) , 1)) FROM { $ table } ; " );
54
+ DB ::statement (' SELECT setval(?, GREATEST(? , 1)) ' , [ $ sequenceName , $ nextVal ] );
52
55
}
53
56
54
57
$ resetCount ++;
55
58
} catch (\Exception $ e ) {
56
- $ this ->line ("⚠️ Skipped {$ table }: {$ e ->getMessage ()}" );
59
+ $ this ->line ("⚠️ Skipped {$ sequenceInfo -> table_name }: {$ e ->getMessage ()}" );
57
60
$ skipCount ++;
58
61
}
59
62
@@ -72,14 +75,31 @@ public function handle(): int
72
75
return Command::SUCCESS ;
73
76
}
74
77
75
- private function hasSequence ( string $ table ): bool
78
+ private function getTablesWithSequences ( ): Collection
76
79
{
77
80
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 ();
83
103
}
84
104
}
85
105
}
0 commit comments