87 lines
3.0 KiB
Ruby
87 lines
3.0 KiB
Ruby
# typed: strict
|
|
class Tasks::Fa::MigrateFaUserPostFavs < Tasks::InterruptableTask
|
|
extend T::Sig
|
|
|
|
sig { override.returns(String) }
|
|
def progress_key
|
|
"fa-migrate-fa-user-post-favs"
|
|
end
|
|
|
|
sig { override.void }
|
|
def run_impl
|
|
raise "not implemented"
|
|
end
|
|
|
|
sig { params(user: Domain::User::FaUser, batch_size: Integer).void }
|
|
def run_for_user(user:, batch_size: 100)
|
|
user_faved_post_ids = user.faved_posts.pluck(:id)
|
|
|
|
total = user_faved_post_ids.size
|
|
return if total <= 0
|
|
pb = ProgressBar.create(format: Tasks::InterruptableTask::PB_FORMAT, total:)
|
|
pb.progress = 0
|
|
|
|
user_faved_post_ids.each_slice(batch_size) do |post_ids|
|
|
post_ids_clause = "domain_posts.id IN (#{post_ids.join(",")})"
|
|
migrate_posts(post_ids_clause)
|
|
pb.progress = [pb.progress + post_ids.size, pb.total].min
|
|
break if interrupted?
|
|
end
|
|
end
|
|
|
|
sig { params(start_at: T.nilable(String), batch_size: Integer).void }
|
|
def run_for_posts(start_at: nil, batch_size: 100)
|
|
domain_post_id_range = Domain::Post.maximum(:id)
|
|
start_at_id = (get_progress(start_at) || 0).to_i
|
|
total = domain_post_id_range - start_at_id
|
|
return if total <= 0
|
|
pb = ProgressBar.create(format: Tasks::InterruptableTask::PB_FORMAT, total:)
|
|
|
|
(start_at_id..domain_post_id_range)
|
|
.step(batch_size)
|
|
.each do |batch_start|
|
|
batch_end = [batch_start + batch_size, domain_post_id_range].min
|
|
batch_end += 1 if batch_end == domain_post_id_range
|
|
|
|
post_ids_clause =
|
|
"domain_posts.id >= #{batch_start} AND domain_posts.id < #{batch_end}"
|
|
migrate_posts(post_ids_clause)
|
|
|
|
pb.progress = [pb.progress + batch_size, pb.total].min
|
|
save_progress(batch_end.to_s)
|
|
break if interrupted?
|
|
end
|
|
end
|
|
|
|
sig { params(post_ids_clause: String).void }
|
|
def migrate_posts(post_ids_clause)
|
|
ReduxApplicationRecord.transaction do
|
|
ReduxApplicationRecord.connection.execute <<-SQL
|
|
UPDATE domain_user_post_favs
|
|
SET type = 'Domain::UserPostFav::FaUserPostFav'
|
|
WHERE post_id IN (
|
|
SELECT id
|
|
FROM domain_posts
|
|
WHERE type = 'Domain::Post::FaPost'
|
|
AND #{post_ids_clause}
|
|
)
|
|
SQL
|
|
|
|
ReduxApplicationRecord.connection.execute <<-SQL
|
|
UPDATE domain_user_post_favs
|
|
SET json_attributes =
|
|
domain_user_post_favs.json_attributes
|
|
|| jsonb_build_object('fav_id', domain_fa_fav_id_and_dates.fav_fa_id)
|
|
|| jsonb_build_object('explicit_time', EXTRACT(EPOCH FROM domain_fa_fav_id_and_dates.date)::integer)
|
|
FROM domain_fa_fav_id_and_dates
|
|
JOIN domain_posts ON (domain_posts.json_attributes->>'fa_id')::integer = domain_fa_fav_id_and_dates.post_fa_id
|
|
WHERE domain_user_post_favs.post_id = domain_posts.id
|
|
AND domain_fa_fav_id_and_dates.user_id = domain_user_post_favs.user_id
|
|
AND domain_user_post_favs.type = 'Domain::UserPostFav::FaUserPostFav'
|
|
AND domain_posts.type = 'Domain::Post::FaPost'
|
|
AND #{post_ids_clause}
|
|
SQL
|
|
end
|
|
end
|
|
end
|