Skip to content

Commit

Permalink
Merge branch 'master' of github.com:ZennerIoT/ex_audit
Browse files Browse the repository at this point in the history
  • Loading branch information
narrowtux committed Apr 4, 2019
2 parents 7b2b754 + 6478d72 commit ac7446b
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 30 deletions.
26 changes: 21 additions & 5 deletions lib/repo/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,21 @@ defmodule ExAudit.Schema do
end

def insert_or_update(module, adapter, changeset, opts) do
# TODO!
opts = augment_opts(opts)
Ecto.Repo.Schema.insert_or_update(module, adapter, changeset, opts)
augment_transaction(module, fn ->
result = Ecto.Repo.Schema.insert_or_update(module, adapter, changeset, opts)

case result do
{:ok, resulting_struct} ->
state = if changeset.data.__meta__.state == :loaded, do: :updated, else: :created
ExAudit.Tracking.track_change(module, adapter, state, changeset, resulting_struct, opts)

_ ->
:ok
end

result
end)
end

def delete(module, adapter, struct, opts) do
Expand Down Expand Up @@ -79,9 +91,13 @@ defmodule ExAudit.Schema do
end

def insert_or_update!(module, adapter, changeset, opts) do
# TODO
opts = augment_opts(opts)
Ecto.Repo.Schema.insert_or_update!(module, adapter, changeset, opts)
augment_transaction(module, fn ->
result = Ecto.Repo.Schema.insert_or_update!(module, adapter, changeset, opts)
state = if changeset.data.__meta__.state == :loaded, do: :updated, else: :created
ExAudit.Tracking.track_change(module, adapter, state, changeset, result, opts)
result
end, true)
end

def delete!(module, adapter, struct, opts) do
Expand Down Expand Up @@ -132,4 +148,4 @@ defmodule ExAudit.Schema do
end ++ custom_fields
end)
end
end
end
22 changes: 12 additions & 10 deletions lib/repo/schema_type.ex
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
defmodule ExAudit.Type.Schema do
@behaviour Ecto.Type

@schemas Application.get_env(:ex_audit, :tracked_schemas, [])

def cast(schema) when is_atom(schema) do
case schema do
schema when schema in @schemas -> {:ok, schema}
case Enum.member?(schemas(), schema) do
true -> {:ok, schema}
_ -> :error
end
end
end

def cast(schema) when is_binary(schema) do
Expand All @@ -24,17 +22,21 @@ defmodule ExAudit.Type.Schema do
end

def dump(schema) do
case schema do
schema when schema in @schemas -> {:ok, schema.__schema__(:source)}
case Enum.member?(schemas(), schema) do
true -> {:ok, schema.__schema__(:source)}
_ -> :error
end
end
end

defp get_schema_by_table(table) do
Enum.find(@schemas, fn schema ->
schemas() |> Enum.find(fn schema ->
schema.__schema__(:source) == table
end)
end

def type, do: :string
end

defp schemas do
Application.get_env(:ex_audit, :tracked_schemas, [])
end
end
15 changes: 10 additions & 5 deletions lib/tracking/tracking.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
defmodule ExAudit.Tracking do
@version_schema Application.get_env(:ex_audit, :version_schema)
@tracked_schemas Application.get_env(:ex_audit, :tracked_schemas)

import Ecto.Query

def find_changes(action, struct_or_changeset, resulting_struct) do
Expand All @@ -24,7 +21,7 @@ defmodule ExAudit.Tracking do
def compare_versions(action, old, new) do
schema = Map.get(old, :__struct__, Map.get(new, :__struct__))

if schema in @tracked_schemas do
if schema in tracked_schemas() do
assocs = schema.__schema__(:associations)

patch = ExAudit.Diff.diff(
Expand Down Expand Up @@ -73,7 +70,7 @@ defmodule ExAudit.Tracking do
case changes do
[] -> :ok
_ ->
Ecto.Repo.Schema.insert_all(module, adapter, @version_schema, changes, opts)
Ecto.Repo.Schema.insert_all(module, adapter, version_schema(), changes, opts)
end
end

Expand Down Expand Up @@ -104,4 +101,12 @@ defmodule ExAudit.Tracking do

insert_versions(module, adapter, deleted_structs, opts)
end

defp tracked_schemas do
Application.get_env(:ex_audit, :tracked_schemas)
end

defp version_schema do
Application.get_env(:ex_audit, :version_schema)
end
end
22 changes: 12 additions & 10 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
%{
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"},
"certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"decimal": {:hex, :decimal, "1.4.1", "ad9e501edf7322f122f7fc151cce7c2a0c9ada96f2b0155b8a09a795c2029770", [:mix], [], "hexpm"},
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.0", "17f0c38eaafb4800f746b457313af4b2442a8c2405b49c645768680f900be603", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.6", "3fd1067661d6d64851a0d4db9acd9e884c00d2d1aa41cc09da687226cf894661", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"ecto": {:hex, :ecto, "2.2.11", "4bb8f11718b72ba97a2696f65d247a379e739a0ecabf6a13ad1face79844791c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.7.4", "3d84b2f15a0e593159f74b19f83794b464b34817183d27965bdc6c462de014f9", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.10.3", "b090a3fbcb3cfa136f0427d038c92a9051f840953ec11b40ee74d9d4eac04d1e", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
"makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
}
66 changes: 66 additions & 0 deletions test/ex_audit_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,72 @@ defmodule ExAuditTest do
assert version.actor_id == user.id
end

test "should track insert_or_update!" do
user = Repo.insert_or_update!(User.changeset(%User{}, %{name: "Admin", email: "admin@example.com"}))
user = Repo.insert_or_update!(User.changeset(user, %{name: "SuperAdmin", email: "admin@example.com"}))


created = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
where: v.action == ^:created)

updated = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
where: v.action == ^:updated)

assert 2 = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
select: count(v.id))

assert %{
email: {:added, "admin@example.com"},
inserted_at: {:added, _},
name: {:added, "Admin"},
updated_at: {:added, _}
} = created.patch

assert patch: %{
name: {:changed, {:primitive_change, "Admin", "SuperAdmin"}},
updated_at: {:changed, _}
} = updated.patch
end

test "should track insert_or_update" do
{:ok, user} = Repo.insert_or_update(User.changeset(%User{}, %{name: "Admin", email: "admin@example.com"}))
{:ok, user} = Repo.insert_or_update(User.changeset(user, %{name: "SuperAdmin", email: "admin@example.com"}))


created = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
where: v.action == ^:created)

updated = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
where: v.action == ^:updated)

assert 2 = Repo.one(from v in Version,
where: v.entity_id == ^user.id,
where: v.entity_schema == ^User,
select: count(v.id))

assert %{
email: {:added, "admin@example.com"},
inserted_at: {:added, _},
name: {:added, "Admin"},
updated_at: {:added, _}
} = created.patch

assert patch: %{
name: {:changed, {:primitive_change, "Admin", "SuperAdmin"}},
updated_at: {:changed, _}
} = updated.patch
end

test "should track custom data from plugs or similar" do
user = Repo.insert!(User.changeset(%User{}, %{name: "Admin", email: "admin@example.com"}))

Expand Down

0 comments on commit ac7446b

Please sign in to comment.