Skip to content

Commit

Permalink
Create serializer module and reuse it across the application
Browse files Browse the repository at this point in the history
  • Loading branch information
rschef committed Apr 30, 2020
1 parent 0976691 commit 0670a46
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 249 deletions.
111 changes: 8 additions & 103 deletions lib/paper_trail.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule PaperTrail do

alias PaperTrail.Version
alias PaperTrail.RepoClient
alias PaperTrail.Serializer

defdelegate get_version(record), to: PaperTrail.VersionQueries
defdelegate get_version(model_or_record, id_or_options), to: PaperTrail.VersionQueries
Expand All @@ -11,6 +12,13 @@ defmodule PaperTrail do
defdelegate get_versions(model_or_record, id_or_options), to: PaperTrail.VersionQueries
defdelegate get_versions(model, id, options), to: PaperTrail.VersionQueries
defdelegate get_current_model(version), to: PaperTrail.VersionQueries
defdelegate make_version_struct(version, model, options), to: Serializer
defdelegate get_sequence_from_model(changeset), to: Serializer
defdelegate serialize(data), to: Serializer
defdelegate get_sequence_id(table_name), to: Serializer
defdelegate add_prefix(changeset, prefix), to: Serializer
defdelegate get_item_type(data), to: Serializer
defdelegate get_model_id(model), to: Serializer

