Skip to content

Commit 8024d0b

Browse files
committed
fix: add foreign keys everywhere
1 parent 5992891 commit 8024d0b

File tree

2 files changed

+307
-21
lines changed

2 files changed

+307
-21
lines changed
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
use Illuminate\Database\Migrations\Migration;
18+
use Illuminate\Database\Schema\Blueprint;
19+
use Illuminate\Support\Facades\DB;
20+
use Illuminate\Support\Facades\Schema;
21+
22+
return new class () extends Migration {
23+
/**
24+
* Run the migrations.
25+
*/
26+
public function up(): void
27+
{
28+
// Missing still:
29+
//
30+
// For performance:
31+
//
32+
// - announces.{user_id,torrent_id}
33+
//
34+
// Foreign records can be deleted but we want to retain these records with the deleted id for transaction history:
35+
//
36+
// - bon_transactions.bon_exchange_id
37+
// - donations.package_id
38+
//
39+
// The tmdb ids are stored before the movie/tv records are fetched via http:
40+
//
41+
// - requests.{tmdb_movie_id,tmdb_tv_id}
42+
// - torrents.{tmdb_movie_id,tmdb_tv_id}
43+
//
44+
// Chatbox needs a separate refactor:
45+
//
46+
// - messages.{bot_id,chatroom_id}
47+
// - user_audibles.{room_id,bot_id}
48+
// - user_echoes.{room_id,bot_id}
49+
50+
DB::table('application_image_proofs')
51+
->whereNotIn('application_id', DB::table('applications')->select('id'))
52+
->delete();
53+
54+
Schema::table('application_image_proofs', function (Blueprint $table): void {
55+
$table->dropIndex(['application_id']);
56+
$table->foreign('application_id')->references('id')->on('applications')->cascadeOnUpdate()->cascadeOnDelete();
57+
});
58+
59+
DB::table('application_url_proofs')
60+
->whereNotIn('application_id', DB::table('applications')->select('id'))
61+
->delete();
62+
63+
Schema::table('application_url_proofs', function (Blueprint $table): void {
64+
$table->dropIndex(['application_id']);
65+
$table->foreign('application_id')->references('id')->on('applications')->cascadeOnUpdate()->cascadeOnDelete();
66+
});
67+
68+
DB::table('automatic_torrent_freeleeches')
69+
->whereNotIn('category_id', DB::table('categories')->select('id'))
70+
->update([
71+
'category_id' => null,
72+
]);
73+
74+
DB::table('automatic_torrent_freeleeches')
75+
->whereNotIn('resolution_id', DB::table('resolutions')->select('id'))
76+
->update([
77+
'resolution_id' => null,
78+
]);
79+
80+
DB::table('automatic_torrent_freeleeches')
81+
->whereNotIn('type_id', DB::table('types')->select('id'))
82+
->update([
83+
'type_id' => null,
84+
]);
85+
86+
Schema::table('automatic_torrent_freeleeches', function (Blueprint $table): void {
87+
$table->unsignedSmallInteger('category_id')->nullable()->change();
88+
$table->unsignedSmallInteger('resolution_id')->nullable()->change();
89+
$table->unsignedSmallInteger('type_id')->nullable()->change();
90+
91+
$table->foreign('category_id')->references('id')->on('categories')->cascadeOnUpdate()->nullOnDelete();
92+
$table->foreign('type_id')->references('id')->on('types')->cascadeOnUpdate()->nullOnDelete();
93+
$table->foreign('resolution_id')->references('id')->on('resolutions')->cascadeOnUpdate()->nullOnDelete();
94+
});
95+
96+
Schema::table('donations', function (Blueprint $table): void {
97+
$table->dropIndex(['user_id']);
98+
$table->foreign('user_id')->references('id')->on('users')->cascadeOnUpdate();
99+
$table->dropIndex(['gifted_user_id']);
100+
$table->foreign('gifted_user_id')->references('id')->on('users')->cascadeOnUpdate()->nullOnDelete();
101+
});
102+
103+
DB::table('forum_permissions')
104+
->whereNotIn('group_id', DB::table('groups')->select('id'))
105+
->delete();
106+
107+
Schema::table('forum_permissions', function (Blueprint $table): void {
108+
$table->dropIndex('fk_permissions_groups1_idx');
109+
$table->foreign('group_id')->references('id')->on('groups')->cascadeOnUpdate()->cascadeOnDelete();
110+
});
111+
112+
DB::table('likes')
113+
->whereNotIn('post_id', DB::table('posts')->select('id'))
114+
->delete();
115+
116+
Schema::table('likes', function (Blueprint $table): void {
117+
$table->foreign('post_id')->references('id')->on('posts')->cascadeOnUpdate()->cascadeOnDelete();
118+
});
119+
120+
DB::table('playlist_torrents')
121+
->whereNotIn('playlist_id', DB::table('playlists')->select('id'))
122+
->delete();
123+
124+
Schema::table('playlist_torrents', function (Blueprint $table): void {
125+
$table->dropIndex(['playlist_id']);
126+
$table->foreign('playlist_id')->references('id')->on('playlists')->cascadeOnUpdate()->cascadeOnDelete();
127+
});
128+
129+
DB::table('reports')
130+
->whereNotIn('reported_request_id', DB::table('requests')->select('id'))
131+
->delete();
132+
133+
Schema::table('reports', function (Blueprint $table): void {
134+
$table->dropIndex(['reported_request_id']);
135+
$table->foreign('reported_request_id')->references('id')->on('requests')->cascadeOnUpdate()->nullOnDelete();
136+
});
137+
138+
DB::table('request_bounty')
139+
->whereNotIn('request_id', DB::table('requests')->select('id'))
140+
->delete();
141+
142+
Schema::table('request_bounty', function (Blueprint $table): void {
143+
$table->dropIndex('request_id');
144+
$table->foreign('requests_id')->references('id')->on('requests')->cascadeOnUpdate()->cascadeOnDelete();
145+
});
146+
147+
DB::table('request_claims')
148+
->whereNotIn('request_id', DB::table('requests')->select('id'))
149+
->delete();
150+
151+
Schema::table('request_claims', function (Blueprint $table): void {
152+
$table->dropIndex('request_id');
153+
$table->foreign('request_id')->references('id')->on('requests')->cascadeOnUpdate()->cascadeOnDelete();
154+
});
155+
156+
Schema::table('subtitles', function (Blueprint $table): void {
157+
$table->dropIndex(['language_id']);
158+
$table->foreign('language_id')->references('id')->on('media_languages')->cascadeOnUpdate();
159+
});
160+
161+
foreach (DB::table('ticket_attachments')->whereNotIn('ticket_id', DB::table('tickets')->select('id'))->get() as $attachment) {
162+
$path = storage_path('app/files/attachments/files/'.$attachment->file_name);
163+
164+
if (is_file($path)) {
165+
@unlink($path);
166+
}
167+
168+
DB::table('ticket_attachments')->where('id', '=', $attachment->id)->delete();
169+
}
170+
171+
Schema::table('ticket_attachments', function (Blueprint $table): void {
172+
$table->dropIndex(['ticket_id']);
173+
$table->foreign('ticket_id')->references('id')->on('tickets')->cascadeOnUpdate();
174+
});
175+
176+
if (DB::table('tickets')->whereNotIn('category_id', DB::table('ticket_categories')->select('id'))->exists()) {
177+
$newTicketCategoryId = DB::table('ticket_categories')->insertGetId([
178+
'name' => 'Other',
179+
'position' => 999,
180+
'created_at' => now(),
181+
'updated_at' => now(),
182+
]);
183+
184+
DB::table('tickets')
185+
->whereNotIn('category_id', DB::table('ticket_categories')->select('id'))
186+
->update([
187+
'category_id' => $newTicketCategoryId,
188+
]);
189+
}
190+
191+
if (DB::table('tickets')->whereNotIn('priority_id', DB::table('ticket_priorities')->select('id'))->exists()) {
192+
$newTicketPriorityId = DB::table('ticket_priorities')->insertGetId([
193+
'name' => 'Other',
194+
'position' => 999,
195+
'color' => '#000',
196+
'icon' => 'fas fa-circle',
197+
'created_at' => now(),
198+
'updated_at' => now(),
199+
]);
200+
201+
DB::table('tickets')
202+
->whereNotIn('priority_id', DB::table('ticket_priorities')->select('id'))
203+
->update([
204+
'priority_id' => $newTicketPriorityId,
205+
]);
206+
}
207+
208+
Schema::table('tickets', function (Blueprint $table): void {
209+
$table->dropIndex(['category_id']);
210+
$table->foreign('category_id')->references('id')->on('ticket_categories')->cascadeOnUpdate();
211+
$table->dropIndex(['priority_id']);
212+
$table->foreign('priority_id')->references('id')->on('ticket_categories')->cascadeOnUpdate();
213+
});
214+
215+
DB::table('torrents')
216+
->whereNotIn('distributor_id', DB::table('distributors')->select('id'))
217+
->update([
218+
'distributor_id' => null,
219+
]);
220+
221+
DB::table('torrents')
222+
->whereNotIn('region_id', DB::table('regions')->select('id'))
223+
->update([
224+
'region_id' => null,
225+
]);
226+
227+
Schema::table('torrents', function (Blueprint $table): void {
228+
$table->dropIndex(['distributor_id']);
229+
$table->foreign('distributor_id')->references('id')->on('distributors')->cascadeOnUpdate();
230+
$table->dropIndex(['region_id']);
231+
$table->foreign('region_id')->references('id')->on('regions')->cascadeOnUpdate();
232+
});
233+
234+
DB::table('users')
235+
->whereNotIn('group_id', DB::table('groups')->select('id'))
236+
->update([
237+
'group_id' => DB::table('groups')->where('slug', '=', 'banned')->value('id'),
238+
]);
239+
240+
DB::table('users')
241+
->whereNotIn('chatroom_id', DB::table('chatrooms')->select('id'))
242+
->update([
243+
'chatroom_id' => DB::table('chatrooms')->value('id'),
244+
]);
245+
246+
DB::table('users')
247+
->whereNotIn('chat_status_id', DB::table('chat_statuses')->select('id'))
248+
->update([
249+
'chat_status_id' => DB::table('chat_statuses')->value('id'),
250+
]);
251+
252+
Schema::table('users', function (Blueprint $table): void {
253+
$table->dropIndex('fk_users_groups_idx');
254+
$table->foreign('group_id')->references('id')->on('groups')->cascadeOnUpdate();
255+
$table->foreign('chatroom_id')->references('id')->on('chatrooms')->cascadeOnUpdate();
256+
$table->foreign('chat_status_id')->references('id')->on('chat_statuses')->cascadeOnUpdate();
257+
});
258+
}
259+
};

0 commit comments

Comments
 (0)