Question

I am updating a record schema that I keep in mnesia. The new schema contains a new field and I would like to, after reading the record by id, check to see if the record has the field and, if not, update the record to the new schema.

So, for example our old record is like so:

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

The new record adds the field street_address2:

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

I would like to be able to upgrade the schema of existing records on-the-fly. To do so with the current logic I would need to lookup the record by id, check the record for the existence of the address_line2 field. If it doesn't exist, set it to the atom undefined and save back to mnesia. For some reason I am having a hard time finding a good way to do this.

Any guidance would be appreciated.

Was it helpful?

Solution 2

Alex is correct. Here's an example of using transform_table for what you described:

-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)
).

What happens is that the variables in the first tuple (Id, Name, StreetAddress, etc) get set automatically from the existing record. Then the record is transformed into the second tuple (the fun's return), using those set variables to assign the new values. This process is applied to every existing record in the table.

Keep in mind the function isn't magical in any way, so you can do anything in there that you need to, for example checking ids or whatever. But for simply adding a field to the record, you can do it like I show here.

If you're doing it from the console, be sure to load in the record definition using rr() or something.

Here's the docs for transform_table: http://www.erlang.org/doc/man/mnesia.html#transform_table-3

OTHER TIPS

According to a reply from Ulf Wiger at https://groups.google.com/forum/#!topic/erlang-programming/U6Q0-_Usb50 you do need to transform the table using mnesia:transform_table(Tab, Fun, NewAttributeList) call.

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

This function applies the argument Fun to all records in the table. Fun is a function which takes a record of the old type and returns a transformed record of the new type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top