Как я могу заставить: mnesia.select работать в эликсире?

У меня есть таблица мнезии, определенная для использования в проекте эликсира.

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"}]}]}

Как видно из приведенного выше листинга, элементы таблицы состоят из двухкортежного ключа и списка карт.

Такой запрос на совпадение работает нормально:

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"}]}]}

Но когда я пытаюсь сделать что-то подобное, я вижу ошибку badarg:

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}}}], [:"$$"]}]]}}

Похоже, что ссылка на ключ кортежа в предложении защиты приводит к ошибкам - например, я могу получить результаты, используя бессмысленные [{:>,: "$ 1", 0}] -, но я просто не видя, что здесь не так.

Я хотел бы, чтобы этот простой запрос с использованием: mnesia.select/2 работал, чтобы я мог использовать его и разработать более сложные запросы. Будем очень благодарны любой помощи.


person wnorman    schedule 13.02.2017    source источник


Ответы (1)


У меня есть только беглый опыт работы с мнезией, но похоже, что MatchHead должен быть структурой / записью (а не атомом, называющим таблицу, как в вашем примере). См. «Использование функций Mnesia» в документации mnesia: начало работы.

Итак, ваш выбор, вероятно, должен выглядеть так:

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

что объясняет {:badarg, [:todo_lists, [{{:todo_lists, :"$1", :"$2"} ... ошибку относительно второго появления: todo_lists.

person kmptkp    schedule 13.02.2017
comment
Да, имя таблицы неудачное. И ваше предложение подойдет для приложения на Erlang, но это Elixir, где я использую позиционные параметры, а не записи. Но чтобы показать имя таблицы и базовый синтаксис, который я использовал выше, ОК, я создаю простую таблицу: todo_lists в новом сеансе iex. Это отлично работает - `: mnesia.select (: todo_lists, [{{: todo_lists,: $ 1,: $ 2}, [{: ==,: $ 1, 20170201}], [: $$]}]) {: atomic, [[20170201, другая задача]]} `-, что заставляет меня подозревать, что проблема здесь, скорее всего, связана с ключом из двух кортежей из моего исходного примера. - person wnorman; 15.02.2017