Skip to content

Instantly share code, notes, and snippets.

@savonarola
Created March 13, 2009 10:44
Show Gist options
  • Save savonarola/78522 to your computer and use it in GitHub Desktop.
Save savonarola/78522 to your computer and use it in GitHub Desktop.
-module(contact_model).
-behaviour(model).
-include("contact.hrl").
description() ->
[ {rotate, 5}, {ensure, 2} ].
-define(CONTACTS_PERIOD, (1000000*60*60*24*30) ).
init(Self) ->
ets_server:start_link(contacts_cache, [set,named_table] ).
get_contacts(Self, User) ->
%model:super(Self, get_contacts, [User]) ,
case ets_server:lookup_first(contacts_cache,User) of
undef -> load_contacts(User);
Contacts -> Contacts
end.
get_contact(Self, User,ContactUser) ->
LoadedContacts = model:call(Self, load_contacts, [User]),
case lists:filter( fun({_CG,CU}) -> CU =:= ContactUser end, LoadedContacts ) of
[] -> undef;
[C|_] -> C
end.
add_to_contacts(Self, User, ContactGroup, ContactUser) ->
ets_server:delete(contacts_cache,User),
model:write(Self,User,add,{User,ContactGroup,ContactUser}).
remove_from_contacts(Self, User,ContactUser)->
ets_server:delete(contacts_cache,User),
model:write(Self,User,remove,{User,ContactUser}).
is_in_contacts(Self, User,ContactUser) ->
LoadedContacts = model:call(Self, load_contacts, [User]),
lists:any( fun({_CG,CU}) -> CU =:= ContactUser end, LoadedContacts ).
load_contacts(Self, User) ->
case ets_server:lookup_first(contacts_cache,User) of
undef ->
Res = model:read(Self, User, ?CONTACTS_PERIOD, get, User,),
Contacts = case Res of
{ok, undef} -> #contacts{user = User};
{ok, C} -> C;
_ -> #contacts{user = User}
end,
error_logger:info_msg( "contact_server:load_contacts Contacts=~p~n", [Contacts] ),
ets_server:insert(contacts_cache,{User, Contacts#contacts.contacts}),
Contacts#contacts.contacts;
CachedContacts -> CachedContacts
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Db server methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% behaviour methods
db_init_node(Self) ->
% model:super(Self, init_node),
mnesia:create_schema([node()]),
mnesia:start(),
Res = mnesia:create_table( contacts, [
{type, set},
{attributes, record_info(fields, contacts) },
{disc_only_copies, [node()]}
] ),
error_logger:info_msg("contacts_dbe:init_node create_table res: ~p~n",[Res]),
%NewSelf = model:set(Self,{Key,Value}),
{ok, Self}.
db_init(Self) ->
mnesia:start(),
{ok, Self}.
db_terminate(Self, _Reason,_Counter) ->
mnesia:stop(),
ok.
db_code_change(Self, _OldVsn, _Extra) -> Self.
% custom_methods
db_get(Self, User) ->
TrRes = mnesia:transaction( fun() ->
Res = mnesia:read({contacts,User}),
error_logger:info_msg("contacts_dbe:get read Res is ~p~n",[Res]),
case Res of
[Contacts] -> Contacts;
_ -> #contacts{user=User}
end
end ),
error_logger:info_msg("contacts_dbe:get Res is ~p~n",[TrRes]),
UserContacts = case TrRes of
{atomic,C} -> C;
_ -> undef
end
{ok, UserContacts, Self}.
db_set(Self, User) ->
mnesia:transaction( fun() -> mnesia:write(Param) end ),
{ok, Self}.
db_add(Self, User, ContactGroup, ContactUser) ->
{} = Param,
Res = mnesia:transaction( fun() ->
OldContacts = case mnesia:read({contacts,User}) of
[C] -> C;
_ -> #contacts{user=User}
end,
AlreadyAdded = lists:any( fun({_Gr,C}) -> C =:= ContactUser end, OldContacts#contacts.contacts ),
if
not AlreadyAdded ->
NewContacts = OldContacts#contacts{ contacts=[{ContactGroup,ContactUser} | OldContacts#contacts.contacts] },
mnesia:write(NewContacts),
NewContacts;
true -> OldContacts
end
end ),
error_logger:info_msg("contacts_dbe:get Res is ~p~n",[Res]),
{ok, Self}.
db_remove(Self, User, ContactUser) ->
mnesia:transaction( fun() ->
case mnesia:read({contacts,User}) of
[OldContacts] ->
IsAdded = lists:any( fun({_Gr,C}) -> C =:= ContactUser end, OldContacts#contacts.contacts ),
if
IsAdded ->
NewContacts = OldContacts#contacts{ contacts = lists:filter( fun({_Gr,C}) -> C =/= ContactUser end, OldContacts#contacts.contacts ) },
mnesia:write(NewContacts);
true -> nope
end;
_ -> nope
end
end ),
{ok, Self}.
resolve(RequestName, Param, Replies) ->
case RequestName of
get ->
AllContacts = lists:append( lists:map( fun(C) -> C#contacts.contacts end, Replies ) ),
Dict = dict:from_list( lists:map( fun({G,C}) -> {C,G} end, AllContacts ) ),
#contacts{ user=Param, contacts=lists:map( fun({C,G}) -> {G,C} end, dict:to_list( Dict ) ) };
_ ->
error
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment