Wednesday, June 6, 2012

Erlang and mnesia example

There is an mnesia example at the following url:

http://www.erlang.org/doc/apps/mnesia/Mnesia_chap2.html#id64245

However, the example code is incomplete.

So I added copied some of the Erlang examples functions and created some new functions to use on the DB.

Some of the functions from the page below do not seem to work (all_*).

%-----------------------------------------------------------------
%company.erl
% compile in the shell with
% > c(company).
%-----------------------------------------------------------------

-module(company). 
-export([
init/0,
insert_emp/3,
mk_projs/2,
mk_project/2,
raise/2,
all_females/0,
all_males/0,
raise_females/1,
over_write/2,
read_employee/1,
read_employee_table/2,
read_emp1/2
]).

-include_lib("stdlib/include/qlc.hrl").
-include("company.hrl").

%%----------------------------------------

init()                             ->
    mnesia:create_table(employee,
                        [{attributes, record_info(fields, employee)}]),
    mnesia:create_table(dept,
                        [{attributes, record_info(fields, dept)}]),
    mnesia:create_table(project,
                        [{attributes, record_info(fields, project)}]),
    mnesia:create_table(manager, [{type, bag},
                                  {attributes, record_info(fields, manager)}]),
    mnesia:create_table(at_dep,
[{attributes, record_info(fields, at_dep)}]),
    mnesia:create_table(in_proj, [{type, bag},
                                  {attributes, record_info(fields, in_proj)}]).

%%----------------------------------------

insert_emp(Emp, DeptId, ProjNames) ->
    Ename = Emp#employee.name,
    Fun = fun() ->
                  mnesia:write(Emp),
                  AtDep = #at_dep{emp = Ename, dept_id = DeptId},
                  mnesia:write(AtDep),
                  mk_projs(Ename, ProjNames)
          end,
    mnesia:transaction(Fun).

%%----------------------------------------

