Sakib Sami

@sakibsami

Erlang Mnesia: The Art of Remembering

September 4th 2018

Erlang is one of the oldest programming language, first appeared in 1986. The language was designed by Joe Armstrong and developed by Ericsson.

OTP (Open Telecom Protocol) comes with an embedded database named Mnesia which is written in Erlang. Currently we at Pathao is working with a Erlang based MQTT broker named EMQ. To match it with our requirements we need to do few customization within the broker through plugin support. While customizing the broker we used Mnesia database to store data. Lets see how Mnesia works.

Assume we have a record (Record is similar to object in OOP languages),

%% er_user is the name of record
-record(er_user, {
username :: binary(), % username is a binary field
password :: binary() % password is a binary field
}). % Erlang statement ends with dot

Opening Database Connection :

mnesia:create_schema([node()]).      % create database for this node
mnesia:start(). % starts database connection
mnesia:create_table(er_user,
[{disc_copies, [node()]},
{attributes,
record_info(fields, er_user)}]).
% creates table for er_user record

Data insertion :

% insert_user is a function having two parameter Username, Password
insert_user(Username, Password) ->
Insert =
fun() ->
mnesia:write(
#er_user{
username = Username,
password = Password
})
end,
{atomic, Results} = mnesia:transaction(Insert). % Transaction writes data to database. Results will return ok if success

Search Data : Lets say we are finding user by their username

find_user(Username) ->
Query =
fun() ->
mnesia:match_object({er_user, Username, '_'})
end,
{atomic, Results} = mnesia:transaction(Query).

mnesia:match_object matches data in database with given pattern. Like in above example, we are matching Username and Password could be anything as we have put ‘_’. The first value is the name of record, in above example which is er_user. The method will return array of records matching the pattern.

%%% Result from mnesia:match_object function
[{er_user,<<"123">>,<<"Abcd">>}]

If you want to find all users into database, the query will look like,

% Ignore username match as well
mnesia:match_object({er_user, '_', '_'})

Delete Data : Delete query is similar to find, the specific function is delete()

% Delete user by username
Query =
fun() ->
mnesia:delete({er_user, Username})
end,
{atomic, Results} = mnesia:transaction(Query).

For more complex search query use,

mnesia:select()

Example source code : https://github.com/s4kibs4mi/er_mnesia_test

More by Sakib Sami

More Related Stories