Skip to content

Commit

Permalink
some logic added
Browse files Browse the repository at this point in the history
  • Loading branch information
izelnakri committed Jul 14, 2016
1 parent 73eb8b4 commit f725ba6
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# PaperTrail

```mix papertrail.install```

PaperTrail.create/1, PaperTrail.update/1, PaperTrail.destroy/1

PaperTrail.get_version\2, PaperTrail.get_version\1 PaperTrail.get_versions\2, PaperTrail.get_versions\1

I will write some tests for this library.

**TODO: Add description**

## Installation
Expand All @@ -17,4 +25,3 @@ If [available in Hex](https://hex.pm/docs/publish), the package can be installed
def application do
[applications: [:paper_trail]]
end

90 changes: 90 additions & 0 deletions lib/paper_trail.ex
Original file line number Diff line number Diff line change
@@ -1,2 +1,92 @@
defmodule PaperTrail do
alias Ecto.Multi
import Ecto.Query
alias Model.Version

def get_versions(model, id) do
item_type = model |> Module.split |> List.last
version_query(item_type, id) |> Application.Repo.all
end

def get_versions(changeset) do
item_type = changeset.__struct__ |> Module.split |> List.last
version_query(item_type, changeset.id) |> Application.Repo.all # where id, item_type last inserted_at
end

def get_version(model, id) do
item_type = Module.split(model) |> List.last
version_query(item_type, id) |> Application.Repo.one
end

def get_version(changeset) do
item_type = changeset.__struct__ |> Module.split |> List.last
last(version_query(item_type, changeset.id)) |> Application.Repo.one # where id, item_type last inserted_at
end

defp version_query(item_type, id) do
from v in Version,
where: v.item_type == ^item_type and v.item_id == ^id
end

# changeset = Model.changeset(Ecto.Repo.get(Model, id), params)

def insert(struct, meta \\ nil) do
Multi.new
|> Multi.insert(:model, struct)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "create"}, model, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end

def update(changeset, meta \\ nil) do
Multi.new
|> Multi.update(:model, changeset)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "update"}, changeset, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end

def delete(struct, meta \\ nil) do
Multi.new
|> Multi.delete(:model, struct)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "destroy"}, model, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end

def make_version_struct(%{event: "create"}, model, meta) do
%Version{
event: "create",
item_type: model.__struct__ |> Module.split |> List.last,
item_id: model.id,
item_changes: Map.drop(model, [:__struct__, :__meta__]),
meta: meta
}
end

def make_version_struct(%{event: "update"}, changeset, meta) do
%Version{
event: "create",
item_type: changeset.data.__struct__ |> Module.split |> List.last,
item_id: changeset.data.id,
item_changes: changeset.changes,
meta: meta
}
end

def make_version_struct(%{event: "destroy"}, model, meta) do
%Version{
event: "destroy",
item_type: model.__struct__ |> Module.split |> List.last,
item_id: model.id,
item_changes: Map.drop(model, [:__struct__, :__meta__]),
meta: meta
}
end
end
33 changes: 33 additions & 0 deletions lib/version.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule Model.Version do
use Ecto.Schema

import Ecto
import Ecto.Changeset
import Ecto.Query
# how to record column changes in migration

schema "versions" do
field :event, :string
field :item_type, :string
field :item_id, :integer
field :item_changes, :map
field :meta, :map
field :originator, :string

timestamps(updated_at: false)
end

@required_fields ~w(item_type item_id event created_at)
@optional_fields ~w(meta originator)

@doc """
Creates a changeset based on the `model` and `params`.
If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end
16 changes: 16 additions & 0 deletions priv/repo/migrations/20160619190936_add_versions.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Repo.Migrations.AddVersions do
use Ecto.Migration

def change do
create table(:versions) do
add :event, :string
add :item_type, :string
add :item_id, :integer
add :item_changes, :map
add :meta, :map
add :originator, :string

add :inserted_at, :datetime, null: false
end
end
end

0 comments on commit f725ba6

Please sign in to comment.