Skip to content

Commit

Permalink
Merge pull request ZennerIoT#36 from hisapy/master
Browse files Browse the repository at this point in the history
Support Ecto v3.4.2 and rewrite ExAudit.Repo to extend Ecto.Repo
  • Loading branch information
narrowtux authored Apr 20, 2020
2 parents b043339 + 1e98604 commit 7d9434b
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 222 deletions.
64 changes: 34 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,36 @@ ExAudit plugs right into your ecto repositories and hooks all the data mutating
to track changes to entities in your database.

## Features
* Wraps Ecto.Repo, no need to change your existing codebase to start tracking changes
* Creates +- diffs of the casted structs. Custom types are automatically supported.
* Ships with functions to review the history of a struct and roll back changes
* Allows custom ID types and custom fields in the version schema
* Tracks associated entities when they're created, updated or deleted in a single Repo call
* Recursively tracks cascading deletions

- Wraps Ecto.Repo, no need to change your existing codebase to start tracking changes
- Creates +- diffs of the casted structs. Custom types are automatically supported.
- Ships with functions to review the history of a struct and roll back changes
- Allows custom ID types and custom fields in the version schema
- Tracks associated entities when they're created, updated or deleted in a single Repo call
- Recursively tracks cascading deletions

## Usage

ExAudit replaces some functions in your repo module:

* `insert/2`
* `insert!/2`
* `update/2`
* `update!/2`
* `delete/2`
* `delete!/2`
- `insert/2`
- `insert!/2`
- `update/2`
- `update!/2`
- `delete/2`
- `delete!/2`

All changes to the database made with these functions will automatically be tracked.

Also, new functions are added to the repository:

* `history/2`: lists all versions of the given struct ordered from oldest to newest
* `revert/2`: rolls the referenced entity back to the state it was before the given version
was changed
- `history/2`: lists all versions of the given struct ordered from oldest to newest
- `revert/2`: rolls the referenced entity back to the state it was before the given version
was changed

With this API, you should be able to enable auditing across your entire application easily.

If for some reason ExAudit does not track a change, you can manually add it with
If for some reason ExAudit does not track a change, you can manually add it with
`ExAudit.Tracking.track_change(module, adapter, action, changeset, resulting_struct, opts)`.

In the same module, there are a few other functions you might find useful to roll custom
Expand All @@ -55,11 +55,15 @@ end

For older ecto versions than 3.2, check out what to do in the [Ecto Versions](#ecto-versions) section.

You have to hook ExAudit to your repo, by replacing `Ecto.Repo` with `ExAudit.Repo`:
You have to hook `ExAudit.Repo` to your repo:

```elixir
defmodule MyApp.Repo do
use ExAudit.Repo, otp_app: :my_app
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres

use ExAudit.Repo
end
```

Expand All @@ -70,8 +74,8 @@ You have to tell ExAudit which schemas to track and the module of your version s
In your config.exs, write something like this:

```elixir
config :ex_audit,
version_schema: MyApp.Version,
config :ex_audit,
version_schema: MyApp.Version,
tracked_schemas: [
MyApp.User,
MyApp.BlogPost,
Expand Down Expand Up @@ -134,10 +138,10 @@ defmodule MyApp.Migrations.AddVersions do
add :patch, :binary

# supports UUID and other types as well
add :entity_id, :integer
add :entity_id, :integer

# name of the table the entity is in
add :entity_schema, :string
add :entity_schema, :string

# type of the action that has happened to the entity (created, updated, deleted)
add :action, :string
Expand Down Expand Up @@ -168,7 +172,7 @@ to the `:ex_audit_custom` option in any Repo function:
MyApp.Repo.insert(changeset, ex_audit_custom: [user_id: conn.assigns.current_user.id])
```

Of course it is tedious to upgrade your entire codebase just to track the user ID for example, so you can
Of course it is tedious to upgrade your entire codebase just to track the user ID for example, so you can
also pass this data in a plug:

```elixir
Expand All @@ -184,18 +188,18 @@ defmodule MyApp.ExAuditPlug do
end
```

In the background, ExAudit.track will remember the PID it was called from and attaches the passed data to that
In the background, ExAudit.track will remember the PID it was called from and attaches the passed data to that
PID. In most cases, the conn process will call the Repo functions, so ExAudit can get the data from that PID again deeper
in the plug tree.

In some cases where it is not possible to call the Repo function from the conn process, you have to pass the
In some cases where it is not possible to call the Repo function from the conn process, you have to pass the
custom data manually via the options described above.

Examples for data you might want to track additionally:

* User ID
* API Key ID
* Message from the user describing what she changed
- User ID
- API Key ID
- Message from the user describing what she changed

## Ecto versions

Expand All @@ -213,4 +217,4 @@ For ecto 3.2, use `{:ex_audit, "~> 0.7"}`

The documentation is available at [https://hexdocs.pm/ex_audit](https://hexdocs.pm/ex_audit).

Check out [ZENNER IoT Solutions](https://zenner-iot.com/), makers of the [ELEMENT IoT platform](https://zenner-iot.com/iot-plattform).
Check out [ZENNER IoT Solutions](https://zenner-iot.com/), makers of the [ELEMENT IoT platform](https://zenner-iot.com/iot-plattform).
2 changes: 2 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ config :ex_audit, ExAudit.Test.Repo,
hostname: "localhost",
pool_size: 10

config :logger, level: :info

config :ex_audit,
ecto_repos: [ExAudit.Test.Repo],
version_schema: ExAudit.Test.Version,
Expand Down
6 changes: 5 additions & 1 deletion example/repo.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
defmodule ExAudit.Test.Repo do
use ExAudit.Repo, otp_app: :ex_audit, adapter: Ecto.Adapters.Postgres
use Ecto.Repo,
otp_app: :ex_audit,
adapter: Ecto.Adapters.Postgres

use ExAudit.Repo
end
14 changes: 9 additions & 5 deletions lib/repo/queryable.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
defmodule ExAudit.Queryable do
@version_schema Application.get_env(:ex_audit, :version_schema)

require Logger

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

@compile {:inline, version_schema: 0}

def update_all(module, queryable, updates, opts) do
Ecto.Repo.Queryable.update_all(module, queryable, updates, opts)
end
Expand All @@ -16,7 +20,7 @@ defmodule ExAudit.Queryable do

query =
from(
v in @version_schema,
v in version_schema(),
order_by: [desc: :recorded_at]
)

Expand Down Expand Up @@ -60,7 +64,7 @@ defmodule ExAudit.Queryable do

versions ++
[
struct(@version_schema, %{
struct(version_schema(), %{
id: oldest_id
})
|> Map.put(:original, empty_map_to_nil(oldest_struct))
Expand All @@ -79,7 +83,7 @@ defmodule ExAudit.Queryable do

query =
from(
v in @version_schema,
v in version_schema(),
where: v.entity_id == ^version.entity_id,
where: v.entity_schema == ^version.entity_schema,
where: v.recorded_at >= ^version.recorded_at,
Expand Down
Loading

0 comments on commit 7d9434b

Please sign in to comment.