erlang - Merging records for Mnesia -
i trying refactor code have software collects current status of agents in call queue. currently, each of 6 or events listen to, check in mnesia table if agent exists , change values in row depending on event or add new if agent doesn't exist. have mnesia transaction in each event , of course bunch of repeated code checking existence of agents , on.
i'm trying change there 1 function change_agent/2 call events handles me.
my problems of course records.... find no way of dynamically creating them or merging 2 of them or anything. preferably there function call like:
change_agent("001", #agent(id = "001", name = "steve")). change_agent("001", #agent(id = "001", paused = 0, talking_to = "none")).
i wrote code while ago merges 2 records. not entirely dynamic, whith macros use several records.
it works this: merge/2 function takes 2 records , converts them lists empty record reference (the record type defined @ compile time, , must be. "undynamic" part). these run through generic function merge/4 works lists , takes elements if defined, otherwise b if defined, or lastly default (which defined).
here's code (please excuse stackoverflow's poor erlang syntax highlighting):
%%%---------------------------------------------------------------------------- %%% @spec merge(recorda, recordb) -> #my_record{} %%% recorda = #my_record{} %%% recordb = #my_record{} %%% %%% @doc merges 2 #my_record{} instances. first takes precedence. %%% @end %%%---------------------------------------------------------------------------- merge(recorda, recordb) when is_record(recorda, my_record), is_record(recordb, my_record) -> list_to_tuple( lists:append([my_record], merge(tl(tuple_to_list(recorda)), tl(tuple_to_list(recordb)), tl(tuple_to_list(#my_record{})), []))). %%%---------------------------------------------------------------------------- %%% @spec merge(a, b, default, []) -> [term()] %%% = [term()] %%% b = [term()] %%% default = [term()] %%% %%% @doc merges lists `a' , `b' new list taking %%% default values `default'. %%% %%% each element of `a' , `b' compared against elements in %%% `default'. if match default, default used. if 1 %%% of them differs other , default value, element %%% chosen. if both differs, element `a' chosen. %%% @end %%%---------------------------------------------------------------------------- merge([d|atail], [d|btail], [d|dtail], to) -> merge(atail, btail, dtail, [d|to]); % if default, take d merge([d|atail], [b|btail], [d|dtail], to) -> merge(atail, btail, dtail, [b|to]); % if default, take b merge([a|atail], [_|btail], [_|dtail], to) -> merge(atail, btail, dtail, [a|to]); % otherwise take merge([], [], [], to) -> lists:reverse(to).
feel free use in way want.
Comments
Post a Comment