defmodule Philomena.UserDownvoteWipe do alias PhilomenaQuery.Batch alias PhilomenaQuery.Search alias Philomena.Users alias Philomena.Users.User alias Philomena.Images.Image alias Philomena.Images alias Philomena.ImageVotes.ImageVote alias Philomena.ImageFaves.ImageFave alias Philomena.Repo import Ecto.Query def perform(user_id, upvotes_and_faves_too \\ false) do user = Users.get_user!(user_id) ImageVote |> where(user_id: ^user.id, up: false) |> Batch.query_batches([id_field: :image_id], fn queryable -> {_, image_ids} = Repo.delete_all(select(queryable, [i_v], i_v.image_id)) {count, nil} = Repo.update_all(where(Image, [i], i.id in ^image_ids), inc: [downvotes_count: -1, score: 1] ) Repo.update_all(where(User, id: ^user.id), inc: [votes_cast_count: -count]) reindex(image_ids) end) if upvotes_and_faves_too do ImageVote |> where(user_id: ^user.id, up: true) |> Batch.query_batches([id_field: :image_id], fn queryable -> {_, image_ids} = Repo.delete_all(select(queryable, [i_v], i_v.image_id)) {count, nil} = Repo.update_all(where(Image, [i], i.id in ^image_ids), inc: [upvotes_count: -1, score: -1] ) Repo.update_all(where(User, id: ^user.id), inc: [votes_cast_count: -count]) reindex(image_ids) end) ImageFave |> where(user_id: ^user.id) |> Batch.query_batches([id_field: :image_id], fn queryable -> {_, image_ids} = Repo.delete_all(select(queryable, [i_f], i_f.image_id)) {count, nil} = Repo.update_all(where(Image, [i], i.id in ^image_ids), inc: [faves_count: -1]) Repo.update_all(where(User, id: ^user.id), inc: [images_favourited_count: -count]) reindex(image_ids) end) end end defp reindex(image_ids) do Image |> where([i], i.id in ^image_ids) |> preload(^Images.indexing_preloads()) |> Search.reindex(Image) # allow time for indexing to catch up :timer.sleep(:timer.seconds(10)) end end