rdbms-1.2 for Erlang R6B

Ulf Wiger <>
Mon Jan 3 14:57:49 CET 2000


I have updated the rdbms user contribution, so that it now works
with the R6B release.

Some of you (assuming that any of you actually use rdbms ;) may have
successfully used rdbms-1.0 on R6B, so I thought I'd explain what
it is in 1.0 that *doesn't* work on R6B.

The functions rdbms:do_add_properties/[1,2] allow the programmer
to define properties from within a schema transaction. This has the
advantage that global properties and local properties can be defined
atomically, instead of calling mnesia:write_table_property/2 for 
each property.

However, this doesn't work with the original implementation of 
mnesia_schema.erl. Therefore, I have included a patch for 
mnesia_schema.erl. Since mnesia_schema.erl has changed since the 
last Open Source release, a new patch was needed.

Apart from this detail, the following changes have been made
(my release notes handling is deplorable -- I apologize):

- I have rewritten the implementation of register_commit_action/1 
and register_rollback_action/1 so that they work as they should, 
even in nested transactions. Quite an intriguing problem...

- rdbms exports a record -- #rdbms_obj{name, attributes}, which
  can be passed to make_object/[1,2] and make_record/1 (below)
  (unfortunately not directly to mnesia:write/1 due to an oversight;
  this is corrected in 1.3 -- on its way to erlang.org). 

- I have added the functions make_object/[1,2] and make_record/1
  to facilitate passing key-value lists to an update function.
  Thus, you can write rdbms:make_object(person, [{name,"..."}|...])
  and let rdbms return a valid record (possibly updated from an 
  existing object.)

Example: 

()1> Ps.
[{{attr,name,type},string},
 {{attr,name,required},true},
 {{attr,address,type},string},
 {{attr,phone,type},string},
 {{attr,phone,required},true}]
()2> mnesia:create_table(
			person,[{disc_copies,[node()]},
				{attributes,[name,address,phone]},
				{user_properties,Ps}]).
{atomic,ok}

()3> rdbms:make_object(person).
{rdbms_obj,person,
           [{name,string,'#.[].#'},
            {address,string,'#.[].#'},
            {phone,string,'#.[].#'}]}

()4> rdbms:make_record(person).
{person,'#.[].#','#.[].#','#.[].#'}

()5> Uffe = rdbms:make_object(person,[{name,"Uffe"},
				  		  {phone,"98195"}]).
{rdbms_obj,person,
           [{name,string,"Uffe"},
            {address,string,'#.[].#'},
            {phone,string,"98195"}]}

()6> rdbms:activity(fun() -> mnesia:write(Uffe) end).
ok

()7> ets:tab2list(person).
[{person,"Uffe",'#.[].#',"98195"}]

()8> Rec = rdbms:make_record(Uffe).
{person,"Uffe",'#.[].#',"98195"}

()9> rdbms:make_object(Rec).
{rdbms_obj,person,
           [{name,string,"Uffe"},
            {address,string,'#.[].#'},
            {phone,string,"98195"}]}


- New type: {tuples, Arity, KeyPos}; verification makes sure that
  the element is in fact a list of tuples of given arity.

- New type: oid, which constructed as {node(), erlang:now()} --
  globally and persistently unique (*). Attributes of type oid are 
  not allowed to be NULL, but make_record/1 and make_object/[1,2]
  will generate a unique oid when needed.

- New referential actions: return and ignore.
  'ignore' means exactly what it says. 'return' means that we 
  return all related objects untouched, so that the user can 
  determine what to do with them.

/Uffe

(*) As long as the node isn't restarted with the system clock
    set back significantly. With reasonably accurate timing, this
    is not a problem.

-- 
Ulf Wiger, Chief Designer AXD 301         <>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuvägen 9, Älvsjö                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44









More information about the erlang-questions mailing list