nitinjain110588
nitinjain110588

Reputation: 177

How to Generate AUTO INCREMENT Id in Erlang Mnesia

I am trying to write records to mnesia, and I want to assign a unique Id to every record. Id needs to be auto incremented.

For instance i have a table with 3 columns - Id, Name, DOB.

Record 1 should have Id = 1, Name = Joe, DOB = 03-05-1994

Record 2 should have Id = 2, Name = Alice, DOB = 11-07-1991 and so on...

Please Help

Upvotes: 3

Views: 1175

Answers (1)

7stud
7stud

Reputation: 48589

It looks like you have to keep track of the last id by hand. You can create a table_ids table which keeps track of the last id used when inserting a record in a given table. The table_ids table can be used to separately track the last id used in all your different tables.

According to the mnesia docs, rather than doing the math yourself by reading the last id for a table from the table_ids table, then incrementing the last id, then writing the last id back to the table_ids table, instead you should simply call mnesia:dirty_update_counter(). Here's an example:

-module(my).
-compile(export_all).
-include_lib("stdlib/include/qlc.hrl"). 

-record(person, {id, name, age}).
-record(table_id, {table_name, last_id}).

init() ->
    mnesia:create_schema([node()]),
    mnesia:start(),

    {atomic, ok} = mnesia:create_table(people, [ 
       {record_name, person},
       {attributes, record_info(fields, person)}
    ]),

    {atomic, ok} = mnesia:create_table(table_ids, [
       {record_name, table_id},
       {attributes, record_info(fields, table_id)}
    ]).

start_counter(TableName) ->
    Fun = fun() ->
                mnesia:write(table_ids, 
                  #table_id{table_name=TableName, last_id=0}, 
                  write
                )
          end,
    {atomic, ok} = mnesia:transaction(Fun).



insert(Name, Age) ->
    Index = mnesia:dirty_update_counter(table_ids, people, 1),
    Fun = fun() ->
                mnesia:write(people,
                    #person{id=Index, name=Name, age=Age},
                    write
                )
          end,
    {atomic, ok} = mnesia:transaction(Fun).

select_all() -> 
    {atomic, People} = mnesia:transaction(
         fun() ->
              qlc:eval(
                qlc:q([X || X <- mnesia:table(people)])
              )
         end
    ),
    People.

In iex:

~/erlang_programs/mnesia$ rm -rf Mnesia.nonode\@nohost/

~/erlang_programs/mnesia$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(my).                   
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}

2> my:init().               
{atomic,ok}

3> my:start_counter(people).
{atomic,ok}

4> my:insert("Joe", 22).    
{atomic,ok}

5> my:insert("Sue", 31).    
{atomic,ok}

6> my:select_all().         
[{person,1,"Joe",22},{person,2,"Sue",31}]

7> mnesia:stop().           
stopped

8> 
=INFO REPORT==== 9-Jan-2019::23:30:02 ===
    application: mnesia
    exited: stopped
    type: temporary

(Hit Return to get back to prompt)
8> 

Upvotes: 3

Related Questions