Erlang/OTP Forums

Author Message

<  Advanced Erlang/OTP  ~  mnesia table layout suggestion

bryan
Posted: Tue Jul 31, 2007 6:54 am Reply with quote
Joined: 15 Jul 2007 Posts: 8
In part of my program, I want to store lists of objects in mnesia. So I have these functions:
Code:
add_to_list( User, Object, List ) -> ...
retrieve_from_list( User, List ) -> ...


So I can do:
Code:
lists:add_to_list( bryan, milk, shopping ).
lists:add_to_list( bryan, eggs, shopping ).
lists:add_to_list( bryan, todo, ask_question ).

retrieve_from_list( bryan, shopping ).
[milk,eggs]


My question is about how to store this in mnesia. Currently, I have a:
Code:
-record( listitem, { key, object } ).
% where key is a tuple of a user and a list
and I am using a bag. This way, it seems that each user has her own set of lists, and she can put as many things in the lists. (There will never be the same item twice in a list, which is the way I want it, and there is no sharing of lists.)

The problem comes when I want to do queries with QLC, though, because what I want is:
Code:
qlc:q([ X#listitem.user || X <- mnesia:tables( listitem ), ... ]).
but since I don't have a 'user' field, I can't do that.

It seems one solution would be to make my:
Code:
-record(listitem, { key, user, list, item }).
with redundant information, but that seems like overkill. Is there a better way to do this? I'm wondering if there is a good way to set up my mnesia table to handle a -record(listitem, { user, list, item }) with the semantics that I want? Or should I just use the redundant information, and if I ever want to use the record outside of the function, I can transform it:
Code:

-record(dblistitem, { key, user, list, item } ).
-record(listitem, { user, list, item } ).
transform_listitem( #dblistitem{ key = {User,List}, item = Item ) ->
  #listitem{ user = User, list = List, item = Item }.


So, do you have any good ideas on the best way to handle this situation?

Thanks in advance,

Bryan
View user's profile Send private message
Jan Henry Nystrom
Posted: Tue Jul 31, 2007 9:21 am Reply with quote
User Joined: 09 Oct 2006 Posts: 28 Location: Uppsala, Sweden
bryan wrote:
In part of my program, I want to store lists of objects in mnesia. So I have these functions:

[Lots removed]

The problem comes when I want to do queries with QLC, though, because what I want is:
Code:
qlc:q([ X#listitem.user || X <- mnesia:tables( listitem ), ... ]).
but since I don't have a 'user' field, I can't do that.


You could always write
Code:
qlc:q([ element(1, X#listitem.key) || X <- mnesia:tables( listitem ), ... ]).


Another alternative would be to have the keys as record rather than a tuple and write
Code:
qlc:q([(X#listitem.key)#key.user || X <- mnesia:tables( listitem ), ... ]).


That is assuming that key is defined as
Code:
 -record(key, {user, list}).


The QLCs are rather versatile.

Jan Henry Nystrom <jan@erlang-consulting.com>
Training Manager @ Erlang Training and Consulting
www.erlang-consulting.com
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger ICQ Number
bryan
Posted: Tue Jul 31, 2007 9:30 am Reply with quote
Joined: 15 Jul 2007 Posts: 8
Ah, I wasn't even aware of the 'element( N, Tuple )' function! That helps quite a bit. In Haskell, I would have used the 'fst' function, but I didn't want to create a new function just for this situation, especially if I had to prefix it 'lists_helpers:fst' when using it in the shell. But now I know the Erlang equivalent, that should help me out. I'll give that a try when I have some more time. Thanks.
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum