From 27265541d6d37557284d9c38cffd105ddaccd90d Mon Sep 17 00:00:00 2001 From: David Sevilla Martin Date: Wed, 26 Jul 2023 12:22:31 -0400 Subject: [PATCH 1/4] Split the two discussion_id -> post_id migrations into 4 total --- ...0000_rename_polls_discussion_id_column.php | 3 +- ...00_rename_polls_discussion_id_column_1.php | 32 +++++++++++++++ ...olls_discussion_relation_to_first_post.php | 9 +---- ...07_08_000002_add_polls_post_id_foreign.php | 39 +++++++++++++++++++ 4 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 migrations/2023_07_08_000000_rename_polls_discussion_id_column_1.php create mode 100644 migrations/2023_07_08_000002_add_polls_post_id_foreign.php diff --git a/migrations/2023_07_08_000000_rename_polls_discussion_id_column.php b/migrations/2023_07_08_000000_rename_polls_discussion_id_column.php index e48c3b91..6f59dffa 100644 --- a/migrations/2023_07_08_000000_rename_polls_discussion_id_column.php +++ b/migrations/2023_07_08_000000_rename_polls_discussion_id_column.php @@ -12,16 +12,15 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; +// Split 1/2 of 2023_07_08_000000_rename_polls_discussion_id_column.php return [ 'up' => function (Builder $schema) { $schema->table('polls', function (Blueprint $table) { $table->dropForeign(['discussion_id']); - $table->renameColumn('discussion_id', 'post_id'); }); }, 'down' => function (Builder $schema) { $schema->table('polls', function (Blueprint $table) { - $table->renameColumn('post_id', 'discussion_id'); $table->foreign('discussion_id')->references('id')->on('discussions')->onDelete('cascade'); }); }, diff --git a/migrations/2023_07_08_000000_rename_polls_discussion_id_column_1.php b/migrations/2023_07_08_000000_rename_polls_discussion_id_column_1.php new file mode 100644 index 00000000..5dd87eb4 --- /dev/null +++ b/migrations/2023_07_08_000000_rename_polls_discussion_id_column_1.php @@ -0,0 +1,32 @@ + function (Builder $schema) { + // Do not run this migration if the column was already renamed before the split + if ($schema->hasColumn('polls', 'post_id')) { + return; + } + + $schema->table('polls', function (Blueprint $table) { + $table->renameColumn('discussion_id', 'post_id'); + }); + }, + 'down' => function (Builder $schema) { + $schema->table('polls', function (Blueprint $table) { + $table->renameColumn('post_id', 'discussion_id'); + }); + }, +]; diff --git a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php index 36d6b4f4..7b9cd77c 100644 --- a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php +++ b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php @@ -13,6 +13,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; +// Split 1/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php return [ 'up' => function (Builder $schema) { $db = $schema->getConnection(); @@ -61,10 +62,6 @@ $deletingPolls->delete(); }); - - $schema->table('polls', function (Blueprint $table) { - $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); - }); }, 'down' => function (Builder $schema) { $db = $schema->getConnection(); @@ -82,9 +79,5 @@ ->join('posts', 'polls.post_id', '=', 'posts.id') ->update(['polls.post_id' => $db->raw("{$prefix}posts.discussion_id")]); }); - - $schema->table('polls', function (Blueprint $table) { - $table->dropForeign(['post_id']); - }); }, ]; diff --git a/migrations/2023_07_08_000002_add_polls_post_id_foreign.php b/migrations/2023_07_08_000002_add_polls_post_id_foreign.php new file mode 100644 index 00000000..104374aa --- /dev/null +++ b/migrations/2023_07_08_000002_add_polls_post_id_foreign.php @@ -0,0 +1,39 @@ + function (Builder $schema) { + // Do not run this migration if the foreign key was already added before the split + $db = $schema->getConnection(); + $foreignKeys = $db->getDoctrineSchemaManager()->listTableForeignKeys("{$db->getTablePrefix()}polls"); + + foreach ($foreignKeys as $foreignKey) { + if (in_array('post_id', $foreignKey->getLocalColumns())) { + return; + } + } + + $schema->table('polls', function (Blueprint $table) { + $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); + }); + }, + 'down' => function (Builder $schema) { + $schema->table('polls', function (Blueprint $table) { + $table->dropForeign(['post_id']); + }); + }, +]; From 78ff79012150bec9f9c0f876c2d06ecaa6566a49 Mon Sep 17 00:00:00 2001 From: David Sevilla Martin Date: Wed, 26 Jul 2023 12:34:46 -0400 Subject: [PATCH 2/4] Keep post_id foreign in existing migration & move value updating to an earlier one to avoid foreign key check --- ..._polls_discussion_id_to_post_id_values.php | 87 +++++++++++++++++++ ...olls_discussion_relation_to_first_post.php | 65 ++------------ ...07_08_000002_add_polls_post_id_foreign.php | 39 --------- 3 files changed, 92 insertions(+), 99 deletions(-) create mode 100644 migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php delete mode 100644 migrations/2023_07_08_000002_add_polls_post_id_foreign.php diff --git a/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php new file mode 100644 index 00000000..2b3f84d2 --- /dev/null +++ b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php @@ -0,0 +1,87 @@ + function (Builder $schema) { + $db = $schema->getConnection(); + + if ($db->table('migrations')->where('migration', '2023_07_08_000001_update_polls_discussion_relation_to_first_post')->exists()) { + return; + } + + $db->transaction(function () use ($db) { + $prefix = $db->getTablePrefix(); + + // Don't run through this step if no rows exist in the polls table + if (!$db->table('polls')->exists()) { + return; + } + + // Update polls whose discussions have a clear first post ID associated + $db->table('polls') + ->join('discussions', function (JoinClause $join) { + $join->on('polls.post_id', '=', 'discussions.id') + ->where('discussions.first_post_id', '!=', null); + }) + ->update(['polls.post_id' => $db->raw("{$prefix}discussions.first_post_id")]); + + // Update polls whose discussions have a null first post ID associated + $firstPosts = $db->table('posts') + ->where('number', '=', 1); + + $db->table('polls') + ->join('discussions', function (JoinClause $join) { + $join->on('polls.post_id', '=', 'discussions.id') + ->where('discussions.first_post_id', '=', null); + }) + ->leftJoinSub($firstPosts, 'first_posts', function (JoinClause $join) { + $join->on('first_posts.discussion_id', '=', 'discussions.id'); + }) + ->update(['polls.post_id' => $db->raw("{$prefix}first_posts.id")]); + + // Delete polls that don't have an associated post + $deletingPolls = $db->table('polls') + ->where('post_id', 0); + $count = $deletingPolls->count(); + + if ($count > 0) { + resolve('log')->warning("[fof/polls] deleting {$deletingPolls->count()} polls with no associated post"); + resolve('log')->warning("[fof/polls] |> #{$deletingPolls->pluck('id')->join(', #')}"); + } else { + resolve('log')->info('[fof/polls] no polls to delete in v2 migration'); + } + + $deletingPolls->delete(); + }); + }, + 'down' => function (Builder $schema) { + $db = $schema->getConnection(); + + $db->transaction(function () use ($db) { + $prefix = $db->getTablePrefix(); + + // Don't run through this step if no rows exist in the polls table + if (!$db->table('polls')->exists()) { + return; + } + + // Go back to using discussion IDs. The discussion ID will always exist since the posts' foreign key cascades on delete. + $db->table('polls') + ->join('posts', 'polls.post_id', '=', 'posts.id') + ->update(['polls.post_id' => $db->raw("{$prefix}posts.discussion_id")]); + }); + }, +]; diff --git a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php index 7b9cd77c..49c6f370 100644 --- a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php +++ b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php @@ -13,71 +13,16 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; -// Split 1/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php +// Split 2/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php return [ 'up' => function (Builder $schema) { - $db = $schema->getConnection(); - - $db->transaction(function () use ($db) { - $prefix = $db->getTablePrefix(); - - // Don't run through this step if no rows exist in the polls table - if (!$db->table('polls')->exists()) { - return; - } - - // Update polls whose discussions have a clear first post ID associated - $db->table('polls') - ->join('discussions', function (JoinClause $join) { - $join->on('polls.post_id', '=', 'discussions.id') - ->where('discussions.first_post_id', '!=', null); - }) - ->update(['polls.post_id' => $db->raw("{$prefix}discussions.first_post_id")]); - - // Update polls whose discussions have a null first post ID associated - $firstPosts = $db->table('posts') - ->where('number', '=', 1); - - $db->table('polls') - ->join('discussions', function (JoinClause $join) { - $join->on('polls.post_id', '=', 'discussions.id') - ->where('discussions.first_post_id', '=', null); - }) - ->leftJoinSub($firstPosts, 'first_posts', function (JoinClause $join) { - $join->on('first_posts.discussion_id', '=', 'discussions.id'); - }) - ->update(['polls.post_id' => $db->raw("{$prefix}first_posts.id")]); - - // Delete polls that don't have an associated post - $deletingPolls = $db->table('polls') - ->where('post_id', 0); - $count = $deletingPolls->count(); - - if ($count > 0) { - resolve('log')->warning("[fof/polls] deleting {$deletingPolls->count()} polls with no associated post"); - resolve('log')->warning("[fof/polls] |> #{$deletingPolls->pluck('id')->join(', #')}"); - } else { - resolve('log')->info('[fof/polls] no polls to delete in v2 migration'); - } - - $deletingPolls->delete(); + $schema->table('polls', function (Blueprint $table) { + $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); }); }, 'down' => function (Builder $schema) { - $db = $schema->getConnection(); - - $db->transaction(function () use ($db) { - $prefix = $db->getTablePrefix(); - - // Don't run through this step if no rows exist in the polls table - if (!$db->table('polls')->exists()) { - return; - } - - // Go back to using discussion IDs. The discussion ID will always exist since the posts' foreign key cascades on delete. - $db->table('polls') - ->join('posts', 'polls.post_id', '=', 'posts.id') - ->update(['polls.post_id' => $db->raw("{$prefix}posts.discussion_id")]); + $schema->table('polls', function (Blueprint $table) { + $table->dropForeign(['post_id']); }); }, ]; diff --git a/migrations/2023_07_08_000002_add_polls_post_id_foreign.php b/migrations/2023_07_08_000002_add_polls_post_id_foreign.php deleted file mode 100644 index 104374aa..00000000 --- a/migrations/2023_07_08_000002_add_polls_post_id_foreign.php +++ /dev/null @@ -1,39 +0,0 @@ - function (Builder $schema) { - // Do not run this migration if the foreign key was already added before the split - $db = $schema->getConnection(); - $foreignKeys = $db->getDoctrineSchemaManager()->listTableForeignKeys("{$db->getTablePrefix()}polls"); - - foreach ($foreignKeys as $foreignKey) { - if (in_array('post_id', $foreignKey->getLocalColumns())) { - return; - } - } - - $schema->table('polls', function (Blueprint $table) { - $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); - }); - }, - 'down' => function (Builder $schema) { - $schema->table('polls', function (Blueprint $table) { - $table->dropForeign(['post_id']); - }); - }, -]; From c1efb94c567ae6d54d97a62925e52f26714995df Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 26 Jul 2023 16:35:04 +0000 Subject: [PATCH 3/4] Apply fixes from StyleCI --- ...07_08_000000_update_polls_discussion_id_to_post_id_values.php | 1 - ..._08_000001_update_polls_discussion_relation_to_first_post.php | 1 - 2 files changed, 2 deletions(-) diff --git a/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php index 2b3f84d2..9a4892d7 100644 --- a/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php +++ b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php @@ -10,7 +10,6 @@ */ use Illuminate\Database\Query\JoinClause; -use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; // Split 1/2 of 2023_07_08_000001_update_polls_discussion_relation_to_first_post.php diff --git a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php index 49c6f370..b003a39f 100644 --- a/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php +++ b/migrations/2023_07_08_000001_update_polls_discussion_relation_to_first_post.php @@ -9,7 +9,6 @@ * file that was distributed with this source code. */ -use Illuminate\Database\Query\JoinClause; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; From dad8e7ca794da42b1e1559f8e6877d16928e313c Mon Sep 17 00:00:00 2001 From: David Sevilla Martin Date: Wed, 26 Jul 2023 12:35:44 -0400 Subject: [PATCH 4/4] Add comment --- ...07_08_000000_update_polls_discussion_id_to_post_id_values.php | 1 + 1 file changed, 1 insertion(+) diff --git a/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php index 9a4892d7..fe776fd2 100644 --- a/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php +++ b/migrations/2023_07_08_000000_update_polls_discussion_id_to_post_id_values.php @@ -17,6 +17,7 @@ 'up' => function (Builder $schema) { $db = $schema->getConnection(); + // Do not run this migration if the values were already updated before the split if ($db->table('migrations')->where('migration', '2023_07_08_000001_update_polls_discussion_relation_to_first_post')->exists()) { return; }