1414 public function up (): void
1515 {
1616 Schema::disableForeignKeyConstraints ();
17+ DB ::beginTransaction ();
18+
19+ // In the case of pgsql we mark the following foreign keys to be defered after the commit transaction
20+ // rather than after every requests
21+ if (DB ::getDriverName () === 'pgsql ' ) {
22+ $ this ->defer ('base_albums ' , 'base_albums_owner_id_foreign ' );
23+ $ this ->defer ('user_base_album ' , 'user_base_album_user_id_foreign ' );
24+ $ this ->defer ('photos ' , 'photos_owner_id_foreign ' );
25+ }
26+
1727 /** @var App\Models\User|null $admin */
1828 $ admin = DB ::table ('users ' )->find (0 );
1929 if ($ admin !== null && ($ admin ->username === '' || $ admin ->password === '' )) {
@@ -22,6 +32,7 @@ public function up(): void
2232 // MigrateAdminUser migration and the user has never logged in.
2333 DB ::table ('users ' )->where ('id ' , '= ' , 0 )->delete ();
2434 }
35+
2536 /** @var App\Models\User $user */
2637 foreach (DB ::table ('users ' )->orderByDesc ('id ' )->get () as $ user ) {
2738 $ oldID = $ user ->id ;
@@ -34,13 +45,15 @@ public function up(): void
3445 DB ::table ('webauthn_credentials ' )->where ('authenticatable_id ' , '= ' , $ oldID )->update (['authenticatable_id ' => $ newID ]);
3546 DB ::table ('users ' )->delete ($ oldID );
3647 }
37- if (Schema::connection (null )->getConnection ()->getDriverName () === 'pgsql ' && DB ::table ('users ' )->count () > 0 ) {
48+
49+ if (DB ::getDriverName () === 'pgsql ' && DB ::table ('users ' )->count () > 0 ) {
3850 // when using PostgreSQL, the new IDs are not updated after incrementing. Thus, we need to reset the index to the greatest ID + 1
3951 // the sequence is called `users_id_seq1`
4052 /** @var App\Models\User $lastUser */
4153 $ lastUser = DB ::table ('users ' )->orderByDesc ('id ' )->first ();
4254 DB ::statement ('ALTER SEQUENCE users_id_seq1 RESTART WITH ' . strval ($ lastUser ->id + 1 ));
4355 }
56+ DB ::commit ();
4457 Schema::enableForeignKeyConstraints ();
4558 }
4659
@@ -52,6 +65,16 @@ public function up(): void
5265 public function down (): void
5366 {
5467 Schema::disableForeignKeyConstraints ();
68+ DB ::beginTransaction ();
69+
70+ // In the case of pgsql we mark the following foreign keys to be defered after the commit transaction
71+ // rather than after every requests
72+ if (DB ::getDriverName () === 'pgsql ' ) {
73+ $ this ->defer ('base_albums ' , 'base_albums_owner_id_foreign ' );
74+ $ this ->defer ('user_base_album ' , 'user_base_album_user_id_foreign ' );
75+ $ this ->defer ('photos ' , 'photos_owner_id_foreign ' );
76+ }
77+
5578 /** @var App\Models\User $user */
5679 foreach (User::query ()->orderBy ('id ' )->get () as $ user ) {
5780 $ oldID = $ user ->id ;
@@ -66,6 +89,15 @@ public function down(): void
6689 DB ::table ('webauthn_credentials ' )->where ('authenticatable_id ' , '= ' , $ oldID )->update (['authenticatable_id ' => $ newID ]);
6790 DB ::table ('users ' )->delete ($ oldID );
6891 }
92+ DB ::commit ();
6993 Schema::enableForeignKeyConstraints ();
7094 }
95+
96+ /**
97+ * Defer a foreign key evalation to the end of a transaction in pgsql.
98+ */
99+ private function defer (string $ tableName , string $ fkName ): void
100+ {
101+ DB ::select ('ALTER TABLE ' . $ tableName . ' ALTER CONSTRAINT ' . $ fkName . ' DEFERRABLE INITIALLY DEFERRED; ' );
102+ }
71103};
0 commit comments