Erlang确定记录是否有字段

时间:2014-04-30 21:48:56

标签: functional-programming erlang otp mnesia

我正在更新我保留在mnesia中的记录架构。新架构包含一个新字段,我希望在通过id读取记录后,检查记录是否包含该字段,如果没有,则将记录更新为新架构。

所以,例如我们的旧记录是这样的:

-record(cust,{id,name,street_address,city,state,zip})。

新记录添加了字段street_address2:

-record(cust,{id,name,street_address,street_address2,city,state,zip})。

我希望能够即时升级现有记录的架构。要使用当前逻辑执行此操作,我需要按id查找记录,检查记录是否存在address_line2字段。如果它不存在,将其设置为未定义的原子并保存回mnesia。出于某种原因,我很难找到一个好方法来做到这一点。

任何指导都将不胜感激。

2 个答案:

答案 0 :(得分:3)

根据Ulf Wiger在https://groups.google.com/forum/#!topic/erlang-programming/U6Q0-_Usb50的回复,您需要使用mnesia:transform_table(Tab, Fun, NewAttributeList)电话转换表格。

http://erldocs.com/R16B03-1/mnesia/mnesia.html?i=1&search=mnesia#mnesia

  

此函数将参数Fun应用于表中的所有记录。 Fun是一个函数,它记录旧类型并返回新类型的转换记录。

答案 1 :(得分:2)

亚历克斯是对的。以下是使用transform_table进行描述的示例:

-record(cust, {id, name, street_address, street_address2, city, state, zip}). % This should be the record definition

mnesia:transform_table(
 cust, 
 fun({cust,
           Id,
           Name,
           StreetAddress,
           City,
           State,
           Zip
      }) ->
      {cust,
           Id,
           Name,
           StreetAddress,
           undefined, % This is setting it to the atom undefined.  You could also do "", or anything you want.
           City,
           State,
           Zip
      }
 end,
 record_info(fields, cust)
).

第一个元组中的变量(Id,Name,StreetAddress等)会从现有记录中自动设置。然后将记录转换为第二个元组(fun的返回),使用这些设置变量来分配新值。此过程适用于表中的每个现有记录。

请记住,该功能在任何方面都不是神奇的,所以你可以在那里做任何你需要做的事情,例如检查id​​或其他什么。但是,只需在记录中添加一个字段,就可以像我在这里看到的那样。

如果您是从控制台进行操作,请务必使用rr()或其他内容加载记录定义。

以下是transform_table的文档:http://www.erlang.org/doc/man/mnesia.html#transform_table-3