Reading from mnesia

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Reading from mnesia

osmuogar
Hi guys,
I am creating a chat application android - erlang.

The problem is i can't read from the table. What am i doing wrong?

-record(message,{leido, from, to, text}).

install(Nodes) ->
    mnesia:create_schema(Nodes),
    mnesia:start(),
    mnesia:create_table(
        message,
        [
            {attributes, record_info(fields, message)}
        ]
    ).

write_message(From, To, Text)->
    Trans = fun()->mnesia:write(#message{leido = false,from = From, to = To, text = Text}) end,
    mnesia:transaction(Trans).

read_message(To)->
    Trans = fun() ->  mnesia:read({message,To}) end,
    mnesia:transaction(Trans).

*leido marks if the message has been readed

Another question is i want to read only messages where leido = false, ¿how can i do it?

Thank you all

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Reading from mnesia

Martin Karlsson-2
Hi Oscar,

Lets start with looking at your record:

> -record(message,{leido, from, to, text}).

The first attribute in the record is the primary key.

The primary key of message is 'leido'. But 'leido' seems to be a
boolean which doesn't make much sense. I.e. you can only have 2
entries in your table.

You should use something else, either unique: For example a timestamp
or a combination of To/From and a timestamp or change your tables to a
bag type and use something like 'to' or a unique user id as key.

For example:
-record(message, {id, leido, from, to, text}). Where id is the message
id or something like that.


> read_message(To)->
>     Trans = fun() ->  mnesia:read({message,To}) end,
>     mnesia:transaction(Trans).

mnesia:read reads using the primary key but as the primary key is
leido not *to* you will not get anything back.

To read data out of the table you can:
*  use a known primary key (for example 'id' if that is your primary key)

* or add an index to the table (for example on to) and do an index_read

* or use other mechanisms such as qlc. (See below)


> Another question is i want to read only messages where leido = false, ¿how
> can i do it?
You can use:

* qlc (Query List Comprehensions. Which lets you filter and sort data
from mnesia tables in a SQL like manner).
* mnesia:select - A lower level utility which forces you to learn
about MatchSpecs which are handy but slightly awkward to work with ;)

with 'qlc' you'd do something like:

mnesia:transcation(qlc:e(qlc:q([M || M <- mnesia:table(message),
M#message.leido =:= false ])))

with 'select' something like:
MatchSpec =[ {#message{leido = '$1', to = '_', from = '_', text='_'},
                       [ {'=:=', '$1', false} ],
                       [ '$_']}],
mnesia:transaction(mnesia:select(message, MatchSpec))

I haven't tested the code so it may not be fully functional but
hopefully points you in the right direction.

Helpful links:

erl -man mnesia
erl -man qlc
http://learnyousomeerlang.com/mnesia
http://erlang.org/doc/apps/mnesia/users_guide.html

Hope this helps.
Cheers,
Martin
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions