From b97073ee1892099c57b8720ed909cd348c5daf43 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Mon, 13 Jul 2020 23:44:45 -0400 Subject: [PATCH] reintroduce transaction and add impossible condition to first element of reduce step --- lib/philomena/tag_changes.ex | 75 ++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/lib/philomena/tag_changes.ex b/lib/philomena/tag_changes.ex index 6580799b..0f7d2a00 100644 --- a/lib/philomena/tag_changes.ex +++ b/lib/philomena/tag_changes.ex @@ -37,59 +37,66 @@ defmodule Philomena.TagChanges do to_remove = added |> Enum.map(&{&1.image_id, &1.tag_id}) - |> Enum.reduce(Tagging, fn {image_id, tag_id}, q -> + |> Enum.reduce(where(Tagging, fragment("'t' = 'f'")), fn {image_id, tag_id}, q -> or_where(q, image_id: ^image_id, tag_id: ^tag_id) end) |> select([t], [t.image_id, t.tag_id]) to_add = Enum.map(removed, &%{image_id: &1.image_id, tag_id: &1.tag_id}) - {_count, inserted} = - Repo.insert_all(Tagging, to_add, on_conflict: :nothing, returning: [:image_id, :tag_id]) + Repo.transaction(fn -> + {_count, inserted} = + Repo.insert_all(Tagging, to_add, on_conflict: :nothing, returning: [:image_id, :tag_id]) - {_count, deleted} = Repo.delete_all(to_remove) + {_count, deleted} = Repo.delete_all(to_remove) - inserted = Enum.map(inserted, &[&1.image_id, &1.tag_id]) + inserted = Enum.map(inserted, &[&1.image_id, &1.tag_id]) - added_changes = - Enum.map(inserted, fn [image_id, tag_id] -> - Map.merge(tag_change_attributes, %{image_id: image_id, tag_id: tag_id, added: true}) - end) + added_changes = + Enum.map(inserted, fn [image_id, tag_id] -> + Map.merge(tag_change_attributes, %{image_id: image_id, tag_id: tag_id, added: true}) + end) - removed_changes = - Enum.map(deleted, fn [image_id, tag_id] -> - Map.merge(tag_change_attributes, %{image_id: image_id, tag_id: tag_id, added: false}) - end) + removed_changes = + Enum.map(deleted, fn [image_id, tag_id] -> + Map.merge(tag_change_attributes, %{image_id: image_id, tag_id: tag_id, added: false}) + end) - Repo.insert_all(TagChange, added_changes ++ removed_changes) + Repo.insert_all(TagChange, added_changes ++ removed_changes) - # In order to merge into the existing tables here in one go, insert_all - # is used with a query that is guaranteed to conflict on every row by - # using the primary key. + # In order to merge into the existing tables here in one go, insert_all + # is used with a query that is guaranteed to conflict on every row by + # using the primary key. - added_upserts = - inserted - |> Enum.group_by(fn [_image_id, tag_id] -> tag_id end) - |> Enum.map(fn {tag_id, instances} -> - Map.merge(tag_attributes, %{id: tag_id, images_count: length(instances)}) - end) + added_upserts = + inserted + |> Enum.group_by(fn [_image_id, tag_id] -> tag_id end) + |> Enum.map(fn {tag_id, instances} -> + Map.merge(tag_attributes, %{id: tag_id, images_count: length(instances)}) + end) - removed_upserts = - deleted - |> Enum.group_by(fn [_image_id, tag_id] -> tag_id end) - |> Enum.map(fn {tag_id, instances} -> - Map.merge(tag_attributes, %{id: tag_id, images_count: -length(instances)}) - end) + removed_upserts = + deleted + |> Enum.group_by(fn [_image_id, tag_id] -> tag_id end) + |> Enum.map(fn {tag_id, instances} -> + Map.merge(tag_attributes, %{id: tag_id, images_count: -length(instances)}) + end) - update_query = update(Tag, inc: [images_count: fragment("EXCLUDED.images_count")]) + update_query = update(Tag, inc: [images_count: fragment("EXCLUDED.images_count")]) - upserts = added_upserts ++ removed_upserts + upserts = added_upserts ++ removed_upserts - Repo.insert_all(Tag, upserts, on_conflict: update_query, conflict_target: [:id]) + Repo.insert_all(Tag, upserts, on_conflict: update_query, conflict_target: [:id]) + end) + |> case do + {:ok, _result} -> + Images.reindex_images(image_ids) - Images.reindex_images(image_ids) + {:ok, tag_changes} - {:ok, tag_changes} + error -> + error + end end @doc """