Skip to content

Commit

Permalink
Returning the written record on operation success
Browse files Browse the repository at this point in the history
  • Loading branch information
sheharyarn committed Aug 29, 2018
1 parent 7790ff0 commit 2277a25
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 27 deletions.
28 changes: 16 additions & 12 deletions lib/memento/query/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -216,18 +216,19 @@ defmodule Memento.Query do
@doc """
Writes a Memento record to its Mnesia table.
Returns `:ok` on success, or aborts the transaction on failure.
This operatiion acquires a lock of the kind specified, which can
be either `:write` or `:sticky_write` (defaults to `:write`).
See `t:lock/0` and `:mnesia.write/3` for more details.
Returns the written record on success, or aborts the transaction
on failure. This operatiion acquires a lock of the kind specified,
which can be either `:write` or `:sticky_write` (defaults to
`:write`). See `t:lock/0` and `:mnesia.write/3` for more details.
## Autoincrement and `nil` primary keys
This method will raise an error if the primary key of the passed
Memento record is `nil` and the table does not have autoincrement
enabled. If it is enabled, this will find the last numeric key
used and increment it.
used, increment it and assign it as the primary key of the written
record (which will be returned as a result of the write operation).
To enable autoincrement, the table needs to be of the type
`ordered_set` and `autoincrement: true` has to be specified in
Expand All @@ -237,20 +238,23 @@ defmodule Memento.Query do
## Examples
```
Memento.Query.write(%Blog.Post{id: 4, title: "something", ... })
# => :ok
Memento.Query.write(%Blog.Post{title: "something", ... })
# => %Blog.Post{id: 4, title: "something"}
Memento.Query.write(%Blog.Author{username: "sye", ... })
# => :ok
# => %Blog.Author{username: "sye", ... }
```
"""
@spec write(Table.record, options) :: :ok | no_return
@spec write(Table.record, options) :: Table.record | no_return
def write(record = %{__struct__: table}, opts \\ []) do
record = prepare_record_for_write!(table, record)
record = Query.Data.dump(record)
struct = prepare_record_for_write!(table, record)
tuple = Query.Data.dump(struct)
lock = Keyword.get(opts, :lock, :write)

Mnesia.call(:write, [table, record, lock])
case Mnesia.call(:write, [table, tuple, lock]) do
:ok -> struct
term -> term
end
end


Expand Down
31 changes: 16 additions & 15 deletions test/memento/query/query_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,17 @@ defmodule Memento.Tests.Query do

test "writes the record to mnesia" do
Support.Mnesia.transaction fn ->
assert :ok = Query.write(%@table{id: :some_id, name: :some_name})
record = %@table{id: :some_id, name: :some_name}
assert record == Query.write(record)
assert [{@table, :some_id, :some_name}] = :mnesia.read(@table, :some_id)
end
end


test "overwrites a previous record with same key" do
Support.Mnesia.transaction fn ->
:ok = Query.write(%@table{id: :key, name: :old_value})
:ok = Query.write(%@table{id: :key, name: :new_value})
%{id: :key, name: :old_value} = Query.write(%@table{id: :key, name: :old_value})
%{id: :key, name: :new_value} = Query.write(%@table{id: :key, name: :new_value})

assert [{@table, :key, :new_value}] = :mnesia.read(@table, :key)
end
Expand All @@ -80,15 +81,15 @@ defmodule Memento.Tests.Query do
test "it writes as usual if a key is specified" do
Support.Mnesia.transaction! fn ->
record = %@table{id: 100, title: "Watchmen", director: "Zack Snyder", year: 2009}
assert :ok = Query.write(record)
assert %{id: 100} = Query.write(record)
end
end


test "it assigns key '1' if no existing records exist and key is nil" do
Support.Mnesia.transaction! fn ->
assert [] = Query.all(@table)
assert :ok = Query.write(%@table{title: "Watchmen"})
assert [] = Query.all(@table)
assert %{id: 1} = Query.write(%@table{title: "Watchmen"})
assert [%{id: 1}] = Query.all(@table)
end
end
Expand All @@ -98,10 +99,10 @@ defmodule Memento.Tests.Query do
Support.Mnesia.transaction! fn ->
assert [] = Query.all(@table)

assert :ok = Query.write(%@table{title: "Watchmen", id: 10})
assert :ok = Query.write(%@table{title: "Deadpool"})
assert :ok = Query.write(%@table{title: "Avengers"})
assert :ok = Query.write(%@table{title: "Ragnarok"})
assert %{id: 10} = Query.write(%@table{title: "Watchmen", id: 10})
assert %{id: 11} = Query.write(%@table{title: "Deadpool"})
assert %{id: 12} = Query.write(%@table{title: "Avengers"})
assert %{id: 13} = Query.write(%@table{title: "Ragnarok"})

assert %{id: 10, title: "Watchmen"} = Query.read(@table, 10)
assert %{id: 11, title: "Deadpool"} = Query.read(@table, 11)
Expand All @@ -115,11 +116,11 @@ defmodule Memento.Tests.Query do
Support.Mnesia.transaction! fn ->
assert [] = Query.all(@table)

assert :ok = Query.write(%@table{title: "Watchmen", id: 10})
assert :ok = Query.write(%@table{title: "Deadpool", id: :xyz})
assert :ok = Query.write(%@table{title: "Ragnarok", id: "hello"})
assert :ok = Query.write(%@table{title: "Punisher", id: -100})
assert :ok = Query.write(%@table{title: "Avengers"})
assert %{id: 10} = Query.write(%@table{title: "Watchmen", id: 10})
assert %{id: :xyz} = Query.write(%@table{title: "Deadpool", id: :xyz})
assert %{id: "hello"} = Query.write(%@table{title: "Ragnarok", id: "hello"})
assert %{id: -100} = Query.write(%@table{title: "Punisher", id: -100})
assert %{id: 11} = Query.write(%@table{title: "Avengers"})

assert %{id: 10, title: "Watchmen"} = Query.read(@table, 10)
assert %{id: 11, title: "Avengers"} = Query.read(@table, 11)
Expand Down

0 comments on commit 2277a25

Please sign in to comment.