Skip to content

Commit

Permalink
Merge pull request #266 from inaka/cabol.265.refactor_sumo_find_by
Browse files Browse the repository at this point in the history
Cabol.265.refactor_sumo_find_by
  • Loading branch information
Brujo Benavides authored Sep 7, 2016
2 parents 6c06000 + d3a65cd commit 9c67616
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 65 deletions.
6 changes: 3 additions & 3 deletions examples/blog/src/blog.erl
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ find_authors_by_name(Name, Limit, Offset) ->
%% @doc Finds a post given the id.
-spec find_post(blog_post:id()) -> blog_post:post()|notfound.
find_post(Id) ->
sumo:find(post, Id).
sumo:fetch(post, Id).

%% @doc Finds an author, given the id.
-spec find_author(blog_author:id()) -> blog_author:author()|notfound.
find_author(Id) ->
sumo:find(author, Id).
sumo:fetch(author, Id).

%% @doc Find a reader, given the id.
-spec find_reader(blog_reader:id()) -> blog_reader:reader()|notfound.
find_reader(Id) ->
sumo:find(reader, Id).
sumo:fetch(reader, Id).

%% @doc Returns all available posts.
-spec total_posts() -> non_neg_integer().
Expand Down
9 changes: 5 additions & 4 deletions src/adapter_test_helpers/sumo_basic_test_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ find(Config) ->
Module = sumo_config:get_prop_value(Name, module),

[First, Second | _] = sumo:find_all(Name),
First = sumo:find(Name, Module:id(First)),
Second = sumo:find(Name, Module:id(Second)),
notfound = sumo:find(Name, 0),
First = sumo:find_one(Name, [{id, Module:id(First)}]),
Second = sumo:fetch(Name, Module:id(Second)),
notfound = sumo:fetch(Name, 0),
notfound = sumo:find_one(Name, [{id, 0}]),
ok.

-spec find_all(config()) -> ok.
Expand Down Expand Up @@ -141,7 +142,7 @@ check_proper_dates(Config) ->
Module = sumo_config:get_prop_value(Name, module),

[P0] = sumo:find_by(Name, [{name, <<"A">>}]),
P1 = sumo:find(Name, Module:id(P0)),
P1 = sumo:fetch(Name, Module:id(P0)),
[P2 | _] = sumo:find_all(Name),

{Date, _} = calendar:universal_time(),
Expand Down
16 changes: 16 additions & 0 deletions src/adapters/sumo_store_mnesia.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
init/1,
create_schema/2,
persist/2,
fetch/3,
delete_by/3,
delete_all/2,
find_all/2, find_all/5,
Expand Down Expand Up @@ -81,6 +82,21 @@ persist(Doc, State) ->
{ok, NewDoc, State}
end.

-spec fetch(DocName, Id, State) -> Response when
DocName :: sumo:schema_name(),
Id :: sumo:field_value(),
State :: state(),
Response :: sumo_store:result(sumo_internal:doc(), state()).
fetch(DocName, Id, State) ->
try
[Result] = mnesia:dirty_read(DocName, Id),
Schema = sumo_internal:get_schema(DocName),
Fields = schema_field_names(Schema),
{ok, wakeup(result_to_doc(Result, Fields)), State}
catch
_:_ -> {error, notfound, State}
end.

-spec delete_by(sumo:schema_name(), sumo:conditions(), state()) ->
sumo_store:result(sumo_store:affected_rows(), state()).
delete_by(DocName, Conditions, State) ->
Expand Down
113 changes: 55 additions & 58 deletions src/sumo.erl
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@
%%% API for standard CRUD functions.
-export([
persist/2,
fetch/2,
find_one/2,
find_all/1, find_all/4,
find_by/2, find_by/4, find_by/5,
delete/2,
delete_by/2,
delete_all/1,
find/2,
find_all/1, find_all/4,
find_by/2, find_by/4, find_by/5,
find_one/2,
call/2, call/3
]).