@doc """
Inserts a record to the database with a related version insertion in one transaction
Expand Down Expand Up @@ -138,107 +146,4 @@ defmodule PaperTrail do
end)
|> elem(1)
end

defp make_version_struct(%{event: "insert"}, model, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "insert",
item_type: get_item_type(model),
item_id: get_model_id(model),
item_changes: serialize(model),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp make_version_struct(%{event: "update"}, changeset, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "update",
item_type: get_item_type(changeset),
item_id: get_model_id(changeset),
item_changes: changeset.changes,
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp make_version_struct(%{event: "delete"}, model_or_changeset, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "delete",
item_type: get_item_type(model_or_changeset),
item_id: get_model_id(model_or_changeset),
item_changes: serialize(model_or_changeset),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp get_sequence_from_model(changeset) do
table_name =
case Map.get(changeset, :data) do
nil -> changeset.__struct__.__schema__(:source)
_ -> changeset.data.__struct__.__schema__(:source)
end

get_sequence_id(table_name)
end

defp get_sequence_id(table_name) do
Ecto.Adapters.SQL.query!(RepoClient.repo(), "select last_value FROM #{table_name}_id_seq").rows
|> List.first()
|> List.first()
end

defp serialize(%Ecto.Changeset{data: data}), do: serialize(data)

defp serialize(model) do
relationships = model.__struct__.__schema__(:associations)
Map.drop(model, [:__struct__, :__meta__] ++ relationships)
end

defp add_prefix(changeset, nil), do: changeset
defp add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)

defp get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
defp get_item_type(model), do: model.__struct__ |> Module.split() |> List.last()

def get_model_id(%Ecto.Changeset{data: data}), do: get_model_id(data)

def get_model_id(model) do
{_, model_id} = List.first(Ecto.primary_key(model))

case PaperTrail.Version.__schema__(:type, :item_id) do
:integer ->
model_id

_ ->
"#{model_id}"
end
end
end
111 changes: 8 additions & 103 deletions lib/paper_trail/multi.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule PaperTrail.Multi do
alias PaperTrail
alias PaperTrail.Version
alias PaperTrail.RepoClient
alias PaperTrail.Serializer

defdelegate new(), to: Ecto.Multi
defdelegate append(lhs, rhs), to: Ecto.Multi
Expand All @@ -14,6 +15,13 @@ defmodule PaperTrail.Multi do
defdelegate run(multi, name, run), to: Ecto.Multi
defdelegate run(multi, name, mod, fun, args), to: Ecto.Multi
defdelegate to_list(multi), to: Ecto.Multi
defdelegate make_version_struct(version, model, options), to: Serializer
defdelegate get_sequence_from_model(changeset), to: Serializer
defdelegate serialize(data), to: Serializer
defdelegate get_sequence_id(table_name), to: Serializer
defdelegate add_prefix(changeset, prefix), to: Serializer
defdelegate get_item_type(data), to: Serializer
defdelegate get_model_id(model), to: Serializer

def insert(%Ecto.Multi{} = multi, changeset, options \\ [
origin: nil, meta: nil, originator: nil, prefix: nil, model_key: :model, version_key: :version
Expand Down Expand Up @@ -145,107 +153,4 @@ defmodule PaperTrail.Multi do
end
end
end

defp make_version_struct(%{event: "insert"}, model, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "insert",
item_type: get_item_type(model),
item_id: get_model_id(model),
item_changes: serialize(model),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp make_version_struct(%{event: "update"}, changeset, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "update",
item_type: get_item_type(changeset),
item_id: get_model_id(changeset),
item_changes: changeset.changes,
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp make_version_struct(%{event: "delete"}, model_or_changeset, options) do
originator = PaperTrail.RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "delete",
item_type: get_item_type(model_or_changeset),
item_id: get_model_id(model_or_changeset),
item_changes: serialize(model_or_changeset),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

defp get_sequence_from_model(changeset) do
table_name =
case Map.get(changeset, :data) do
nil -> changeset.__struct__.__schema__(:source)
_ -> changeset.data.__struct__.__schema__(:source)
end

get_sequence_id(table_name)
end

defp get_sequence_id(table_name) do
Ecto.Adapters.SQL.query!(RepoClient.repo(), "select last_value FROM #{table_name}_id_seq").rows
|> List.first()
|> List.first()
end

defp serialize(%Ecto.Changeset{data: data}), do: serialize(data)

defp serialize(model) do
relationships = model.__struct__.__schema__(:associations)
Map.drop(model, [:__struct__, :__meta__] ++ relationships)
end

defp add_prefix(changeset, nil), do: changeset
defp add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)

defp get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
defp get_item_type(model), do: model.__struct__ |> Module.split() |> List.last()

defp get_model_id(%Ecto.Changeset{data: data}), do: get_model_id(data)

defp get_model_id(model) do
{_, model_id} = List.first(Ecto.primary_key(model))

case PaperTrail.Version.__schema__(:type, :item_id) do
:integer ->
model_id

_ ->
"#{model_id}"
end
end
end
110 changes: 110 additions & 0 deletions lib/paper_trail/serializer.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
defmodule PaperTrail.Serializer do

alias PaperTrail.RepoClient
alias PaperTrail.Version

def make_version_struct(%{event: "insert"}, model, options) do
originator = RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "insert",
item_type: get_item_type(model),
item_id: get_model_id(model),
item_changes: serialize(model),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

def make_version_struct(%{event: "update"}, changeset, options) do
originator = RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "update",
item_type: get_item_type(changeset),
item_id: get_model_id(changeset),
item_changes: changeset.changes,
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

def make_version_struct(%{event: "delete"}, model_or_changeset, options) do
originator = RepoClient.originator()
originator_ref = options[originator[:name]] || options[:originator]

%Version{
event: "delete",
item_type: get_item_type(model_or_changeset),
item_id: get_model_id(model_or_changeset),
item_changes: serialize(model_or_changeset),
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
end,
origin: options[:origin],
meta: options[:meta]
}
|> add_prefix(options[:prefix])
end

def get_sequence_from_model(changeset) do
table_name =
case Map.get(changeset, :data) do
nil -> changeset.__struct__.__schema__(:source)
_ -> changeset.data.__struct__.__schema__(:source)
end

get_sequence_id(table_name)
end

def get_sequence_id(table_name) do
Ecto.Adapters.SQL.query!(RepoClient.repo(), "select last_value FROM #{table_name}_id_seq").rows
|> List.first()
|> List.first()
end

def serialize(nil), do: nil

def serialize(%Ecto.Changeset{data: data}), do: serialize(data)

def serialize(model) do
relationships = model.__struct__.__schema__(:associations)
Map.drop(model, [:__struct__, :__meta__] ++ relationships)
end

def add_prefix(changeset, nil), do: changeset
def add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)

def get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
def get_item_type(%schema{}), do: schema |> Module.split() |> List.last()

def get_model_id(%Ecto.Changeset{data: data}), do: get_model_id(data)

def get_model_id(model) do
{_, model_id} = List.first(Ecto.primary_key(model))

case PaperTrail.Version.__schema__(:type, :item_id) do
:integer ->
model_id

_ ->
"#{model_id}"
end
end
end
Loading

0 comments on commit 0670a46

Please sign in to comment.