Skip to content

Instantly share code, notes, and snippets.

@jschoch
Created July 9, 2013 13:29
Show Gist options
  • Save jschoch/5957366 to your computer and use it in GitHub Desktop.
Save jschoch/5957366 to your computer and use it in GitHub Desktop.

Getting started:

Add the following file to ./lib/db.ex

# needed to get defdatabase and other macros
use Amnesia
 
# defines a database called Database, it's basically a defmodule with
# some additional magic
defdatabase Database do
  # this is just a forward declaration of the table, otherwise you'd have
  # to fully scope User.read in Message functions
  deftable User
 
  # this defines a table with an user_id key and a content attribute, and
  # makes the table a bag; tables are basically records with a bunch of helpers
  deftable Message, [:user_id, :content], type: :bag do
    # this isn't required, but it's always nice to spec things
    @type t :: Message[user_id: integer, content: String.t]
 
    # this defines a helper function to fetch the user from a Message record
    def user(self) do
      User.read(self.user_id)
    end
 
    # this does the same, but uses dirty operations
    def user!(self) do
      User.read!(self.user_id)
    end
  end
 
  # this defines a table with other attributes as ordered set, and defines an
  # additional index as email, this improves lookup operations
  deftable User, [:id, :name, :email], type: :ordered_set, index: [:email] do
    # again not needed, but nice to have
    @type t :: User[id: integer, name: String.t, email: String.t]
 
    # this is a helper function to add a message to the user, using write
    # on the created records makes it write to the mnesia table
    def add_message(content, self) do
      Message[user_id: self.id, content: content].write
    end
 
    # like above, but again with dirty operations, the bang methods are used
    # thorough amnesia to be the dirty counterparts of the bang-less functions
    def add_message!(content, self) do
      Message[user_id: self.id, content: content].write!
    end
 
    # this is a helper to fetch all messages for the user
    def messages(self) do
      Message.read(self.id)
    end
 
    # like above, but with dirty operations
    def messages!(self) do
      Message.read!(self.id)
    end
  end
end

run iex

iex -S mix

create the mnesia database

iex(1)> Amnesia.Schema.create
{:error, {:"nonode@nohost", {:already_exists, :"nonode@nohost"}}}
iex(2)> Amnesia.start
:ok
iex(3)> Database.create
[atomic: :ok, atomic: :ok]
iex(4)> Database.wait
:ok

Create a user by pasting the following into iex

Amnesia.transaction! do
  user = User[id: 23]
  user.add_message("yo dawg")
  user.write
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment