Skip to content

Commit c58cbd5

Browse files
rschefmayel
authored andcommitted
Dump fields using Ecto when serializing changes (izelnakri#83)
* Add .tool-versions to .gitignore * Change logger level to warn in test environment * Fix warning when running tests * Create serializer module and reuse it across the application * Dump ecto fields when serializing changes * Add type specs and docs to Serializer * Replace get_sequence_from_model/1 by get_sequence_id/1 * Apply documentation
1 parent fbe5840 commit c58cbd5

15 files changed

+292
-277
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
erl_crash.dump
55
*.ez
66
.elixir_ls
7+
.tool-versions

config/test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ config :paper_trail, PaperTrail.UUIDRepo,
1919
database: "paper_trail_uuid_test",
2020
hostname: System.get_env("PG_HOST"),
2121
poolsize: 10
22+
23+
config :logger, level: :warn

lib/paper_trail.ex

Lines changed: 8 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule PaperTrail do
33

44
alias PaperTrail.Version
55
alias PaperTrail.RepoClient
6+
alias PaperTrail.Serializer
67

78
defdelegate get_version(record), to: PaperTrail.VersionQueries
89
defdelegate get_version(model_or_record, id_or_options), to: PaperTrail.VersionQueries
@@ -11,6 +12,12 @@ defmodule PaperTrail do
1112
defdelegate get_versions(model_or_record, id_or_options), to: PaperTrail.VersionQueries
1213
defdelegate get_versions(model, id, options), to: PaperTrail.VersionQueries
1314
defdelegate get_current_model(version), to: PaperTrail.VersionQueries
15+
defdelegate make_version_struct(version, model, options), to: Serializer
16+
defdelegate serialize(data), to: Serializer
17+
defdelegate get_sequence_id(table_name), to: Serializer
18+
defdelegate add_prefix(schema, prefix), to: Serializer
19+
defdelegate get_item_type(data), to: Serializer
20+
defdelegate get_model_id(model), to: Serializer
1421

1522
@doc """
1623
Intialise paper_trail for existing record
@@ -52,7 +59,7 @@ defmodule PaperTrail do
5259
changeset_data =
5360
Map.get(changeset, :data, changeset)
5461
|> Map.merge(%{
55-
id: get_sequence_from_model(changeset) + 1,
62+
id: get_sequence_id(changeset) + 1,
5663
first_version_id: version_id,
5764
current_version_id: version_id
5865
})
@@ -155,107 +162,4 @@ defmodule PaperTrail do
155162
end)
156163
|> elem(1)
157164
end
158-
159-
defp make_version_struct(%{event: "insert"}, model, options) do
160-
originator = PaperTrail.RepoClient.originator()
161-
originator_ref = options[originator[:name]] || options[:originator]
162-
163-
%Version{
164-
event: "insert",
165-
item_type: get_item_type(model),
166-
item_id: get_model_id(model),
167-
item_changes: serialize(model),
168-
originator_id:
169-
case originator_ref do
170-
nil -> nil
171-
_ -> originator_ref |> Map.get(:id)
172-
end,
173-
origin: options[:origin],
174-
meta: options[:meta]
175-
}
176-
|> add_prefix(options[:prefix])
177-
end
178-
179-
defp make_version_struct(%{event: "update"}, changeset, options) do
180-
originator = PaperTrail.RepoClient.originator()
181-
originator_ref = options[originator[:name]] || options[:originator]
182-
183-
%Version{
184-
event: "update",
185-
item_type: get_item_type(changeset),
186-
item_id: get_model_id(changeset),
187-
item_changes: changeset.changes,
188-
originator_id:
189-
case originator_ref do
190-
nil -> nil
191-
_ -> originator_ref |> Map.get(:id)
192-
end,
193-
origin: options[:origin],
194-
meta: options[:meta]
195-
}
196-
|> add_prefix(options[:prefix])
197-
end
198-
199-
defp make_version_struct(%{event: "delete"}, model_or_changeset, options) do
200-
originator = PaperTrail.RepoClient.originator()
201-
originator_ref = options[originator[:name]] || options[:originator]
202-
203-
%Version{
204-
event: "delete",
205-
item_type: get_item_type(model_or_changeset),
206-
item_id: get_model_id(model_or_changeset),
207-
item_changes: serialize(model_or_changeset),
208-
originator_id:
209-
case originator_ref do
210-
nil -> nil
211-
_ -> originator_ref |> Map.get(:id)
212-
end,
213-
origin: options[:origin],
214-
meta: options[:meta]
215-
}
216-
|> add_prefix(options[:prefix])
217-
end
218-
219-
defp get_sequence_from_model(changeset) do
220-
table_name =
221-
case Map.get(changeset, :data) do
222-
nil -> changeset.__struct__.__schema__(:source)
223-
_ -> changeset.data.__struct__.__schema__(:source)
224-
end
225-
226-
get_sequence_id(table_name)
227-
end
228-
229-
defp get_sequence_id(table_name) do
230-
Ecto.Adapters.SQL.query!(RepoClient.repo(), "select last_value FROM #{table_name}_id_seq").rows
231-
|> List.first()
232-
|> List.first()
233-
end
234-
235-
defp serialize(%Ecto.Changeset{data: data}), do: serialize(data)
236-
237-
defp serialize(model) do
238-
relationships = model.__struct__.__schema__(:associations)
239-
Map.drop(model, [:__struct__, :__meta__] ++ relationships)
240-
end
241-
242-
defp add_prefix(changeset, nil), do: changeset
243-
defp add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)
244-
245-
defp get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
246-
defp get_item_type(model), do: model.__struct__ |> Module.split() |> List.last()
247-
248-
def get_model_id(%Ecto.Changeset{data: data}), do: get_model_id(data)
249-
250-
def get_model_id(model) do
251-
{_, model_id} = List.first(Ecto.primary_key(model))
252-
253-
case PaperTrail.Version.__schema__(:type, :item_id) do
254-
:integer ->
255-
model_id
256-
257-
_ ->
258-
"#{model_id}"
259-
end
260-
end
261165
end

lib/paper_trail/multi.ex

Lines changed: 8 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ defmodule PaperTrail.Multi do
44
alias PaperTrail
55
alias PaperTrail.Version
66
alias PaperTrail.RepoClient
7+
alias PaperTrail.Serializer
78

89
defdelegate new(), to: Ecto.Multi
910
defdelegate append(lhs, rhs), to: Ecto.Multi
@@ -14,6 +15,12 @@ defmodule PaperTrail.Multi do
1415
defdelegate run(multi, name, run), to: Ecto.Multi
1516
defdelegate run(multi, name, mod, fun, args), to: Ecto.Multi
1617
defdelegate to_list(multi), to: Ecto.Multi
18+
defdelegate make_version_struct(version, model, options), to: Serializer
19+
defdelegate serialize(data), to: Serializer
20+
defdelegate get_sequence_id(table_name), to: Serializer
21+
defdelegate add_prefix(schema, prefix), to: Serializer
22+
defdelegate get_item_type(data), to: Serializer
23+
defdelegate get_model_id(model), to: Serializer
1724

1825
def insert(
1926
%Ecto.Multi{} = multi,
@@ -41,7 +48,7 @@ defmodule PaperTrail.Multi do
4148
changeset_data =
4249
Map.get(changeset, :data, changeset)
4350
|> Map.merge(%{
44-
id: get_sequence_from_model(changeset) + 1,
51+
id: get_sequence_id(changeset) + 1,
4552
first_version_id: version_id,
4653
current_version_id: version_id
4754
})
@@ -177,107 +184,4 @@ defmodule PaperTrail.Multi do
177184
end
178185
end
179186
end
180-
181-
defp make_version_struct(%{event: "insert"}, model, options) do
182-
originator = PaperTrail.RepoClient.originator()
183-
originator_ref = options[originator[:name]] || options[:originator]
184-
185-
%Version{
186-
event: "insert",
187-
item_type: get_item_type(model),
188-
item_id: get_model_id(model),
189-
item_changes: serialize(model),
190-
originator_id:
191-
case originator_ref do
192-
nil -> nil
193-
_ -> originator_ref |> Map.get(:id)
194-
end,
195-
origin: options[:origin],
196-
meta: options[:meta]
197-
}
198-
|> add_prefix(options[:prefix])
199-
end
200-
201-
defp make_version_struct(%{event: "update"}, changeset, options) do
202-
originator = PaperTrail.RepoClient.originator()
203-
originator_ref = options[originator[:name]] || options[:originator]
204-
205-
%Version{
206-
event: "update",
207-
item_type: get_item_type(changeset),
208-
item_id: get_model_id(changeset),
209-
item_changes: changeset.changes,
210-
originator_id:
211-
case originator_ref do
212-
nil -> nil
213-
_ -> originator_ref |> Map.get(:id)
214-
end,
215-
origin: options[:origin],
216-
meta: options[:meta]
217-
}
218-
|> add_prefix(options[:prefix])
219-
end
220-
221-
defp make_version_struct(%{event: "delete"}, model_or_changeset, options) do
222-
originator = PaperTrail.RepoClient.originator()
223-
originator_ref = options[originator[:name]] || options[:originator]
224-
225-
%Version{
226-
event: "delete",
227-
item_type: get_item_type(model_or_changeset),
228-
item_id: get_model_id(model_or_changeset),
229-
item_changes: serialize(model_or_changeset),
230-
originator_id:
231-
case originator_ref do
232-
nil -> nil
233-
_ -> originator_ref |> Map.get(:id)
234-
end,
235-
origin: options[:origin],
236-
meta: options[:meta]
237-
}
238-
|> add_prefix(options[:prefix])
239-
end
240-
241-
defp get_sequence_from_model(changeset) do
242-
table_name =
243-
case Map.get(changeset, :data) do
244-
nil -> changeset.__struct__.__schema__(:source)
245-
_ -> changeset.data.__struct__.__schema__(:source)
246-
end
247-
248-
get_sequence_id(table_name)
249-
end
250-
251-
defp get_sequence_id(table_name) do
252-
Ecto.Adapters.SQL.query!(RepoClient.repo(), "select last_value FROM #{table_name}_id_seq").rows
253-
|> List.first()
254-
|> List.first()
255-
end
256-
257-
defp serialize(%Ecto.Changeset{data: data}), do: serialize(data)
258-
259-
defp serialize(model) do
260-
relationships = model.__struct__.__schema__(:associations)
261-
Map.drop(model, [:__struct__, :__meta__] ++ relationships)
262-
end
263-
264-
defp add_prefix(changeset, nil), do: changeset
265-
defp add_prefix(changeset, prefix), do: Ecto.put_meta(changeset, prefix: prefix)
266-
267-
defp get_item_type(%Ecto.Changeset{data: data}), do: get_item_type(data)
268-
defp get_item_type(model), do: model.__struct__ |> Module.split() |> List.last()
269-
270-
defp get_model_id(%Ecto.Changeset{data: data}), do: get_model_id(data)
271-
272-
defp get_model_id(model) do
273-
{_, model_id} = List.first(Ecto.primary_key(model))
274-
275-
case PaperTrail.Version.__schema__(:type, :item_id) do
276-
:integer ->
277-
model_id
278-
279-
_ ->
280-
"#{model_id}"
281-
end
282-
end
283187
end

0 commit comments

Comments
 (0)