-module(db_server_otp).
-export([start/0,stop/0]).
-export([write/2,read/1,delete/1,match/1]).
-export([init/1,terminate/2,handle_cast/2,handle_call/3]).
-behavior(gen_server).
%%
%% Operations & Maintenance API
%%
start() ->
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
stop() ->
gen_server:cast(?MODULE, stop).
%%
%% DB Server API
%%
write(Key, Data) ->
gen_server:call(?MODULE, {write, Key, Data}).
read(Key) ->
gen_server:call(?MODULE, {read, Key}).
delete(Key) ->
gen_server:call(?MODULE, {delete, Key}).
match(Element) ->
gen_server:call(?MODULE, {match, Element}).
%%
%% OTP gen_server Callback Functions
%%
init(_Arguments) ->
{ok, []}.
terminate(_Reason, _LoopData) ->
ok.
handle_cast(stop, LoopData) ->
{stop, normal, LoopData}.
handle_call({write, Key, Data}, _From, LoopData) ->
case lists:keymember(Key, 1, LoopData) of
true ->
NewLoopData = lists:keyreplace(Key, 1, LoopData, {Key, Data}),
Reply = ok;
false ->
NewLoopData = LoopData ++ [{Key, Data}],
Reply = ok
end,
{reply, Reply, NewLoopData};
handle_call({read, Key}, _From, LoopData) ->
case lists:keymember(Key, 1, LoopData) of
true ->
{_, Value} = lists:keyfind(Key, 1, LoopData),
Reply = {ok, Value};
false ->
Reply = {error, instance}
end,
{reply, Reply, LoopData};
handle_call({delete, Key}, _From, LoopData) ->
case lists:keymember(Key, 1, LoopData) of
true ->
NewLoopData = lists:keydelete(Key, 1, LoopData),
Reply = ok;
false ->
NewLoopData = LoopData,
Reply = ok
end,
{reply, Reply, NewLoopData};
handle_call({match, Element}, _From, LoopData) ->
Matches = lists:filter(
fun({_ ,Value}) ->
if
Value =:= Element -> true;
true -> false
end end,
LoopData),
Reply = get_db_keys(Matches, []),
{reply, Reply, LoopData}.
get_db_keys([], KeyList) -> KeyList;
get_db_keys(ListOfTuples, KeyList) ->
[H|T] = ListOfTuples,
{Key, _} = H,
get_db_keys(T, KeyList ++ [Key]).