Skip to content

Commit 78ff790

Browse files
Keep post_id foreign in existing migration & move value updating to an earlier one to avoid foreign key check
1 parent 2726554 commit 78ff790

3 files changed

+92
-99
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/*
4+
* This file is part of fof/polls.
5+
*
6+
* Copyright (c) FriendsOfFlarum.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Illuminate\Database\Query\JoinClause;
13+
use Illuminate\Database\Schema\Blueprint;
14+
use Illuminate\Database\Schema\Builder;
15+
16+
// Split 1/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php
17+
return [
18+
'up' => function (Builder $schema) {
19+
$db = $schema->getConnection();
20+
21+
if ($db->table('migrations')->where('migration', '2023_07_08_000001_update_polls_discussion_relation_to_first_post')->exists()) {
22+
return;
23+
}
24+
25+
$db->transaction(function () use ($db) {
26+
$prefix = $db->getTablePrefix();
27+
28+
// Don't run through this step if no rows exist in the polls table
29+
if (!$db->table('polls')->exists()) {
30+
return;
31+
}
32+
33+
// Update polls whose discussions have a clear first post ID associated
34+
$db->table('polls')
35+
->join('discussions', function (JoinClause $join) {
36+
$join->on('polls.post_id', '=', 'discussions.id')
37+
->where('discussions.first_post_id', '!=', null);
38+
})
39+
->update(['polls.post_id' => $db->raw("{$prefix}discussions.first_post_id")]);
40+
41+
// Update polls whose discussions have a null first post ID associated
42+
$firstPosts = $db->table('posts')
43+
->where('number', '=', 1);
44+
45+
$db->table('polls')
46+
->join('discussions', function (JoinClause $join) {
47+
$join->on('polls.post_id', '=', 'discussions.id')
48+
->where('discussions.first_post_id', '=', null);
49+
})
50+
->leftJoinSub($firstPosts, 'first_posts', function (JoinClause $join) {
51+
$join->on('first_posts.discussion_id', '=', 'discussions.id');
52+
})
53+
->update(['polls.post_id' => $db->raw("{$prefix}first_posts.id")]);
54+
55+
// Delete polls that don't have an associated post
56+
$deletingPolls = $db->table('polls')
57+
->where('post_id', 0);
58+
$count = $deletingPolls->count();
59+
60+
if ($count > 0) {
61+
resolve('log')->warning("[fof/polls] deleting {$deletingPolls->count()} polls with no associated post");
62+
resolve('log')->warning("[fof/polls] |> #{$deletingPolls->pluck('id')->join(', #')}");
63+
} else {
64+
resolve('log')->info('[fof/polls] no polls to delete in v2 migration');
65+
}
66+
67+
$deletingPolls->delete();
68+
});
69+
},
70+
'down' => function (Builder $schema) {
71+
$db = $schema->getConnection();
72+
73+
$db->transaction(function () use ($db) {
74+
$prefix = $db->getTablePrefix();
75+
76+
// Don't run through this step if no rows exist in the polls table
77+
if (!$db->table('polls')->exists()) {
78+
return;
79+
}
80+
81+
// Go back to using discussion IDs. The discussion ID will always exist since the posts' foreign key cascades on delete.
82+
$db->table('polls')
83+
->join('posts', 'polls.post_id', '=', 'posts.id')
84+
->update(['polls.post_id' => $db->raw("{$prefix}posts.discussion_id")]);
85+
});
86+
},
87+
];

migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php

+5-60
Original file line numberDiff line numberDiff line change
@@ -13,71 +13,16 @@
1313
use Illuminate\Database\Schema\Blueprint;
1414
use Illuminate\Database\Schema\Builder;
1515

16-
// Split 1/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php
16+
// Split 2/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php
1717
return [
1818
'up' => function (Builder $schema) {
19-
$db = $schema->getConnection();
20-
21-
$db->transaction(function () use ($db) {
22-
$prefix = $db->getTablePrefix();
23-
24-
// Don't run through this step if no rows exist in the polls table
25-
if (!$db->table('polls')->exists()) {
26-
return;
27-
}
28-
29-
// Update polls whose discussions have a clear first post ID associated
30-
$db->table('polls')
31-
->join('discussions', function (JoinClause $join) {
32-
$join->on('polls.post_id', '=', 'discussions.id')
33-
->where('discussions.first_post_id', '!=', null);
34-
})
35-
->update(['polls.post_id' => $db->raw("{$prefix}discussions.first_post_id")]);
36-
37-
// Update polls whose discussions have a null first post ID associated
38-
$firstPosts = $db->table('posts')
39-
->where('number', '=', 1);
40-
41-
$db->table('polls')
42-
->join('discussions', function (JoinClause $join) {
43-
$join->on('polls.post_id', '=', 'discussions.id')
44-
->where('discussions.first_post_id', '=', null);
45-
})
46-
->leftJoinSub($firstPosts, 'first_posts', function (JoinClause $join) {
47-
$join->on('first_posts.discussion_id', '=', 'discussions.id');
48-
})
49-
->update(['polls.post_id' => $db->raw("{$prefix}first_posts.id")]);
50-
51-
// Delete polls that don't have an associated post
52-
$deletingPolls = $db->table('polls')
53-
->where('post_id', 0);
54-
$count = $deletingPolls->count();
55-
56-
if ($count > 0) {
57-
resolve('log')->warning("[fof/polls] deleting {$deletingPolls->count()} polls with no associated post");
58-
resolve('log')->warning("[fof/polls] |> #{$deletingPolls->pluck('id')->join(', #')}");
59-
} else {
60-
resolve('log')->info('[fof/polls] no polls to delete in v2 migration');
61-
}
62-
63-
$deletingPolls->delete();
19+
$schema->table('polls', function (Blueprint $table) {
20+
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
6421
});
6522
},
6623
'down' => function (Builder $schema) {
67-
$db = $schema->getConnection();
68-
69-
$db->transaction(function () use ($db) {
70-
$prefix = $db->getTablePrefix();
71-
72-
// Don't run through this step if no rows exist in the polls table
73-
if (!$db->table('polls')->exists()) {
74-
return;
75-
}
76-
77-
// Go back to using discussion IDs. The discussion ID will always exist since the posts' foreign key cascades on delete.
78-
$db->table('polls')
79-
->join('posts', 'polls.post_id', '=', 'posts.id')
80-
->update(['polls.post_id' => $db->raw("{$prefix}posts.discussion_id")]);
24+
$schema->table('polls', function (Blueprint $table) {
25+
$table->dropForeign(['post_id']);
8126
});
8227
},
8328
];

migrations/2023_07_08_000002_add_polls_post_id_foreign.php

-39
This file was deleted.

0 commit comments

Comments
 (0)