An open API service indexing awesome lists of open source software.

https://github.com/qqwy/elixir-revisionair_ecto

A Revisionair adapter based on Ecto. Allows you to persist and keep track of revisions of your data structures in any of Ecto's supported databases.
https://github.com/qqwy/elixir-revisionair_ecto

ecto elixir-lang elixir-library revision

Last synced: 3 months ago
JSON representation

A Revisionair adapter based on Ecto. Allows you to persist and keep track of revisions of your data structures in any of Ecto's supported databases.

Awesome Lists containing this project

README

        

# RevisionairEcto

[![Hex.pm](https://img.shields.io/hexpm/v/revisionair_ecto.svg)](https://hex.pm/packages/revisionair_ecto)

A [Revisionair](https://github.com/Qqwy/elixir_revisionair) adapter based on [Ecto](https://github.com/elixir-ecto/ecto). Allows you to persist and keep track of revisions of your data structures in any of Ecto's supported databases.

The things that you want to keep track of do _not_ necessarily need to be (Ecto-backed) models/schemas. _Any_ data structure can be used (even things that are not structs).

## Installation

First, install the library by adding `revisionair_ecto` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:revisionair_ecto, "~> 1.0"}]
end
```

Then, create a migration (`mix ecto.gen.migration revisions_table`) akin to the following:

```elixir

defmodule RevisionairEcto.Repo.Migrations.RevisionsTable do
use Ecto.Migration

def change do
create table(:revisions, primary_key: false) do
add :item_type, :string, null: false
# If you want to use UUIDs instead, alter the following line to
# add :item_id, :uuid, null: false
add :item_id, :integer, null: false
# If you want to use JSON serialization instead, alter the following line to
# add :encoded_item, :json, null: false
add :encoded_item, :binary, null: false
add :metadata, :map, null: false
add :revision, :integer, null: false
end

create unique_index(:revisions, [:item_type, :item_id, :revision])
end
end
```

Finally, in your `config/config.exs`, add the following lines to configure Revisonair and RevisionairEcto:

```elixir
# Set default Revisionair storage adapter.
config :revisionair, storage: RevisionairEcto

# Default repo used by RevisionairEcto:
config :revisionair_ecto, repo: RevisionairEcto.Repo

# Uncomment if you use UUIDs instead of numerical ids:
# config :revisionair_ecto, item_id_type: :uuid

# Uncomment if you use JSON serialization instead of binary term storage:
# config :revisionair_ecto, serialization_format: :json

# Uncomment if you use a different table than "revisions" to store the revisions information:
# config :revisionair_ecto, revisions_table: "table_name"
```

Of course, any of these settings can also be specified in the `options` parameter when calling any of the Revisionair functions:

```elixir

Revisionair.store_revision(my_post, [storage: RevisionairEcto, storage_options: [repo: MyOtherRepo, revisions_table: "my_revisions", item_id_type: :uuid, serialization_format: :json]])

```

(This also allows overriding certain settings only in certain special locations.)

## Usage

The functions in this module should not be used directly, rather, the functions that the [Revisionair](https://github.com/Qqwy/elixir_revisionair) module exposes should be used.

As these function calls will hit the database directly, make sure that especially `store_revision` is used within a Repo transaction to ensure that the revision is only stored if the other database operations could be performed successfully.

Example:
```elixir

{:ok, post} = Repo.transaction fn ->
post = Repo.insert!(%Post{title: "Test", content: "Lorem ipsum"})

:ok = Revisionair.store_revision(post, Post, post.id)

# if using JSON serialization, you must also pass a whitelist of attributes you wish to serialize:
# :ok = Revisionair.store_revision(post, Post, post.id, [storage_options: [attributes: [:id, :content, :title]]])

post
end

Revisionair.newest_revision(post)
Revisionair.list_revisions(post)
Revisionair.get_revision(post, 0)
```

## Changelog

- 1.2.2 Removes unused `struct_name` column from migration examples.
- 1.2.1 Updates migration examples (in README and tests) to no longer include unneccesary primary key and superfluous index.
- 1.2.0 Adds the possibility to serialize data using a JSON format instead of the Erlang Term Format.
- 1.1.0 Upgrade to Ecto 3.
- 1.0.2 Removes superfluous and noisy logging call.
- 1.0.1 Updates Revisionair version.
- 1.0.0 First Stable Version.