wnorman
wnorman

Reputation: 56

How can I get :mnesia.select to work in elixir?

I have a mnesia table defined for use in an elixir project.

iex 1> :mnesia.create_table(:todo_lists, [attributes: [:name, :list], disc_only_copies: nodes])

iex 4> :mnesia.transaction(fn ->
... 4> :mnesia.match_object({:todo_lists, :_, :_})
... 4> end)
{:atomic,
 [{:todo_lists, {"normans_list", {2017, 2, 11}},
   [%{date: {2017, 2, 11}, title: "job interview"},
    %{date: {2017, 2, 11}, title: "market"}]},
  {:todo_lists, {"obamas_list", {2017, 2, 11}},
   [%{date: {2017, 2, 11}, title: "vacation"},
    %{date: {2017, 2, 11}, title: "coding session"}]},
  {:todo_lists, {"alices_list", {2017, 2, 14}},
   [%{date: {2017, 2, 14}, title: "yoga class"}]},
  {:todo_lists, {"bills_list", {2017, 2, 11}},
   [%{date: {2017, 2, 11}, title: "business meeting"}]},
  {:todo_lists, {"bills_list", {2017, 2, 14}},
   [%{date: {2017, 2, 14}, title: "band practice"}]}]}

As you can see from the listing above, the table elements consist of a two-tuple key and a list of maps.

A match query like this works fine:

iex 13> :mnesia.transaction(fn ->
... 13> :mnesia.match_object({:todo_lists, {"bills_list", :_}, :_})
... 13> end)

{:atomic,
 [{:todo_lists, {"bills_list", {2017, 2, 11}},
   [%{date: {2017, 2, 11}, title: "business meeting"}]},
  {:todo_lists, {"bills_list", {2017, 2, 14}},
   [%{date: {2017, 2, 14}, title: "band practice"}]}]}

But when I try something like this I see the badarg error:

iex 14> :mnesia.transaction(fn ->                                                              
... 14> :mnesia.select(:todo_lists, [{{:todo_lists, :"$1", :"$2"},[{:==, :"$1", {"bills_list", {2017, 2, 14}}}], [:"$$"]}])
... 14> end)
{:aborted,
 {:badarg,
  [:todo_lists,
   [{{:todo_lists, :"$1", :"$2"}, [{:==, :"$1", {"bills_list", {2017,2,14}}}], [:"$$"]}]]}}

It appears that a reference to the tuple key in the guard clause results in a badarg -- For instance, I can get results using the nonsensical [{:>, :"$1", 0}] --, but I am just not seeing what is wrong here.

I would like to get this simple query using :mnesia.select/2 to work so I can build upon this and develop some more complex queries. Any assistance would be greatly appreciated.

Upvotes: 1

Views: 967

Answers (1)

kmptkp
kmptkp

Reputation: 158

I have only cursory experience with mnesia, but it looks like the MatchHead should be a struct/record (and not an atom naming a table, as in your example). See "Using Mnesia Functions" in the mnesia getting started docs.

So your select should probably look like:

:mnesia.select(:todo_lists, [{%YourStructHere{ ..WhateverMatch..}, Guard, Result}])

which explains the {:badarg, [:todo_lists, [{{:todo_lists, :"$1", :"$2"} ... error, wrt the second occurrence of :todo_lists.

Upvotes: 1

Related Questions