aboutsummaryrefslogtreecommitdiff
path: root/apps/dreki/src/dreki_dets_tasks.erl
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dreki/src/dreki_dets_tasks.erl')
-rw-r--r--apps/dreki/src/dreki_dets_tasks.erl90
1 files changed, 90 insertions, 0 deletions
diff --git a/apps/dreki/src/dreki_dets_tasks.erl b/apps/dreki/src/dreki_dets_tasks.erl
new file mode 100644
index 0000000..9b798ef
--- /dev/null
+++ b/apps/dreki/src/dreki_dets_tasks.erl
@@ -0,0 +1,90 @@
+-module(dreki_dets_tasks).
+-include("dreki.hrl").
+
+%% Types
+-type db() :: term().
+-type args() :: #{db_name => binary()}.
+
+%% storage-specific
+-export([start/1, open/1, sync/1, close/1, stop/1]).
+-export([checkout/1, checkin/1]).
+-export([list/1, count/1, exists/2, get/2, create/2, update/2, delete/2]).
+
+-define(DETS, dreki_tasks_dets).
+
+dets_name(_Args = #{store_name := StoreName}) when is_binary(StoreName) ->
+ {dreki_dets_tasks, StoreName}.
+
+file_name(_Args = #{file_name := FileName}) when is_binary(FileName) ->
+ binary:bin_to_list(FileName);
+file_name(_Args = #{store_name := StoreName}) when is_binary(StoreName) ->
+ File = <<"tasks.", StoreName/binary, ".dets">>,
+ binary:bin_to_list(File).
+
+-spec start(args()) -> {ok, db()} | {error, Reason::term()}.
+start(Args) ->
+ dets:open_file(dets_name(Args), [{file, file_name(Args)}, {keypos, 2}]).
+
+-spec open(args()) -> {ok, db()} | {error, Reason::term()}.
+open(Args) ->
+ start(Args).
+
+-spec close(db()) -> ok | {error, Reason::term()}.
+close(Tab) ->
+ dets:close(Tab).
+
+-spec stop(args()) -> ok | {error, Reason::term()}.
+stop(Args) ->
+ Tab = dets_name(Args),
+ dets:close(Tab).
+
+sync(Tab) ->
+ dets:sync(Tab).
+
+checkout(Args) ->
+ start(Args).
+
+checkin(Tab) ->
+ dets:close(Tab).
+
+-spec list(db()) -> {ok, [dreki_task()]} | {error, Reason::term()}.
+list(Tab) ->
+ dets:foldl(fun (T, {ok, Ts}) -> {ok, [T | Ts]} end, {ok, []}, Tab).
+
+-spec count(db()) -> {ok, Count::non_neg_integer()} | {error, Reason::term()}.
+count(Tab) ->
+ dets:foldl(fun (_T, {ok, Ct}) -> {ok, Ct + 1} end, {ok, 0}, Tab).
+
+-spec exists(db(), dreki_id()) -> boolean.
+exists(Tab, Id) ->
+ dets:member(Tab, Id).
+
+-spec get(db(), dreki_id()) -> {ok, dreki_task()} | {error, {task_not_found, dreki_id()}}.
+get(Tab, Id) ->
+ case dets:lookup(Tab, Id) of
+ [] -> {error, {task_not_found, Id}};
+ [Task] -> {ok, Task}
+ end.
+
+-spec delete(db(), dreki_id()) -> ok | {error, Reason::term()}.
+delete(Tab, Id) ->
+ dets:delete(Tab, Id).
+
+-spec create(db(), dreki_task()) -> {ok, dreki_task()} | {error, Reason::term()}.
+create(Tab, Task = #dreki_task{persisted=false}) ->
+ case dets:insert_new(Tab, Task#dreki_task{persisted=true, dirty=false}) of
+ true -> {ok, Task#dreki_task{persisted=true, dirty=false}};
+ false -> {error, {task_exists, Task#dreki_task.id}};
+ {error, Error} -> {error, Error}
+ end.
+
+-spec update(db(), dreki_task()) -> {ok, dreki_task()} | {error, Reason::term()}.
+update(_Tab, Task = #dreki_task{persisted=false}) ->
+ {error, {task_not_created, Task#dreki_task.id}};
+update(_Tab, Task = #dreki_task{dirty=false}) ->
+ {ok, Task};
+update(Tab, Task = #dreki_task{persisted=true, dirty=true}) ->
+ case dets:insert(Tab, Task#dreki_task{dirty=false}) of
+ ok -> {ok, Task#dreki_task{dirty=false}};
+ {error, Error} -> {error, Error}
+ end.