Kalai Vannan
Kalai Vannan

Reputation: 1

Mnesia - Check for a value in either of the keys in the table

I have a mnesia table "users" created with the following record

-record(users,{username,nickname,age})

Let's say i have the mnesia table like the following records

users | username | nickname | age

users | John     | baddy    | 25 

users | Monk     | John     | 26

I have a name to match with the table...(Say "John")..I want to select or match the rows which has "John" either as username or nickname...How can i achieve this? If someone can suggest me a way, i will be really happy...

Thanks

Upvotes: 0

Views: 496

Answers (4)

Tesfaye Yimam
Tesfaye Yimam

Reputation: 1

I have a table of the form below.

NB: the module name of this Erlang script is <candidates_server.erl>

-record(candidates,{
  name,
  surname,
  contestid,
  tally
}).

I wanted to read the number of records(rows) given the contestid. I have constructed a function like this one:

%-spec(read_a_candidate (Contestid::binary()) ->  {succeed,{Records_counter :: pos_integer(), Records_list :: list(map())}}).%
read_a_candidate(Contestid) ->
  F = fun() ->
    Record = #candidates{ contestid = Contestid,  _ = '_' },
    mnesia:select(candidates, [{Record, [], ['$_']}])
                      end,
  {atomic,ResultList}=mnesia:activity(transaction,F),
  {succeed,length(ResultList),ResultList}.

  1. First, don't forget to compile your .erl code to .beam like this.

         $ erlc *.erl 
    
  2. Run the the Erlang shell by

     $ erl -mnesia dir '"./dir/to/file/path"' -pa /ebin -name\
      [email protected] -setcookie 'candidates_secret_cookie' -kernel\     
      candidates_server init shell_history enabled
    
  3. Here is the screen-shot of the Erlang shell: enter image description here

Upvotes: 0

BlackMamba
BlackMamba

Reputation: 10254

-module(wy).
-compile(export_all).

-record(users, {username, nickname, age}).
-include_lib("stdlib/include/ms_transform.hrl").

create_table()->
    mnesia:create_schema(node()),
    mnesia:start(),
    mnesia:create_table(users, [{attributes, record_info(fields, users)}]).

test()->
    Fun = fun()->
              mnesia:write(#users{username = "John", nickname = "baddy", age = 25}),
              mnesia:write(#users{username = "DaDa", nickname = "KaKa", age = 24}),
              mnesia:write(#users{username = "Monk", nickname = "John", age = 24})
          end,
    mnesia:transaction(Fun),

    Fun2 = ets:fun2ms(fun({users, UserName, NickName, Age}) when
                       UserName == "John" orelse NickName == "John" ->
                            {users, UserName, NickName, Age}
                  end), 

    mnesia:transaction(fun() -> mnesia:select(users, Fun2) end).

Upvotes: 2

Muzaaya Joshua
Muzaaya Joshua

Reputation: 7836

select(Q)->
    case mnesia:is_transaction() of
        false -> 
            F = fun(QH)-> qlc:e(QH) end,
            mnesia:activity(transaction,F,[Q],mnesia_frag);
        true -> qlc:e(Q)
    end.

read_by_name_or_nickname(Name)->
    Data = select(qlc:q([X || X <- mnesia:table(users),
        ((X#users.username == Name) orelse (X#users.nickname == Name))])),
    Data.

Upvotes: 0

Tom H.
Tom H.

Reputation: 510

Have a look at QLC - there's a simple example here on Learn You Some Erlang, or the man page here. You can use booleans to match e.g. (in pseudocode) (username == John OR nickname == John).

Upvotes: 1

Related Questions