diff options
Diffstat (limited to 'learn-you-some-erlang/mafiapp-1.0.1/src/mafiapp.erl')
-rw-r--r-- | learn-you-some-erlang/mafiapp-1.0.1/src/mafiapp.erl | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/learn-you-some-erlang/mafiapp-1.0.1/src/mafiapp.erl b/learn-you-some-erlang/mafiapp-1.0.1/src/mafiapp.erl new file mode 100644 index 0000000..f40ebce --- /dev/null +++ b/learn-you-some-erlang/mafiapp-1.0.1/src/mafiapp.erl @@ -0,0 +1,142 @@ +-module(mafiapp). +-behaviour(application). +-include_lib("stdlib/include/ms_transform.hrl"). +-include_lib("stdlib/include/qlc.hrl"). +-export([start/2, stop/1]). +-export([install/1]). +-export([add_friend/4, friend_by_name/1, friend_by_expertise/1, + add_service/4, debts/1]). +-export([add_enemy/2, find_enemy/1, enemy_killed/1]). + + +-record(mafiapp_friends, {name, + contact=[], + info=[], + expertise}). +-record(mafiapp_services, {from, + to, + date, + description}). +-record(mafiapp_enemies, {name, + info=[]}). + +start(normal, []) -> + mnesia:wait_for_tables([mafiapp_friends, + mafiapp_services, + mafiapp_enemies], 5000), + mafiapp_sup:start_link(). + +stop(_) -> ok. + +install(Nodes) -> + ok = mnesia:create_schema(Nodes), + rpc:multicall(Nodes, application, start, [mnesia]), + mnesia:create_table(mafiapp_friends, + [{attributes, record_info(fields, mafiapp_friends)}, + {index, [#mafiapp_friends.expertise]}, + {disc_copies, Nodes}]), + mnesia:create_table(mafiapp_services, + [{attributes, record_info(fields, mafiapp_services)}, + {index, [#mafiapp_services.to]}, + {disc_copies, Nodes}, + {type, bag}]), + mnesia:create_table(mafiapp_enemies, + [{attributes, record_info(fields, mafiapp_enemies)}, + {disc_copies, Nodes}, + {local_content, true}]), + rpc:multicall(Nodes, application, stop, [mnesia]). + +add_friend(Name, Contact, Info, Expertise) -> + F = fun() -> + mnesia:write(#mafiapp_friends{name=Name, + contact=Contact, + info=Info, + expertise=Expertise}) + end, + mnesia:activity(transaction, F). + +friend_by_name(Name) -> + F = fun() -> + case mnesia:read({mafiapp_friends, Name}) of + [#mafiapp_friends{contact=C, info=I, expertise=E}] -> + {Name,C,I,E,find_services(Name)}; + [] -> + undefined + end + end, + mnesia:activity(transaction, F). + +friend_by_expertise(Expertise) -> + F = fun() -> + qlc:eval(qlc:q( + [{Name,C,I,E,find_services(Name)} || + #mafiapp_friends{name=Name, + contact=C, + info=I, + expertise=E} <- mnesia:table(mafiapp_friends), + E =:= Expertise])) + end, + mnesia:activity(transaction, F). + +%% Adding validation is left to the reader +add_service(From, To, Date, Description) -> + F = fun() -> + case mnesia:read({mafiapp_friends, From}) =:= [] orelse + mnesia:read({mafiapp_friends, To}) =:= [] of + true -> + {error, unknown_friend}; + false -> + mnesia:write(#mafiapp_services{from=From, + to=To, + date=Date, + description=Description}) + end + end, + mnesia:activity(transaction,F). + +debts(Name) -> + F = fun() -> + QH = qlc:q( + [if Name =:= To -> {From,1}; + Name =:= From -> {To,-1} + end || #mafiapp_services{from=From, to=To} <- + mnesia:table(mafiapp_services), + Name =:= To orelse Name =:= From]), + qlc:fold(fun({Person,N}, Dict) -> + dict:update(Person, fun(X) -> X + N end, N, Dict) + end, + dict:new(), + QH) + end, + lists:sort([{V,K} || {K,V} <- dict:to_list(mnesia:activity(transaction, F))]). + +add_enemy(Name, Info) -> + F = fun() -> mnesia:write(#mafiapp_enemies{name=Name, info=Info}) end, + mnesia:activity(transaction, F). + +find_enemy(Name) -> + F = fun() -> mnesia:read({mafiapp_enemies, Name}) end, + case mnesia:activity(transaction, F) of + [] -> undefined; + [#mafiapp_enemies{name=N, info=I}] -> {N,I} + end. + +enemy_killed(Name) -> + F = fun() -> mnesia:delete({mafiapp_enemies, Name}) end, + mnesia:activity(transaction, F). + +%%%%%%%%%%%%%%% +%%% PRIVATE %%% +%%%%%%%%%%%%%%% + +find_services(Name) -> + Match = ets:fun2ms( + fun(#mafiapp_services{from=From, to=To, date=D, description=Desc}) + when From =:= Name -> + {to, To, D, Desc}; + (#mafiapp_services{from=From, to=To, date=D, description=Desc}) + when To =:= Name -> + {from, From, D, Desc} + end + ), + mnesia:select(mafiapp_services, Match). |