diff --git a/storage/src/storage.erl b/storage/src/storage.erl index 2ec65ce..83be868 100644 --- a/storage/src/storage.erl +++ b/storage/src/storage.erl @@ -53,7 +53,7 @@ file: shrink/2]). % Public record operation functions --export([delete/2, list/2, read/2, write/3, write/4]). +-export([delete/2, delete_set/2, list/2, read/2, write/3, write/4]). % Module callbacks -export([code_change/3, @@ -462,6 +462,30 @@ Spec: delete(Bucket, Key) -> gen_server:call(?MODULE, {delete, Bucket, Key}). +-doc """ +Delete a set of records based on the given metadata list. + +Spec: + +``` +-spec delete_set(Bucket, Metadata) -> ok | {error, Reason} when + Bucket :: atom(), + Metadata :: [{Key, Value}], + Key :: term(), + Value :: term(), + Reason :: term(). +``` +""". +-spec delete_set(Bucket, Metadata) -> ok | {error, Reason} when + Bucket :: atom(), + Metadata :: [{Key, Value}], + Key :: term(), + Value :: term(), + Reason :: term(). + +delete_set(Bucket, Metadata) -> + gen_server:call(?MODULE, {delete_set, Bucket, Metadata}). + -doc """ Spec: @@ -704,6 +728,20 @@ handle_call({delete, Bucket, Key}, _From, State) -> {aborted, Reason} -> {reply, {error, Reason}, State} end; +handle_call({delete_set, Bucket, Metadata}, _From, State) -> + Q = qlc:q([X || X <- mnesia:table(Bucket), filter(Metadata, X#object.metadata)]), + + F = fun() -> + Recs = qlc:e(Q), + + delete_matching(Bucket, Recs) + end, + + case mnesia:transaction(F) of + {atomic, ok} -> {reply, ok, State}; + {aborted, Reason} -> {reply, {error, Reason}, State} + end; + handle_call({write, Bucket, Key, Term}, _From, State) -> handle_call({write, Bucket, Key, Term, []}, _From, State); @@ -791,4 +829,12 @@ filter([H | T], M) -> Val =:= V -> filter(T, M); true -> false end - end. \ No newline at end of file + end. + +% +% Delete all the records in a table for every key in the list. +% +delete_matching(_Bucket, []) -> ok; +delete_matching(Bucket, [H | T]) -> + mnesia:delete(Bucket, H#object.key), + delete_matching(Bucket, T).