mk_projs(Ename, [ProjName|Tail])   ->
    mnesia:write(#in_proj{emp = Ename, proj_name = ProjName}),
    mk_projs(Ename, Tail);
mk_projs(_, [])                    -> ok.

%%----------------------------------------

mk_project(ProjName, ProjNumber)   ->
    mnesia:write(#project{name = ProjName, number = ProjNumber}).

%%----------------------------------------

raise(Eno, Raise)                  ->
    F = fun() ->
                [E] = mnesia:read(employee, Eno, write),
                Salary = E#employee.salary + Raise,
                New = E#employee{salary = Salary},
                mnesia:write(New)
        end,
    mnesia:transaction(F).

%%----------------------------------------

all_males()                        ->
    F = fun() ->
Male = #employee{sex = male, name = '$1', _ = '_'},
mnesia:select(employee, [{Male, [], ['$1']}])
        end,
    mnesia:transaction(F).

%%----------------------------------------

all_females()                      ->
    F = fun() ->
Female = #employee{sex = female, name = '$1', _ = '_'},
mnesia:select(employee, [{Female, [], ['$1']}])
        end,
    mnesia:transaction(F).

%%----------------------------------------

raise_females(Amount)              ->
    F = fun() ->
                Q = qlc:q([E || E <- mnesia:table(employee),
                                E#employee.sex == female]),
Fs = qlc:e(Q),
                over_write(Fs, Amount)
        end,
    mnesia:transaction(F).

%%----------------------------------------

over_write([E|Tail], Amount)       ->
    Salary = E#employee.salary + Amount,
    New = E#employee{salary = Salary},
    mnesia:write(New),
    1 + over_write(Tail, Amount);
over_write([], _)                  ->   0.

%%----------------------------------------

read_employee(Eno)                  ->
Fun = fun() ->
    mnesia:read({employee,Eno})
    end,
  {atomic,[Row]}=mnesia:transaction(Fun),
  io:format("~p~n",[Row#employee.name]).

%%----------------------------------------

read_employee_table(Table,Eno) ->
    mnesia:read({Table,Eno})
    .

%read_employee_name(Eno, Table, Field) ->
%  {atomic,[Row]}=mnesia:transaction(read_employee_table(Table, Eno)),
%  io:format("~p~n",[RowTable.Field]).
%

read_emp1(Eno, Field)                  ->
Fun = fun() ->
    mnesia:read({employee,Eno})
    end,
  {atomic,[Row]}=mnesia:transaction(Fun),
  io:format("~p~n",[Row#employee.Field]).



%  io:format("~p~n",[Row#employee.emp_no]).
% mnesia:read(employee, Eno, write).

%%----------------------------------------

%Fun = fun() ->
%   mnesia:read({employee,115018})
%   end,
% {atomic,[Row]}=mnesia:transaction(Fun),
% io:format("~p~n",[Row#employee.emp_no]).




%-----------------------------------------------------------------
%company.hrl
% compile in the shell with
% > rr("company").
%-----------------------------------------------------------------

-record(employee, {emp_no,
                   name,
                   salary,
                   sex,
                   phone,
                   room_no}).

-record(dept, {id,
               name}).

-record(project, {name,
                  number}).


-record(manager, {emp,
                  dept}).

-record(at_dep, {emp,
                 dept_id}).

-record(in_proj, {emp,
                  proj_name}).

 

%-----------------------------------------------------------------
% company_sample.erl
% compile in the shell with
% > c(company_sample).
%-----------------------------------------------------------------

 erl -mnesia dir '"/tmp/Mnesia.Company"'

mnesia:create_schema([node()]).
mnesia:start().
c(company.erl).
rr("company.hrl").
company:init().
mnesia:info().

%Employees
Emp0  = #employee{emp_no = 104465, name = "Johnson Torbjorn",  salary =  1, sex = male,   phone = 99184, room_no = {242,038}}, company:insert_emp(Emp0, 'B/SFR', [otp]).
Emp1  = #employee{emp_no = 107912, name = "Carlsson Tuula",    salary =  2, sex = female, phone = 94556, room_no = {242,056}}, company:insert_emp(Emp1, 'B/SFR', [otp]).
Emp2  = #employee{emp_no = 114872, name = "Dacker Bjarne",     salary =  3, sex = male,   phone = 99415, room_no = {221,035}}, company:insert_emp(Emp2, 'B/SFR', [otp]).
Emp3  = #employee{emp_no = 104531, name = "Nilsson Hans",      salary =  3, sex = male,   phone = 99495, room_no = {222,026}}, company:insert_emp(Emp3, 'B/SFR', [otp]).
Emp4  = #employee{emp_no = 104659, name = "Tornkvist Torbjorn",salary =  2, sex = male,   phone = 99514, room_no = {222,022}}, company:insert_emp(Emp4, 'B/SFR', [otp]).
Emp5  = #employee{emp_no = 104732, name = "Wikstrom Claes",    salary =  2, sex = male,   phone = 99586, room_no = {221,015}}, company:insert_emp(Emp5, 'B/SFR', [otp]).
Emp6  = #employee{emp_no = 117716, name = "Fedoriw Anna",      salary =  1, sex = female, phone = 99143, room_no = {221,031}}, company:insert_emp(Emp6, 'B/SFR', [otp]).
Emp7  = #employee{emp_no = 115018, name = "Mattsson Hakan",    salary =  3, sex = male,   phone = 99251, room_no = {203,348}}, company:insert_emp(Emp7, 'B/SFR', [otp]).    

%company:all_females();
%company:all_males();

% %Dept
%
%         {dept, 'B/SF',  "Open Telecom Platform"}.
%         {dept, 'B/SFP', "OTP - Product Development"}.
%         {dept, 'B/SFR', "Computer Science Laboratory"}.
%     
%

% %Projects
%company:mk_project(erlang       , 1).
%company:mk_project(otp          , 2).
%company:mk_project(beam         , 3).
%company:mk_project(mnesia       , 5).
%company:mk_project(wolf         , 6).
%company:mk_project(documentation, 7).
%company:mk_project(www          , 8).

%     
%
% % The above three tables, titled employees, dept, and projects, are the tables which are made up of real records.
% % The following database content is stored in the tables which is built on relationships.
% % These tables are titled manager, at_dep, and in_proj.
%
% %Manager
%
%         {manager, 104465, 'B/SF'}.
%         {manager, 104465, 'B/SFP'}.
%         {manager, 114872, 'B/SFR'}.
%     
%
% %At_dep
%
%         {at_dep, 104465, 'B/SF'}.
%         {at_dep, 107912, 'B/SF'}.
%         {at_dep, 114872, 'B/SFR'}.
%         {at_dep, 104531, 'B/SFR'}.
%         {at_dep, 104659, 'B/SFR'}.
%         {at_dep, 104732, 'B/SFR'}.
%         {at_dep, 117716, 'B/SFP'}.
%         {at_dep, 115018, 'B/SFP'}.
%     
%
% %In_proj
%
%         {in_proj, 104465, otp}.
%         {in_proj, 107912, otp}.
%         {in_proj, 114872, otp}.
%         {in_proj, 104531, otp}.
%         {in_proj, 104531, mnesia}.
%         {in_proj, 104545, wolf}.
%         {in_proj, 104659, otp}.
%         {in_proj, 104659, wolf}.
%         {in_proj, 104732, otp}.
%         {in_proj, 104732, mnesia}.
%         {in_proj, 104732, erlang}.
%         {in_proj, 117716, otp}.
%         {in_proj, 117716, documentation}.
%         {in_proj, 115018, otp}.
%         {in_proj, 115018, mnesia}.
%     
% otp = "otp".
% Emp  = #employee{emp_no= 104732,                     
%                             name = klacke,
%                             salary = 7,
%                             sex = male,
%                             phone = 98108,
%                             room_no = {221, 015}},
%          insert_emp(Me, 'B/SFR', [otp]).