Expand Down Expand Up @@ -110,33 +110,38 @@
%%% Code starts here.
%%%=============================================================================

%% @doc Returns all the configured docs.
-spec get_docs() -> [{atom(), atom()}].
get_docs() ->
{ok, Docs} = application:get_env(sumo_db, docs),
Docs.
%% @doc Creates or updates the given Doc.
-spec persist(schema_name(), UserDoc) -> UserDoc.
persist(DocName, State) ->
Module = sumo_config:get_prop_value(DocName, module),
DocMap = Module:sumo_sleep(State),
Store = sumo_config:get_store(DocName),
case sumo_store:persist(Store, sumo_internal:new_doc(DocName, DocMap)) of
{ok, NewDoc} ->
Ret = sumo_internal:wakeup(NewDoc),
sumo_event:dispatch(DocName, persisted, [Ret]),
Ret;
Error ->
throw(Error)
end.

%% @doc Creates the schema for all known (configured) docs.
-spec create_schema() -> ok.
create_schema() ->
lists:foreach(fun({DocName, _, _}) ->
create_schema(DocName)
end, get_docs()).
%% @doc Returns the doc identified by Id.
-spec fetch(schema_name(), field_value()) -> user_doc() | notfound.
fetch(DocName, Id) ->
Store = sumo_config:get_store(DocName),
case sumo_store:fetch(Store, DocName, Id) of
{ok, Doc} -> sumo_internal:wakeup(Doc);
{error, Reason} -> Reason
end.

%% @doc Returns 1 doc that matches the given Conditions.
-spec find_one(schema_name(), conditions()) -> user_doc() | notfound.
find_one(DocName, Conditions) ->
case find_by(DocName, Conditions, 1, 0) of
[] -> notfound;
List -> hd(List)
[] -> notfound;
[First | _] -> First
end.

%% @doc Returns the doc identified by Id.
-spec find(schema_name(), field_value()) -> user_doc() | notfound.
find(DocName, Id) ->
IdFieldName = sumo_internal:id_field_name(DocName),
find_one(DocName, [{IdFieldName, Id}]).

%% @doc Returns all docs from the given store.
-spec find_all(schema_name()) -> [user_doc()].
find_all(DocName) ->
Expand Down Expand Up @@ -201,31 +206,12 @@ find_by(DocName, Conditions, SortFields, Limit, Offset) ->
NormalizedSortFields = normalize_sort_fields(SortFields),
Store = sumo_config:get_store(DocName),
case sumo_store:find_by(
Store, DocName, Conditions, NormalizedSortFields, Limit, Offset) of
Store, DocName, Conditions, NormalizedSortFields, Limit, Offset
) of
{ok, Docs} -> docs_wakeup(Docs);
Error -> throw(Error)
end.

%% @doc Creates or updates the given Doc.
-spec persist(schema_name(), UserDoc) -> UserDoc.
persist(DocName, State) ->
IdField = sumo_internal:id_field_name(DocName),
Module = sumo_config:get_prop_value(DocName, module),
DocMap = Module:sumo_sleep(State),
EventName = case maps:get(IdField, DocMap, undefined) of
undefined -> created;
_ -> updated
end,
Store = sumo_config:get_store(DocName),
case sumo_store:persist(Store, sumo_internal:new_doc(DocName, DocMap)) of
{ok, NewDoc} ->
Ret = sumo_internal:wakeup(NewDoc),
sumo_event:dispatch(DocName, EventName, [Ret]),
Ret;
Error ->
throw(Error)
end.

%% @doc Deletes all docs of type DocName.
-spec delete_all(schema_name()) -> non_neg_integer().
delete_all(DocName) ->
Expand Down Expand Up @@ -264,6 +250,27 @@ delete_by(DocName, Conditions) ->
throw(Error)
end.

%% @doc Calls the given custom function of a store.
-spec call(schema_name(), atom()) -> term().
call(DocName, Function) ->
call(DocName, Function, []).

