From fbf0eedb8e83bf4f2d8932b4b01296aed03f2315 Mon Sep 17 00:00:00 2001 From: Fabian Linges Date: Wed, 25 Jan 2017 10:15:13 +0100 Subject: [PATCH] fix whodoneit-map. #18 --- lib/mix/tasks/whatwasit.install.ex | 16 ++++++ .../whatwasit.install/lib}/whatwasit/repo.ex | 0 .../whatwasit.install/lib/whatwasit/repo_.ex | 52 +++++++++++++++++++ .../lib/whatwasit/repo_map.ex | 52 +++++++++++++++++++ 4 files changed, 120 insertions(+) rename {lib => priv/templates/whatwasit.install/lib}/whatwasit/repo.ex (100%) create mode 100644 priv/templates/whatwasit.install/lib/whatwasit/repo_.ex create mode 100644 priv/templates/whatwasit.install/lib/whatwasit/repo_map.ex diff --git a/lib/mix/tasks/whatwasit.install.ex b/lib/mix/tasks/whatwasit.install.ex index 3a3ca52..44f3d1e 100644 --- a/lib/mix/tasks/whatwasit.install.ex +++ b/lib/mix/tasks/whatwasit.install.ex @@ -82,9 +82,25 @@ defmodule Mix.Tasks.Whatwasit.Install do config |> gen_migration |> gen_version_model + |> gen_repo |> print_instructions end + defp gen_repo(%{whodoneit_map: true, binding: binding} = config) do + Mix.Phoenix.copy_from paths(), + "priv/templates/whatwasit.install/lib/whatwasit", "", binding, [ + {:eex, "repo_map.ex", "lib/whatwasit/repo.ex"}, + ] + config + end + defp gen_repo(%{binding: binding} = config) do + Mix.Phoenix.copy_from paths(), + "priv/templates/whatwasit.install/lib/whatwasit", "", binding, [ + {:eex, "repo.ex", "lib/whatwasit/repo.ex"}, + ] + config + end + defp gen_version_model(%{models: true, whodoneit_map: true, boilerplate: true, binding: binding} = config) do changeset_fields = "~w(item_type item_id object action whodoneit)a" schema_fields = "field :whodoneit, :map\n" diff --git a/lib/whatwasit/repo.ex b/priv/templates/whatwasit.install/lib/whatwasit/repo.ex similarity index 100% rename from lib/whatwasit/repo.ex rename to priv/templates/whatwasit.install/lib/whatwasit/repo.ex diff --git a/priv/templates/whatwasit.install/lib/whatwasit/repo_.ex b/priv/templates/whatwasit.install/lib/whatwasit/repo_.ex new file mode 100644 index 0000000..0b8420a --- /dev/null +++ b/priv/templates/whatwasit.install/lib/whatwasit/repo_.ex @@ -0,0 +1,52 @@ +defmodule Whatwasit.Repo do + + defmacro __using__(_opts \\ []) do + quote do + @base Mix.Project.get |> Module.split |> Enum.reverse |> Enum.at(1) + @version_module Module.concat([@base, Whatwasit, Version]) + alias Ecto.Multi + def insert_with_version(%Ecto.Changeset{} = changeset, opts \\ []) do + repo = opts[:repo] || changeset.repo || Application.get_env(:whatwasit, :repo) + res = Multi.new + |> Multi.insert(:insert, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:insert) + end + def update_with_version(%Ecto.Changeset{} = changeset, opts \\ []) do + repo = opts[:repo] || changeset.repo || Application.get_env(:whatwasit, :repo) + res = Multi.new + |> Multi.update(:update, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:update) + end + def delete_with_version(changeset, opts \\ []) do + repo = opts[:repo] || Application.get_env(:whatwasit, :repo) + Multi.new + |> Multi.delete(:delete, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:delete) + end + end + end + + def insert_version(changes, module, repo, opts) do + [{action, model}] = Map.to_list changes + whodoneit = opts[:whodoneit] + changeset = module.version_changeset(model, whodoneit, action) + apply(repo, :insert, [changeset]) + |> case do + {:ok, _} -> {:ok, model} + error -> error + end + end + + def handle_result(result, action) do + case result do + {:error, _, changeset, _} -> {:error, changeset} + {:ok, %{} = res} -> {:ok, res[action]} + end + end +end diff --git a/priv/templates/whatwasit.install/lib/whatwasit/repo_map.ex b/priv/templates/whatwasit.install/lib/whatwasit/repo_map.ex new file mode 100644 index 0000000..0b8420a --- /dev/null +++ b/priv/templates/whatwasit.install/lib/whatwasit/repo_map.ex @@ -0,0 +1,52 @@ +defmodule Whatwasit.Repo do + + defmacro __using__(_opts \\ []) do + quote do + @base Mix.Project.get |> Module.split |> Enum.reverse |> Enum.at(1) + @version_module Module.concat([@base, Whatwasit, Version]) + alias Ecto.Multi + def insert_with_version(%Ecto.Changeset{} = changeset, opts \\ []) do + repo = opts[:repo] || changeset.repo || Application.get_env(:whatwasit, :repo) + res = Multi.new + |> Multi.insert(:insert, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:insert) + end + def update_with_version(%Ecto.Changeset{} = changeset, opts \\ []) do + repo = opts[:repo] || changeset.repo || Application.get_env(:whatwasit, :repo) + res = Multi.new + |> Multi.update(:update, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:update) + end + def delete_with_version(changeset, opts \\ []) do + repo = opts[:repo] || Application.get_env(:whatwasit, :repo) + Multi.new + |> Multi.delete(:delete, changeset) + |> Multi.run(:version, unquote(__MODULE__), :insert_version, [@version_module, repo, opts]) + |> repo.transaction + |> unquote(__MODULE__).handle_result(:delete) + end + end + end + + def insert_version(changes, module, repo, opts) do + [{action, model}] = Map.to_list changes + whodoneit = opts[:whodoneit] + changeset = module.version_changeset(model, whodoneit, action) + apply(repo, :insert, [changeset]) + |> case do + {:ok, _} -> {:ok, model} + error -> error + end + end + + def handle_result(result, action) do + case result do + {:error, _, changeset, _} -> {:error, changeset} + {:ok, %{} = res} -> {:ok, res[action]} + end + end +end