Search code examples
erlanglist-comprehensionmnesia

write a Query List Comprehensions for a mnesia query


I'm trying to build a small testing app with erlang+mnesia.

I have a user table build from the #user record, as defined here:

-record(user_details, {name, password}).
-record(user, {id, details}).

then I insert a user with that function:

add_sample_data() ->
    Mat = #user{
      details = #user_details{
    name = "mat", password = "mat"
       }
     }, 
    user:insert_user(Mat),

the query [U#user.details || U <- mnesia:table(user)] return a non empty list. now I'm trying to build a query which would return a list containing zero record if there is no record with details.name matching Name or the matching record if there is one.

here is the method I use (this one works):

user_exists() ->
  Fun = fun() ->
    Query = qlc:q([
      U#user.details || 
      U <- mnesia:table(user)
    ]),
    qlc:e(Query)
  end,
  case mnesia:transaction(Fun) of
    {atomic, []} -> false;
    {atomic, [_User]} -> true
  end.

I copied some stuff from this tutorial. A similar problem is solved with mnesia:select in the mne_fun_query({sport, Sport}) method (slide 19) but now I'd like to do it with qlc.

I tried various combinations but without any success (often failed at compilation time..).

I'm really new to erlang, if you can tell which query should works and explains it a little, that would be greatly appreciated!

mat.

edit

here is one version which does not work but maybe explain my problem better

user_exists() ->
  Fun = fun() ->
    Query = qlc:q([
      U#user.details || 
      U <- mnesia:table(user), 
      U#user.details.name == "mat"     <<<<< This is the line with the problem
    ]),
    qlc:e(Query)
  end,
  case mnesia:transaction(Fun) of
    {atomic, []} -> false;
    {atomic, [_User]} -> true
  end.

and the error I have:

mathieu@evangeneer:~/projects/nopair$ make
Recompile: src/resources/user_resource
src/resources/user_resource.erl:22: syntax error before: '.'
src/resources/user_resource.erl:6: function user_exists/2 undefined make:
*** [erl] Error 1


Solution

  • On the problem line:

    U#user.details.name == "mat"
    

    You are attempting to access the user_details record but not naming it. Try...

    (U#user.details)#user_details.name == "mat"
    

    From my experience, the compiler doesn't figure out on its own that #user.details is a #user_details.