timestamper/src/ts_common.erl

86 lines
2.6 KiB
Erlang
Raw Normal View History

-module(ts_common).
-export([new/1, update/1, update_record/2, list/3, order_datetimes/2]).
-include_lib("stdlib/include/qlc.hrl").
new(Record) ->
Table = element(1, Record),
% check for existing record
case mnesia:dirty_read(Table, element(2, Record)) of
% record exists
[ExistingRecord] -> {error, {record_exists, ExistingRecord}};
[] -> mnesia:dirty_write(Record)
end.
update(Record) ->
Table = element(1, Record),
Key = element(2, Record),
% look for existing record
case mnesia:dirty_read(Table, Key) of
% record does not exist, cannot update
[] -> no_record;
% record does exist, update
[ExistingRecord] ->
mnesia:dirty_write(update_record(ExistingRecord, Record))
end.
update_record(Record, UpdateData) ->
update_record(tuple_to_list(Record), tuple_to_list(UpdateData), []).
update_record([], [], Updated) -> list_to_tuple(lists:reverse(Updated));
update_record([Field|RecordFields], [FieldReplacement|UpdateData], Acc) ->
UpdatedField = case FieldReplacement of
undefined -> Field;
NewValue -> NewValue
end,
update_record(RecordFields, UpdateData, [UpdatedField|Acc]).
%% list <Length> number of records, skipping the first <Start>
list(Table, Start, Length)
when is_atom(Table) and is_integer(Start) and is_integer(Length) ->
list(qlc:q([A || A <- mnesia:table(Table)]), Start, Length);
list(Query, Start, Length) ->
{atomic, Result} = mnesia:transaction(fun() ->
% create a cursor for the query
C = qlc:cursor(Query),
% skip the first Start records
if Start > 0 -> qlc:next_answers(C, Start);
true -> ok
end,
% return Length records
List = qlc:next_answers(C, Length),
% free cursor
ok = qlc:delete_cursor(C),
List
end),
Result.
% This is somewhat ridiculous.
order_datetimes({{Y1, Mon1, D1}, {H1, Min1, S1}},
{{Y2, Mon2, D2}, {H2, Min2, S2}}) ->
% this is actually a deep-nested set of case statements, but it seems
% cleaner to keep the indentation level and follow a strict pattern
% compare field.If /=, return that value, else drop through to next field
case Y1 = Y2 of false -> Y1 > Y2; true ->
case Mon1 = Mon2 of false -> Mon1 > Mon2; true ->
case D1 = D2 of false -> D1 > D2; true ->
case H1 = H2 of flase -> H1 > H2; true ->
case Min1 = Min2 of false -> Min1 > Min2; true ->
case S1 = S2 of false -> S1 > S2; true -> true
% sec min hr day mon year
end end end end end end.