Skip to content

Commit

Permalink
Keep post_id foreign in existing migration & move value updating to a…
Browse files Browse the repository at this point in the history
…n earlier one to avoid foreign key check
  • Loading branch information
dsevillamartin committed Jul 26, 2023
1 parent 2726554 commit 78ff790
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 99 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/*
* This file is part of fof/polls.
*
* Copyright (c) FriendsOfFlarum.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

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
return [
'up' => 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")]);
});
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
});
},
];
39 changes: 0 additions & 39 deletions migrations/2023_07_08_000002_add_polls_post_id_foreign.php

This file was deleted.

0 comments on commit 78ff790

Please sign in to comment.