[erlang-questions] Mnesia record with composite key and QLC questions

Ulf Wiger <>
Fri May 15 11:54:13 CEST 2009


I dust off my standard response that the 'rdbms'
contrib offered a solution for this, by providing
support for compound attributes and user-defined indexing,
including the option to specify that an index value must
be unique.

Rdbms /has/ been used commercially, but I don't consider
it ready for commercial use in general. I've not done
anything on it for quite a while, since I don't perceive
any user pressure, but anyone who wants that to change is
of course welcome to contact me and argue their case.

http://ulf.wiger.net/rdbms/doc/rdbms.html
(The docs leave a lot to be desired, I know - see above.)

BR,
Ulf W

Leon de Rooij wrote:
> Hi all,
> 
> I want to store users in an mnesia database, but want the key not only  
> to be unique on username, but also on domain.
> 
> So I defined the user record as follows:
> 
> -record(user, {domain_username, params=[]})
> 
> where domain_username = {Domain, Username}
> and params = [ {Key1,Value1}, {Key2, Value2}, ... ]
> 
> I chose params to be a list because I don't know beforehand how many  
> key/value tuples will be in there.
> 
> Is this the correct way to do things ? (Instead of having domain and  
> username as standalone strings (lists) in the record and make it a bag  
> instead of a set, or for the params having a seperate table with  
> relations/foreign keys, like I would do with SQL ?)
> 
> It's also not clear to me what is the best way to search through the  
> records:
> 
> To find a user based on a param, the following function works:
> 
> Param = {"accountcode", "1234"},
> Fun = fun() -> qlc:eval(qlc:q([ U || U <- mnesia:table(user),  
> lists:member(Param, U#user.params) ])) end,
> mnesia:transaction(Fun).
> 
> That works, but can this be done more efficient ? (Searching on params  
> won't be done often, but still I'd like to know..)
> 
> Also, I'd like to be able to for example get a list of all users in a  
> certain domain, but I can't get it to work yet..
> 
> I tried this:
> 
> Domain = "test.com",
> Fun = fun() -> qlc:eval(qlc:q([ U || U <- mnesia:table(user),  
> {Domain,_} =:= U#user.domain_username ])) end,
> mnesia:transaction(Fun).
> 
> But, having an underscore for username in the tuple to match equality  
> is not allowed (compilation breaks with "variable '_' is unbound").
> 
> Then I tried using assignment operator there:
> 
> Fun = fun() -> qlc:eval(qlc:q([ U || U <- mnesia:table(user),  
> {Domain,_} = U#user.domain_username ])) end,
> 
> which does compile, but it breaks at runtime with:
> 
> =ERROR REPORT==== 15-May-2009::08:26:37 ===
> Error in process <0.31.0> with exit value: {undef, 
> [{test,get_user_by_domain,["test.com"]},{erl_eval,do_apply,5}, 
> {shell,exprs,6},{shell,eval_loop,3}]}
> 
> ** exited: {undef,[{test,get_user_by_domain,["test.com"]},
>                     {erl_eval,do_apply,5},
>                     {shell,exprs,6},
>                     {shell,eval_loop,3}]} **
> 
> Can anyone tell me what is best practice in these cases ?
> 
> Thanks and kind regards,
> 
> Leon
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions


-- 
Ulf Wiger
CTO, Erlang Training & Consulting Ltd
http://www.erlang-consulting.com



More information about the erlang-questions mailing list