amnesia icon indicating copy to clipboard operation
amnesia copied to clipboard

foldl-like function that returns a struct

Open macabeus opened this issue 6 years ago • 1 comments

As far as I understand, if we want to run a function on each record on table (to filter, or map...), we could use the foldl/3 function.

But, it's hard to use, because the value passed to function isn't a struct, for example, if we have

defdatabase Database do
  deftable Account, [{:id, autoincrement}, :email, :account_number :amount],
  ...

and use

Amnesia.transaction do
  Database.Account.foldl([], &([&1 | &2]))
end

The return is something like [{Database.Account, 1, "[email protected]", "1", 100000, true}, {Database.Account, 2, "[email protected]", "2", 100000, true}].

A possible better return is [%Database.Account{account_number: "1", amount: 100000, email: "[email protected]", id: 1}, %Database.Account{account_number: "2", amount: 100000, email: "[email protected]", id: 2}].

Currently, I'm using a workaround to return an array of structs:

Amnesia.transaction do
  Database.Account.keys
  |> Enum.map(&Database.Account.read!/1)
end

But, maybe exists a better solution, and I think that it's useful to add on Amnesia.

macabeus avatar Feb 08 '18 23:02 macabeus

The problem is that foldl and such is supposed to allow you to play with the schema as well, for instance if you want to change a table up you'll need to do this.

Now this is undocumented, and it probably shouldn't be, but you can use Database.Account.coerce/1 to turn a tuple into a struct, and a struct into a tuple.

Keep in mind that foldl and friends are thin wrappers around mnesia functions, so you always need to coerce back and forth.

meh avatar Feb 09 '18 20:02 meh