pknoth

pknoth

Mnesia qlc queries with filters error (:undefined_record)

Using Mnesia recently, I am trying to move from match_spec to qlc queries in order to query multiple tables at once. I am facing an error trying to apply qualifiers for filtering my results :

require Qlc

defmodule TestSchema do
  defstruct id: nil, field: nil
end

:mnesia.start()

:mnesia.create_table(:test, [
  ram_copies: [node()],
  record_name: TestSchema,
  attributes: [:id, :field],
  type: :ordered_set
])

Qlc.q("[A || A <- mnesia:table('test'), A#'TestSchema'.field == \"field 2\"]", [])

# => ** (MatchError) no match of right hand side value: {:not_ok, [error: {1, :erl_lint, {:undefined_record, :TestSchema}}]}
#  (qlc) lib/qlc.ex:183: Qlc.expr_to_handle/3

Is the syntax right ?

I a possible solution may be to declare Erlang record, Record.defrecord/2 only provide utilities to manipulate such type.

any clues ?

Marked As Solved

pknoth

pknoth

Can also use Erlang records as follow :slight_smile:

require Qlc

defmodule TestSchema do
  defstruct id: nil, field: nil
end

:mnesia.start()

IO.inspect :mnesia.create_table(:test, [
  ram_copies: [node()],
  record_name: :test,
  attributes: [:id, :field],
  type: :ordered_set,
  index: [:field]
])

:mnesia.transaction fn ->
  :mnesia.write(:test, {:test, 1, "field 2"}, :write)
end

defmodule Test do
  require Qlc.Record

  Qlc.Record.defrecord(:test, [:id, :field])

  def query() do
    query = Qlc.q("[X || X <- mnesia:table(test), #{test!(X, :id)} == Field]", [Field: 1])

    IO.puts :qlc.info(query)
    :mnesia.transaction fn ->
      IO.inspect :timer.tc(fn -> Qlc.e(query) end)
    end
  end
end

Test.query()

# {:atomic, :ok}
# mnesia:table(test,
#              [{traverse,
#                {select,
#                 [{'$1',
#                   [{'==', {element, 2, '$1'}, {const, 1000000}}],
#                   ['$1']}]}},
#               {n_objects, 100},
#               {lock, read}])
# {265701, [{:test, 1000000, "field 1000000"}]}

Also Liked

hauleth

hauleth

No, it is not correct as Elixir’s structures and Erlang’s records are completely different entities. In your case you want to create record:

require Qlc

defmodule TestSchema do
  Record.defrecord(:foo, id: nil, field: nil)
end

:mnesia.start()

:mnesia.create_table(:test, [
  ram_copies: [node()],
  record_name: :foo,
  attributes: [:id, :field],
  type: :ordered_set
])

However I am not sure if it is possible to make Qlc “aware” of the :foo record in such case. Alternatively if you are using Erlang 21+ then you can do:

Qlc.q("[A || A <- mnesia:table('test'), map_get(field, A) == \"field 2\"]", [])

IIRC there was Elixir library that provided similar features as qlc but was implemented as Elixir macro, but I cannot recall it’s name right now.

pknoth

pknoth

Tried map_get/2 which don’t work, element/2 neither. It led me to a solution consisting in mnesia record pattern match.

An exemple below :slight_smile:

require Qlc

defmodule TestSchema do
  defstruct id: nil, field: nil
end

:mnesia.start()

:mnesia.create_table(:test, [
  ram_copies: [node()],
  record_name: TestSchema,
  attributes: [:id, :field],
  type: :ordered_set
])

:mnesia.transaction fn ->
  :mnesia.write(:test, {TestSchema, 1, "field 2"}, :write)
end

query = Qlc.q("[[Id, Field] || {Schema, Id, Field} <- mnesia:table('test'), Id == 1]", [])
IO.inspect :mnesia.transaction fn ->
  Qlc.e(query)
end

# => {:atomic, [[1, "field 2"]]}

Where Next?

Popular in Questions Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New

We're in Beta

About us Mission Statement