%% @doc Calls the given custom function of a store with the given args.
-spec call(schema_name(), atom(), [term()]) -> term().
call(DocName, Function, Args) ->
Store = sumo_config:get_store(DocName),
case sumo_store:call(Store, DocName, Function, Args) of
{ok, {docs, Docs}} -> docs_wakeup(Docs);
{ok, {raw, Value}} -> Value
end.

%% @doc Creates the schema for all known (configured) docs.
-spec create_schema() -> ok.
create_schema() ->
lists:foreach(fun({DocName, _, _}) ->
create_schema(DocName)
end, get_docs()).

%% @doc Creates the schema for the docs of type DocName.
-spec create_schema(schema_name()) -> ok.
create_schema(DocName) ->
Expand All @@ -282,20 +289,6 @@ create_schema(DocName, Store) ->
throw(Error)
end.

%% @doc Calls the given custom function of a store.
-spec call(schema_name(), atom()) -> term().
call(DocName, Function) ->
call(DocName, Function, []).

%% @doc Calls the given custom function of a store with the given args.
-spec call(schema_name(), atom(), [term()]) -> term().
call(DocName, Function, Args) ->
Store = sumo_config:get_store(DocName),
case sumo_store:call(Store, DocName, Function, Args) of
{ok, {docs, Docs}} -> docs_wakeup(Docs);
{ok, {raw, Value}} -> Value
end.

%% @doc Returns a new schema.
-spec new_schema(schema_name(), [field()]) -> schema().
new_schema(Name, Fields) ->
Expand Down Expand Up @@ -326,3 +319,7 @@ normalize_sort_fields({Name, Order}) ->
[{Name, Order}];
normalize_sort_fields(SortFields) when is_list(SortFields) ->
lists:flatmap(fun normalize_sort_fields/1, SortFields).

%% @private
get_docs() ->
application:get_env(sumo_db, docs, []).
22 changes: 22 additions & 0 deletions src/sumo_store.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
start_link/3,
create_schema/2,
persist/2,
fetch/3,
delete_by/3,
delete_all/2,
find_all/2,
Expand Down Expand Up @@ -75,6 +76,11 @@
Doc :: sumo_internal:doc(),
Res :: result(sumo_internal:doc(), State).

-callback fetch(Schema, Id, State) -> Res when
Schema :: sumo:schema_name(),
Id :: sumo:field_value(),
Res :: result(sumo_internal:doc(), State).

-callback delete_by(Schema, Conditions, State) -> Res when
Schema :: sumo:schema_name(),
Conditions :: sumo:conditions(),
Expand Down Expand Up @@ -147,6 +153,15 @@ create_schema(Name, Schema) ->
persist(Name, Doc) ->
wpool:call(Name, {persist, Doc}).

%% @doc Fetch a single doc by its `Id'.
-spec fetch(Name, DocName, Id) -> Res when
Name :: atom(),
DocName :: sumo:schema_name(),
Id :: sumo:field_value(),
Res :: {ok, sumo_internal:doc()} | {error, term()}.
fetch(Name, DocName, Id) ->
wpool:call(Name, {fetch, DocName, Id}).

%% @doc Deletes the docs identified by the given conditions.
-spec delete_by(Name, DocName, Conditions) -> Res when
Name :: atom(),
Expand Down Expand Up @@ -264,6 +279,13 @@ handle_call(
{OkOrError, Reply, NewState} = Handler:persist(Doc, HState),
{reply, {OkOrError, Reply}, State#state{handler_state=NewState}};

handle_call(
{fetch, DocName, Id}, _From,
#state{handler = Handler, handler_state = HState} = State
) ->
{OkOrError, Reply, NewState} = Handler:fetch(DocName, Id, HState),
{reply, {OkOrError, Reply}, State#state{handler_state=NewState}};

handle_call(
{delete_by, DocName, Conditions}, _From,
#state{handler = Handler, handler_state = HState} = State
Expand Down

0 comments on commit 9c67616

Please sign in to comment.