diff --git a/examples/blog/src/blog_author.erl b/examples/blog/src/blog_author.erl index e22d780..0e02632 100644 --- a/examples/blog/src/blog_author.erl +++ b/examples/blog/src/blog_author.erl @@ -92,12 +92,12 @@ set(Key, Value, Author) when is_atom(Key), is_list(Author) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> author(). +-spec sumo_wakeup(sumo:model()) -> author(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(author()) -> sumo:doc(). +-spec sumo_sleep(author()) -> sumo:model(). sumo_sleep(Author) -> maps:from_list(Author). diff --git a/examples/blog/src/blog_post.erl b/examples/blog/src/blog_post.erl index 4c5f97a..d115194 100644 --- a/examples/blog/src/blog_post.erl +++ b/examples/blog/src/blog_post.erl @@ -98,12 +98,12 @@ set(Key, Value, Post) when is_atom(Key), is_list(Post) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> post(). +-spec sumo_wakeup(sumo:model()) -> post(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(post()) -> sumo:doc(). +-spec sumo_sleep(post()) -> sumo:model(). sumo_sleep(Post) -> maps:from_list(Post). diff --git a/examples/blog/src/blog_reader.erl b/examples/blog/src/blog_reader.erl index de0a4d1..e7a8bf2 100644 --- a/examples/blog/src/blog_reader.erl +++ b/examples/blog/src/blog_reader.erl @@ -88,12 +88,12 @@ set(Key, Value, Reader) when is_atom(Key), is_list(Reader) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> reader(). +-spec sumo_wakeup(sumo:model()) -> reader(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(reader()) -> sumo:doc(). +-spec sumo_sleep(reader()) -> sumo:model(). sumo_sleep(Reader) -> maps:from_list(Reader). diff --git a/examples/blog/src/blog_vote.erl b/examples/blog/src/blog_vote.erl index 45c2bdb..2b48d1b 100644 --- a/examples/blog/src/blog_vote.erl +++ b/examples/blog/src/blog_vote.erl @@ -77,12 +77,12 @@ get(Key, Vote) when is_atom(Key), is_list(Vote) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> vote(). +-spec sumo_wakeup(sumo:model()) -> vote(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(vote()) -> sumo:doc(). +-spec sumo_sleep(vote()) -> sumo:model(). sumo_sleep(Vote) -> maps:from_list(Vote). diff --git a/examples/elastic-blog/src/blog_author.erl b/examples/elastic-blog/src/blog_author.erl index 1648271..2ba10fb 100644 --- a/examples/elastic-blog/src/blog_author.erl +++ b/examples/elastic-blog/src/blog_author.erl @@ -92,12 +92,12 @@ set(Key, Value, Author) when is_atom(Key), is_list(Author) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> author(). +-spec sumo_wakeup(sumo:model()) -> author(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(author()) -> sumo:doc(). +-spec sumo_sleep(author()) -> sumo:model(). sumo_sleep(Author) -> maps:from_list(Author). diff --git a/examples/elastic-blog/src/blog_post.erl b/examples/elastic-blog/src/blog_post.erl index e80f357..0222488 100644 --- a/examples/elastic-blog/src/blog_post.erl +++ b/examples/elastic-blog/src/blog_post.erl @@ -101,12 +101,12 @@ set(Key, Value, Post) when is_atom(Key), is_list(Post) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> post(). +-spec sumo_wakeup(sumo:model()) -> post(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(post()) -> sumo:doc(). +-spec sumo_sleep(post()) -> sumo:model(). sumo_sleep(Post) -> maps:from_list(Post). diff --git a/examples/elastic-blog/src/blog_reader.erl b/examples/elastic-blog/src/blog_reader.erl index c856cf5..88629c5 100644 --- a/examples/elastic-blog/src/blog_reader.erl +++ b/examples/elastic-blog/src/blog_reader.erl @@ -88,12 +88,12 @@ set(Key, Value, Reader) when is_atom(Key), is_list(Reader) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> reader(). +-spec sumo_wakeup(sumo:model()) -> reader(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(reader()) -> sumo:doc(). +-spec sumo_sleep(reader()) -> sumo:model(). sumo_sleep(Reader) -> maps:from_list(Reader). diff --git a/examples/elastic-blog/src/blog_vote.erl b/examples/elastic-blog/src/blog_vote.erl index b98f07c..c7bbc54 100644 --- a/examples/elastic-blog/src/blog_vote.erl +++ b/examples/elastic-blog/src/blog_vote.erl @@ -77,12 +77,12 @@ get(Key, Vote) when is_atom(Key), is_list(Vote) -> %% sumo behavior follows. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Part of the sumo_doc behavior. --spec sumo_wakeup(sumo:doc()) -> vote(). +-spec sumo_wakeup(sumo:model()) -> vote(). sumo_wakeup(Data) -> maps:to_list(Data). %% @doc Part of the sumo_doc behavior. --spec sumo_sleep(vote()) -> sumo:doc(). +-spec sumo_sleep(vote()) -> sumo:model(). sumo_sleep(Vote) -> maps:from_list(Vote). diff --git a/src/adapter_test_helpers/sumo_basic_test_helper.erl b/src/adapter_test_helpers/sumo_basic_test_helper.erl index 781fead..8d2f7fb 100644 --- a/src/adapter_test_helpers/sumo_basic_test_helper.erl +++ b/src/adapter_test_helpers/sumo_basic_test_helper.erl @@ -19,26 +19,28 @@ -spec find(config()) -> ok. find(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), + Module = sumo_config:get_prop_value(Name, module), - [First, Second | _] = sumo:find_all(Module), - First = sumo:find(Module, Module:id(First)), - Second = sumo:find(Module, Module:id(Second)), - notfound = sumo:find(Module, 0), + [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), ok. -spec find_all(config()) -> ok. find_all(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), - [_, _, _, _, _, _, _, _] = sumo:find_all(Module), + [_, _, _, _, _, _, _, _] = sumo:find_all(Name), ok. -spec find_by(config()) -> ok. find_by(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), + Module = sumo_config:get_prop_value(Name, module), - Results = sumo:find_by(Module, [{last_name, <<"D">>}]), + Results = sumo:find_by(Name, [{last_name, <<"D">>}]), [_, _] = Results, SortFun = fun(A, B) -> Module:name(A) < Module:name(B) end, [First, Second | _] = lists:sort(SortFun, Results), @@ -56,8 +58,9 @@ find_by(Config) -> undefined = Module:description(First), {Today, _} = Module:created_at(First), % Check that it returns what we have inserted - [LastPerson | _NothingElse] = - sumo:find_by(Module, [{last_name, <<"LastName">>}]), + [LastPerson | _NothingElse] = sumo:find_by(Name, [ + {last_name, <<"LastName">>} + ]), <<"Name">> = Module:name(LastPerson), <<"LastName">> = Module:last_name(LastPerson), 3 = Module:age(LastPerson), @@ -72,53 +75,54 @@ find_by(Config) -> %% Check find_by ID FirstId = Module:id(First), - [First1] = sumo:find_by(Module, [{id, FirstId}]), - [First1] = sumo:find_by( - Module, [{last_name, <<"D">>}, {id, FirstId}]), - [] = sumo:find_by(Module, [{name, <<"NotB">>}, {id, FirstId}]), + [First1] = sumo:find_by(Name, [{id, FirstId}]), + [First1] = sumo:find_by(Name, [{last_name, <<"D">>}, {id, FirstId}]), + [] = sumo:find_by(Name, [{name, <<"NotB">>}, {id, FirstId}]), First1 = First, %% Check pagination - Results1 = sumo:find_by(Module, [], 3, 1), + Results1 = sumo:find_by(Name, [], 3, 1), [_, _, _] = Results1, %% This test is #177 github issue related - [_, _, _, _, _, _, _, _] = sumo:find_by(Module, []), - Robot = sumo:find_by(Module, [{name, <<"Model T-2000">>}]), + [_, _, _, _, _, _, _, _] = sumo:find_by(Name, []), + Robot = sumo:find_by(Name, [{name, <<"Model T-2000">>}]), [_] = Robot, ok. -spec delete_all(config()) -> ok. delete_all(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), - sumo:delete_all(Module), - [] = sumo:find_all(Module), + sumo:delete_all(Name), + [] = sumo:find_all(Name), ok. -spec delete(config()) -> ok. delete(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), + Module = sumo_config:get_prop_value(Name, module), %% delete_by - 2 = sumo:delete_by(Module, [{last_name, <<"D">>}]), - Results = sumo:find_by(Module, [{last_name, <<"D">>}]), + 2 = sumo:delete_by(Name, [{last_name, <<"D">>}]), + Results = sumo:find_by(Name, [{last_name, <<"D">>}]), [] = Results, %% delete - [First | _ ] = All = sumo:find_all(Module), + [First | _ ] = All = sumo:find_all(Name), Id = Module:id(First), - sumo:delete(Module, Id), - NewAll = sumo:find_all(Module), + sumo:delete(Name, Id), + NewAll = sumo:find_all(Name), [_] = All -- NewAll, ok. -spec check_proper_dates(config()) -> ok. check_proper_dates(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), + {_, Name} = lists:keyfind(name, 1, Config), + Module = sumo_config:get_prop_value(Name, module), - [P0] = sumo:find_by(Module, [{name, <<"A">>}]), - P1 = sumo:find(Module, Module:id(P0)), - [P2 | _] = sumo:find_all(Module), + [P0] = sumo:find_by(Name, [{name, <<"A">>}]), + P1 = sumo:find(Name, Module:id(P0)), + [P2 | _] = sumo:find_all(Name), {Date, _} = calendar:universal_time(), @@ -129,26 +133,27 @@ check_proper_dates(Config) -> Date = Module:birthdate(P2), {Date, {_, _, _}} = Module:created_at(P2), - Person = sumo:persist(Module, Module:new(<<"X">>, <<"Z">>, 6)), + Person = sumo:persist(Name, Module:new(<<"X">>, <<"Z">>, 6)), Date = Module:birthdate(Person), ok. --spec init_store(module()) -> ok. -init_store(Module) -> - sumo:create_schema(Module), - sumo:delete_all(Module), +-spec init_store(atom()) -> ok. +init_store(Name) -> + sumo:create_schema(Name), + Module = sumo_config:get_prop_value(Name, module), + sumo:delete_all(Name), - sumo:persist(Module, Module:new(<<"A">>, <<"E">>, 6)), - sumo:persist(Module, Module:new(<<"B">>, <<"D">>, 3)), - sumo:persist(Module, Module:new(<<"C">>, <<"C">>, 5)), - sumo:persist(Module, Module:new(<<"D">>, <<"D">>, 4)), - sumo:persist(Module, Module:new(<<"E">>, <<"A">>, 2)), - sumo:persist(Module, Module:new(<<"F">>, <<"E">>, 1)), - sumo:persist(Module, Module:new(<<"Model T-2000">>, <<"undefined">>, 7)), + sumo:persist(Name, Module:new(<<"A">>, <<"E">>, 6)), + sumo:persist(Name, Module:new(<<"B">>, <<"D">>, 3)), + sumo:persist(Name, Module:new(<<"C">>, <<"C">>, 5)), + sumo:persist(Name, Module:new(<<"D">>, <<"D">>, 4)), + sumo:persist(Name, Module:new(<<"E">>, <<"A">>, 2)), + sumo:persist(Name, Module:new(<<"F">>, <<"E">>, 1)), + sumo:persist(Name, Module:new(<<"Model T-2000">>, <<"undefined">>, 7)), {Date, _} = calendar:universal_time(), sumo:persist( - Module, + Name, Module:new( <<"Name">>, <<"LastName">>, diff --git a/src/adapter_test_helpers/sumo_conditionals_test_helper.erl b/src/adapter_test_helpers/sumo_conditionals_test_helper.erl index 95f17e7..f7d2a5c 100644 --- a/src/adapter_test_helpers/sumo_conditionals_test_helper.erl +++ b/src/adapter_test_helpers/sumo_conditionals_test_helper.erl @@ -21,36 +21,36 @@ -spec dates(config()) -> ok. dates(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("dates with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("dates with ~p", [Name]), - [_, _, _, _, _] = sumo:find_all(Module), + [_, _, _, _, _] = sumo:find_all(Name), Now = {Today, _} = calendar:universal_time(), - [] = sumo:find_by(Module, [{birthdate, '>', Today}]), - [_, _, _, _, _] = sumo:find_by(Module, [{birthdate, '==', Today}]), - [_, _, _, _, _] = sumo:find_by(Module, [{birthdate, '=<', Today}]), - [] = sumo:find_by(Module, [{created_at, '>', Now}]), - [_, _, _, _, _] = sumo:find_by(Module, [{created_at, '=<', Now}]), + [] = sumo:find_by(Name, [{birthdate, '>', Today}]), + [_, _, _, _, _] = sumo:find_by(Name, [{birthdate, '==', Today}]), + [_, _, _, _, _] = sumo:find_by(Name, [{birthdate, '=<', Today}]), + [] = sumo:find_by(Name, [{created_at, '>', Now}]), + [_, _, _, _, _] = sumo:find_by(Name, [{created_at, '=<', Now}]), ok. -spec backward_compatibility(config()) -> ok. backward_compatibility(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("backward_compatibility with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("backward_compatibility with ~p", [Name]), - [_, _, _, _, _] = sumo:find_all(Module), - [_, _, _] = sumo:find_by(Module, [{last_name, <<"Doe">>}]), - [_] = sumo:find_by(Module, [{name, <<"Jane">>}, {last_name, <<"Doe">>}]), + [_, _, _, _, _] = sumo:find_all(Name), + [_, _, _] = sumo:find_by(Name, [{last_name, <<"Doe">>}]), + [_] = sumo:find_by(Name, [{name, <<"Jane">>}, {last_name, <<"Doe">>}]), ok. -spec or_conditional(config()) -> ok. or_conditional(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("or_conditional with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("or_conditional with ~p", [Name]), - [_, _, _] = sumo:find_by(Module, + [_, _, _] = sumo:find_by(Name, {'or', [ {name, <<"John">>}, {name, <<"Joe">>}, @@ -58,7 +58,7 @@ or_conditional(Config) -> ]} ), - [_, _] = sumo:find_by(Module, [ + [_, _] = sumo:find_by(Name, [ {last_name, <<"Doe">>}, {'or', [ {name, <<"Jane">>}, @@ -69,10 +69,10 @@ or_conditional(Config) -> -spec and_conditional(config()) -> ok. and_conditional(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("and_conditional with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("and_conditional with ~p", [Name]), - [] = sumo:find_by(Module, + [] = sumo:find_by(Name, {'and', [ {name, <<"John">>}, {name, <<"Joe">>}, @@ -80,7 +80,7 @@ and_conditional(Config) -> ]} ), - [_, _] = sumo:find_by(Module, + [_, _] = sumo:find_by(Name, {'and', [ {last_name, <<"Doe">>}, {'or', [ @@ -93,77 +93,77 @@ and_conditional(Config) -> -spec not_null_conditional(config()) -> ok. not_null_conditional(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("not_null_conditional with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("not_null_conditional with ~p", [Name]), - [_, _, _] = sumo:find_by(Module, {age, 'not_null'}), - [_] = sumo:find_by(Module, {address, 'not_null'}), + [_, _, _] = sumo:find_by(Name, {age, 'not_null'}), + [_] = sumo:find_by(Name, {address, 'not_null'}), ok. -spec null_conditional(config()) -> ok. null_conditional(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("null_conditional with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("null_conditional with ~p", [Name]), - [_, _] = sumo:find_by(Module, {age, 'null'}), - [_, _, _, _] = sumo:find_by(Module, {address, 'null'}), + [_, _] = sumo:find_by(Name, {age, 'null'}), + [_, _, _, _] = sumo:find_by(Name, {address, 'null'}), ok. -spec operators(config()) -> ok. operators(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("operators with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("operators with ~p", [Name]), - [_, _] = sumo:find_by(Module, + [_, _] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '<', 100} ]} ), - [_] = sumo:find_by(Module, + [_] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '>', 100} ]} ), - [] = sumo:find_by(Module, + [] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '>', 102} ]} ), - [_] = sumo:find_by(Module, + [_] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '>=', 102} ]} ), - [_] = sumo:find_by(Module, + [_] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '<', 30} ]} ), - [_, _] = sumo:find_by(Module, + [_, _] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '=<', 30} ]} ), - [_, _, _] = sumo:find_by(Module, + [_, _, _] = sumo:find_by(Name, {'or', [ {age, 'null'}, {age, '==', 30} ]} ), - [_, _] = sumo:find_by(Module, + [_, _] = sumo:find_by(Name, {'and', [ {age, 'not_null'}, {age, '/=', 30} @@ -172,10 +172,10 @@ operators(Config) -> case sumo_utils:keyfind(people_with_like, Config, false) of true -> - [_, _, _, _] = sumo:find_by(Module, {name, 'like', <<"J%">>}), - [_, _] = sumo:find_by(Module, {'and', [{name, 'like', <<"Ja%">>}]}), - [_] = sumo:find_by(Module, {name, 'like', <<"A%">>}), - [_, _] = sumo:find_by(Module, {name, 'like', <<"%n">>}), + [_, _, _, _] = sumo:find_by(Name, {name, 'like', <<"J%">>}), + [_, _] = sumo:find_by(Name, {'and', [{name, 'like', <<"Ja%">>}]}), + [_] = sumo:find_by(Name, {name, 'like', <<"A%">>}), + [_, _] = sumo:find_by(Name, {name, 'like', <<"%n">>}), ok; false -> ok @@ -183,8 +183,8 @@ operators(Config) -> -spec deeply_nested(config()) -> ok. deeply_nested(Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - ct:comment("deeply_nested with ~p", [Module]), + {_, Name} = lists:keyfind(name, 1, Config), + ct:comment("deeply_nested with ~p", [Name]), Conditions = {'or', [ @@ -195,18 +195,19 @@ deeply_nested(Config) -> {age, 'null'}, {last_name, <<"Turing">>} ]}, - [_, _, _] = sumo:find_by(Module, Conditions), + [_, _, _] = sumo:find_by(Name, Conditions), ok. --spec init_store(module()) -> ok. -init_store(Module) -> - sumo:create_schema(Module), - sumo:delete_all(Module), - - sumo:persist(Module, Module:new(<<"Jane">>, <<"Doe">>)), - sumo:persist(Module, Module:new(<<"John">>, <<"Doe">>, 30)), - sumo:persist(Module, Module:new(<<"Jane Jr.">>, <<"Doe">>, 5)), - sumo:persist(Module, Module:new(<<"Joe">>, <<"Armstrong">>)), - sumo:persist(Module, Module:new( +-spec init_store(atom()) -> ok. +init_store(Name) -> + sumo:create_schema(Name), + Module = sumo_config:get_prop_value(Name, module), + sumo:delete_all(Name), + + sumo:persist(Name, Module:new(<<"Jane">>, <<"Doe">>)), + sumo:persist(Name, Module:new(<<"John">>, <<"Doe">>, 30)), + sumo:persist(Name, Module:new(<<"Jane Jr.">>, <<"Doe">>, 5)), + sumo:persist(Name, Module:new(<<"Joe">>, <<"Armstrong">>)), + sumo:persist(Name, Module:new( <<"Alan">>, <<"Turing">>, 102, <<"Computer St.">>)), ok. diff --git a/src/adapter_test_helpers/sumo_test_people.erl b/src/adapter_test_helpers/sumo_test_people.erl index d617c38..c034578 100644 --- a/src/adapter_test_helpers/sumo_test_people.erl +++ b/src/adapter_test_helpers/sumo_test_people.erl @@ -65,7 +65,7 @@ -spec sumo_schema() -> no_return(). sumo_schema() -> throw(should_be_implemented_by_children). --spec sumo_sleep(Person :: person()) -> sumo:doc(). +-spec sumo_sleep(Person :: person()) -> sumo:model(). sumo_sleep(Person) -> #{id => Person#person.id, name => Person#person.name, @@ -79,7 +79,7 @@ sumo_sleep(Person) -> profile_image => Person#person.profile_image, weird_field => Person#person.weird_field}. --spec sumo_wakeup(Person :: sumo:doc()) -> person(). +-spec sumo_wakeup(Person :: sumo:model()) -> person(). sumo_wakeup(Person) -> #person{ id = maps:get(id, Person), diff --git a/src/adapters/sumo_store_mnesia.erl b/src/adapters/sumo_store_mnesia.erl index e8769b7..0e7bdfe 100644 --- a/src/adapters/sumo_store_mnesia.erl +++ b/src/adapters/sumo_store_mnesia.erl @@ -38,8 +38,9 @@ %%% Types %%%============================================================================= --type option() :: - disc_copies | ram_copies | majority | snmp | storage_properties. +-type option() :: disc_copies | ram_copies | majority + | snmp | storage_properties. + -type state() :: #{default_options => [{option(), term()}]}. %%%============================================================================= @@ -54,7 +55,7 @@ init(Options) -> -spec persist(sumo_internal:doc(), state()) -> sumo_store:result(sumo_internal:doc(), state()). persist(Doc, State) -> - %% Set the real id, replacing undefined by 0 so it is autogenerated + %% Set the real id, replacing undefined by 0 so it is auto-generated DocName = sumo_internal:doc_name(Doc), IdField = sumo_internal:id_field_name(DocName), Id = sumo_internal:get_field(IdField, Doc), @@ -155,7 +156,7 @@ find_by(DocName, Conditions, [], Limit, Offset, State) -> end end, Transaction = case Limit of - 0 -> Transaction0; + 0 -> Transaction0; Limit -> TransactionL end, case mnesia:transaction(Transaction) of @@ -179,13 +180,11 @@ create_schema(Schema, #{default_options := DefaultOptions} = State) -> sumo_internal:field_name(Field) || Field <- Fields, lists:member(index, sumo_internal:field_attrs(Field)) ], - Options = [ {attributes, Attributes}, {index, Indexes} | DefaultOptions ], - case mnesia:create_table(Name, Options) of {atomic, ok} -> {ok, State}; {aborted, {already_exists, Name}} -> {ok, State}; @@ -200,7 +199,8 @@ create_schema(Schema, #{default_options := DefaultOptions} = State) -> parse(Options) -> parse(Options, []). %% @private -parse([], Acc) -> Acc; +parse([], Acc) -> + Acc; parse([{disc_copies, here} | Options], Acc) -> parse(Options, [{disc_copies, [node()]} | Acc]); parse([{disc_copies, Nodes} | Options], Acc) -> @@ -258,8 +258,9 @@ build_match_spec(DocName, Conditions) -> end, ValuesSorted = lists:sort(OrderingFun, maps:values(FieldsMap)), MatchHead = list_to_tuple([DocName | ValuesSorted]), - Guard = - [condition_to_guard(Condition, FieldsMap) || Condition <- NewConditions], + Guard = [ + condition_to_guard(Condition, FieldsMap) || Condition <- NewConditions + ], Result = '$_', [{MatchHead, Guard, [Result]}]. @@ -315,7 +316,8 @@ schema_fields(Schema) -> %% @private place_id_first(Fields) -> place_id_first(Fields, []). -place_id_first([], Acc) -> lists:reverse(Acc); +place_id_first([], Acc) -> + lists:reverse(Acc); place_id_first([Field|Fields], Acc) -> case lists:member(id, sumo_internal:field_attrs(Field)) of true -> [Field|lists:reverse(Acc)] ++ Fields; @@ -334,7 +336,8 @@ result_to_doc(Result, Fields) -> %% @private transform_conditions(DocName, Conditions) -> sumo_utils:transform_conditions( - fun validate_date/1, DocName, Conditions, [date]). + fun validate_date/1, DocName, Conditions, [date] + ). %% @private validate_date({FieldType, _, FieldValue}) -> diff --git a/src/sumo.erl b/src/sumo.erl index 601f8b4..9a74f95 100644 --- a/src/sumo.erl +++ b/src/sumo.erl @@ -25,13 +25,15 @@ -export([ new_schema/2, new_field/3, - new_field/2]). + new_field/2 +]). %%% API for schema creation. -export([ create_schema/0, create_schema/1, - create_schema/2]). + create_schema/2 +]). %%% API for standard CRUD functions. -export([ @@ -48,27 +50,43 @@ %%% Types -type schema_name() :: atom(). --type field_attr() :: id | unique | index | not_null | auto_increment | - {length, integer()}. + +-type custom_attr() :: term(). + +-type field_attr() :: id | unique | index | not_null | auto_increment + | {length, integer()} | custom_attr(). + -type field_attrs() :: [field_attr()]. --type field_type() :: integer | string | binary | text | float | - date | datetime | custom. --type field_name() :: atom(). + +-type field_type() :: integer | string | binary | text | float + | date | datetime | custom. + +-type field_name() :: atom(). + -type field_value() :: term(). --type operator() :: '<' | '>' | '==' | '=<' | '>=' | '/=' | 'like'. --type doc() :: #{field_name() => field_value()}. --type conditions() :: condition() | [condition()]. --type condition() :: {'and', [condition()]} | {'or', [condition()]} | - {'not', condition()} | {field_name(), field_value()} | - {field_name(), operator(), field_value()} | - {field_name(), operator(), field_name()}. --type sort_order() :: asc | desc. --type sort() :: field_name() | - {field_name(), sort_order()} | - [{field_name(), sort_order()}]. --type schema() :: sumo_internal:schema(). --type field() :: sumo_internal:field(). --type user_doc() :: term(). + +-type operator() :: '<' | '>' | '==' | '=<' | '>=' | '/=' | 'like'. + +-type model() :: #{field_name() => field_value()}. + +-type condition() :: {'and', [condition()]} | {'or', [condition()]} + | {'not', condition()} | {field_name(), field_value()} + | {field_name(), operator(), field_value()} + | {field_name(), operator(), field_name()}. + +-type conditions() :: condition() | [condition()]. + +-type sort_order() :: asc | desc. + +-type sort() :: field_name() + | {field_name(), sort_order()} + | [{field_name(), sort_order()}]. + +-type schema() :: sumo_internal:schema(). + +-type field() :: sumo_internal:field(). + +-type user_doc() :: term(). -export_type([ schema_name/0, @@ -77,7 +95,7 @@ field_type/0, field_name/0, field_value/0, - doc/0, + model/0, conditions/0, sort/0, sort_order/0, @@ -122,8 +140,8 @@ find(DocName, Id) -> %% @doc Returns all docs from the given store. -spec find_all(schema_name()) -> [user_doc()]. find_all(DocName) -> - case sumo_store:find_all(sumo_internal:get_store(DocName), DocName) of - {ok, Docs} -> docs_wakeup(DocName, Docs); + case sumo_store:find_all(sumo_config:get_store(DocName), DocName) of + {ok, Docs} -> docs_wakeup(Docs); Error -> throw(Error) end. @@ -136,18 +154,18 @@ find_all(DocName) -> Res :: [user_doc()]. find_all(DocName, SortFields0, Limit, Offset) -> SortFields = normalize_sort_fields(SortFields0), - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:find_all(Store, DocName, SortFields, Limit, Offset) of - {ok, Docs} -> docs_wakeup(DocName, Docs); + {ok, Docs} -> docs_wakeup(Docs); Error -> throw(Error) end. %% @doc Returns *all* docs that match Conditions. -spec find_by(schema_name(), conditions()) -> [user_doc()]. find_by(DocName, Conditions) -> - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:find_by(Store, DocName, Conditions) of - {ok, Docs} -> docs_wakeup(DocName, Docs); + {ok, Docs} -> docs_wakeup(Docs); Error -> throw(Error) end. @@ -162,9 +180,9 @@ find_by(DocName, Conditions) -> Offset :: non_neg_integer(), Res :: [user_doc()]. find_by(DocName, Conditions, Limit, Offset) -> - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:find_by(Store, DocName, Conditions, Limit, Offset) of - {ok, Docs} -> docs_wakeup(DocName, Docs); + {ok, Docs} -> docs_wakeup(Docs); Error -> throw(Error) end. @@ -181,10 +199,10 @@ find_by(DocName, Conditions, Limit, Offset) -> Res :: [user_doc()]. find_by(DocName, Conditions, SortFields, Limit, Offset) -> NormalizedSortFields = normalize_sort_fields(SortFields), - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:find_by( Store, DocName, Conditions, NormalizedSortFields, Limit, Offset) of - {ok, Docs} -> docs_wakeup(DocName, Docs); + {ok, Docs} -> docs_wakeup(Docs); Error -> throw(Error) end. @@ -192,15 +210,16 @@ find_by(DocName, Conditions, SortFields, Limit, Offset) -> -spec persist(schema_name(), UserDoc) -> UserDoc. persist(DocName, State) -> IdField = sumo_internal:id_field_name(DocName), - DocMap = DocName:sumo_sleep(State), + 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_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:persist(Store, sumo_internal:new_doc(DocName, DocMap)) of {ok, NewDoc} -> - Ret = sumo_internal:wakeup(DocName, NewDoc), + Ret = sumo_internal:wakeup(NewDoc), sumo_event:dispatch(DocName, EventName, [Ret]), Ret; Error -> @@ -210,7 +229,7 @@ persist(DocName, State) -> %% @doc Deletes all docs of type DocName. -spec delete_all(schema_name()) -> non_neg_integer(). delete_all(DocName) -> - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:delete_all(Store, DocName) of {ok, NumRows} -> case NumRows > 0 of @@ -234,7 +253,7 @@ delete(DocName, Id) -> %% @doc Deletes the doc identified by Conditions. -spec delete_by(schema_name(), conditions()) -> non_neg_integer(). delete_by(DocName, Conditions) -> - Store = sumo_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:delete_by(Store, DocName, Conditions) of {ok, 0} -> 0; @@ -248,11 +267,10 @@ delete_by(DocName, Conditions) -> %% @doc Creates the schema for the docs of type DocName. -spec create_schema(schema_name()) -> ok. create_schema(DocName) -> - create_schema(DocName, sumo_internal:get_store(DocName)). + create_schema(DocName, sumo_config:get_store(DocName)). %% @doc -%% Creates the schema for the docs of type DocName using the given -%% store. +%% Creates the schema for the docs of type `DocName' using the given `Store'. %% @end -spec create_schema(schema_name(), atom()) -> ok. create_schema(DocName, Store) -> @@ -272,9 +290,9 @@ 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_internal:get_store(DocName), + Store = sumo_config:get_store(DocName), case sumo_store:call(Store, DocName, Function, Args) of - {ok, {docs, Docs}} -> docs_wakeup(DocName, Docs); + {ok, {docs, Docs}} -> docs_wakeup(Docs); {ok, {raw, Value}} -> Value end. @@ -298,10 +316,8 @@ new_field(Name, Type) -> %%%============================================================================= %% @private -docs_wakeup(DocName, Docs) -> - lists:map(fun(Doc) -> - sumo_internal:wakeup(DocName, Doc) - end, Docs). +docs_wakeup(Docs) -> + lists:map(fun(Doc) -> sumo_internal:wakeup(Doc) end, Docs). %% @private normalize_sort_fields(FieldName) when is_atom(FieldName) -> diff --git a/src/sumo_backend_sup.erl b/src/sumo_backend_sup.erl index 8835028..ec3c8a3 100644 --- a/src/sumo_backend_sup.erl +++ b/src/sumo_backend_sup.erl @@ -23,15 +23,6 @@ -behaviour(supervisor). --define(CLD(Name, Module, Options), { - Name, % Child Id - {Module, start_link, [Name, Options]}, % Start Fun - permanent, % Restart - 5000, % Shutdown - worker, % Type - [Module] % Modules -}). - %%% API -export([start_link/0]). @@ -50,11 +41,23 @@ start_link() -> %%% Supervisor callbacks %%%============================================================================= --spec init(any()) -> - {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. +-spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> {ok, Backends} = application:get_env(sumo_db, storage_backends), Children = lists:map(fun({Name, Module, Options}) -> - ?CLD(Name, Module, Options) + child_spec(Name, Module, Options) end, Backends), {ok, {{one_for_one, 5, 10}, Children}}. + +%%%============================================================================= +%%% Internal functions +%%%============================================================================= + +%% @private +child_spec(Name, Module, Options) -> + {Name, + {Module, start_link, [Name, Options]}, + permanent, + 5000, + worker, + [Module]}. diff --git a/src/sumo_config.erl b/src/sumo_config.erl new file mode 100644 index 0000000..80446f0 --- /dev/null +++ b/src/sumo_config.erl @@ -0,0 +1,70 @@ +%%%------------------------------------------------------------------- +%%% @doc Main **internal** module for sumo. +%%% Use this one from your own applications. +%%% +%%% Copyright 2012 Inaka <hello@inaka.net> +%%% +%%% Licensed under the Apache License, Version 2.0 (the "License"); +%%% you may not use this file except in compliance with the License. +%%% You may obtain a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, +%%% software distributed under the License is distributed on an +%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +%%% either express or implied. See the License for the specific +%%% language governing permissions and limitations under the License. +%%% @end +%%% @copyright Inaka +%%%------------------------------------------------------------------- +-module(sumo_config). + +%% API +-export([ + get_docs/0, + get_doc/1, + get_store/1, + get_props/1, + get_prop_value/2 +]). + +-type doc_config() :: {DocName :: atom(), Store :: atom(), Props :: map()}. + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec get_docs() -> [doc_config()]. +get_docs() -> + application:get_env(sumo_db, docs, []). + +-spec get_doc(atom()) -> doc_config() | undefined. +get_doc(DocName) -> + case ets:lookup(?MODULE, DocName) of + [Doc] -> Doc; + [] -> undefined + end. + +-spec get_store(atom()) -> atom(). +get_store(DocName) -> + lookup_element(DocName, 2). + +-spec get_props(atom()) -> map(). +get_props(DocName) -> + lookup_element(DocName, 3). + +-spec get_prop_value(atom(), atom()) -> term(). +get_prop_value(DocName, Prop) -> + maps:get(Prop, get_props(DocName), undefined). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +%% @private +lookup_element(Key, Pos) -> + try ets:lookup_element(?MODULE, Key, Pos) + catch + _:_ -> undefined + end. diff --git a/src/sumo_doc.erl b/src/sumo_doc.erl index 31ef9c3..e990915 100644 --- a/src/sumo_doc.erl +++ b/src/sumo_doc.erl @@ -24,5 +24,5 @@ %% Returns all behavior callbacks. -callback sumo_schema() -> sumo:schema(). --callback sumo_wakeup(sumo:doc()) -> sumo:user_doc(). --callback sumo_sleep(sumo:user_doc()) -> sumo:doc(). +-callback sumo_wakeup(sumo:model()) -> sumo:user_doc(). +-callback sumo_sleep(sumo:user_doc()) -> sumo:model(). diff --git a/src/sumo_internal.erl b/src/sumo_internal.erl index 715f5af..d906eaf 100644 --- a/src/sumo_internal.erl +++ b/src/sumo_internal.erl @@ -26,32 +26,28 @@ %%% API for doc/schema manipulation. -export([new_schema/2, new_field/3]). +%%% API for opaqueness +-export([ + schema_name/1, + schema_fields/1, + doc_name/1, + doc_fields/1, + wakeup/1, + new_doc/1, + new_doc/2 +]). + %%% API for schema fields manipulation. -export([ - get_field/2, - set_field/3, - id_field_name/1, get_schema/1, - field_is/2, - id_field_type/1, field_name/1, field_type/1, - field_attrs/1 -]). - -%%% API for store handling. --export([get_store/1]). - -%%% API for opaqueness --export([ - wakeup/1, - wakeup/2, - new_doc/1, - new_doc/2, - doc_name/1, - doc_fields/1, - schema_name/1, - schema_fields/1 + field_attrs/1, + field_is/2, + get_field/2, + set_field/3, + id_field_name/1, + id_field_type/1 ]). %%% API for conditional logic. @@ -59,6 +55,10 @@ -export([report_overrun/1]). +%%%=================================================================== +%%% Types definitions +%%%=================================================================== + -opaque schema() :: #{ name => atom(), fields => [field()] @@ -66,7 +66,8 @@ -opaque doc() :: #{ name => atom(), - fields => sumo:doc() + module => module(), + fields => sumo:model() }. -opaque field() :: #{ @@ -77,9 +78,21 @@ -export_type([schema/0, doc/0, field/0]). -%%%============================================================================= +%%%=================================================================== %%% API -%%%============================================================================= +%%%=================================================================== + +%% @doc Returns a new schema. +-spec new_schema(sumo:schema_name(), [field()]) -> schema(). +new_schema(Name, Fields) -> + #{name => Name, fields => Fields}. + +%% @doc Returns a new field of the given type and attributes. +-spec new_field( + sumo:field_name(), sumo:field_type(), sumo:field_attrs() +) -> field(). +new_field(Name, Type, Attributes) -> + #{name => Name, type => Type, attrs => Attributes}. %% @doc Returns the name of the schema -spec schema_name(schema()) -> sumo:schema_name(). @@ -96,66 +109,33 @@ schema_fields(Schema) -> doc_name(Doc) -> maps:get(name, Doc, undefined). --spec doc_fields(doc()) -> sumo:doc(). +-spec doc_fields(doc()) -> sumo:model(). doc_fields(Doc) -> maps:get(fields, Doc, []). %% @doc Wakes up the document -spec wakeup(doc()) -> sumo:user_doc(). wakeup(Doc) -> - wakeup(doc_name(Doc), Doc). - -%% @doc Wakes up the document --spec wakeup(module(), doc()) -> sumo:user_doc(). -wakeup(DocName, Doc) -> + Module = sumo_config:get_prop_value(doc_name(Doc), module), Fields = maps:get(fields, Doc, []), - DocName:sumo_wakeup(Fields). - -%% @doc Returns all the configured docs. --spec get_docs() -> [{atom(), atom()}]. -get_docs() -> - {ok, Docs} = application:get_env(sumo_db, docs), - Docs. + Module:sumo_wakeup(Fields). -%% @doc Returns the process name that handles persistence for the given -%% Doc or DocName. --spec get_store(sumo:schema_name() | doc()) -> atom(). -get_store(DocName) when is_atom(DocName) -> - sumo_utils:keyfind(DocName, get_docs()); +%% @doc Returns a new doc. +-spec new_doc(sumo:schema_name()) -> doc(). +new_doc(Name) -> + new_doc(Name, #{}). -get_store(_Doc = #{name := Name}) -> - get_store(Name). +%% @doc Returns a new doc. +-spec new_doc(sumo:schema_name(), sumo:model()) -> doc(). +new_doc(Name, Fields) -> + Module = sumo_config:get_prop_value(Name, module), + #{name => Name, module => Module, fields => Fields}. %% @doc Returns the schema for a given DocName. -spec get_schema(sumo:schema_name()) -> schema(). get_schema(DocName) -> - DocName:sumo_schema(). - -%% @doc Returns the value of a field from a sumo_doc. --spec get_field(sumo:field_name(), doc()) -> sumo:field_value(). -get_field(Name, Doc) -> - maps:get(Name, doc_fields(Doc), undefined). - -%% @doc Sets a value in an sumo_doc. --spec set_field(sumo:field_name(), sumo:field_value(), doc()) -> doc(). -set_field(FieldName, Value, _Doc = #{fields := Fields, name := Name}) -> - new_doc(Name, maps:put(FieldName, Value, Fields)). - -%% @doc Returns name of field marked as ID for the given schema or doc name. --spec id_field_name(sumo:schema_name()) -> sumo:field_name(). -id_field_name(DocName) -> - field_name(get_id_field(get_schema(DocName))). - -%% @doc Returns type of field marked as ID for the given schema or doc name. --spec id_field_type(sumo:schema_name()) -> sumo:field_type(). -id_field_type(DocName) -> - field_type(get_id_field(get_schema(DocName))). - -%% @doc Returns field marked as ID for the given schema or doc name. -get_id_field(_Schema = #{fields := Fields}) -> - hd(lists:filter(fun(_Field = #{attrs := Attributes}) -> - length(lists:filter(fun(T) -> T =:= id end, Attributes)) > 0 - end, Fields)). + Module = sumo_config:get_prop_value(DocName, module), + Module:sumo_schema(). %% @doc Returns the name of the given field. -spec field_name(field()) -> sumo:field_name(). @@ -177,27 +157,25 @@ field_attrs(_Field = #{attrs := Attributes}) -> field_is(What, #{attrs := Attributes}) -> proplists:is_defined(What, Attributes). -%% @doc Returns a new doc. --spec new_doc(sumo:schema_name()) -> doc(). -new_doc(Name) -> - new_doc(Name, #{}). +%% @doc Returns the value of a field from a sumo_doc. +-spec get_field(sumo:field_name(), doc()) -> sumo:field_value(). +get_field(Name, Doc) -> + maps:get(Name, doc_fields(Doc), undefined). -%% @doc Returns a new doc. --spec new_doc(sumo:schema_name(), sumo:doc()) -> doc(). -new_doc(Name, Fields) -> - #{name => Name, fields => Fields}. +%% @doc Sets a value in an sumo_doc. +-spec set_field(sumo:field_name(), sumo:field_value(), doc()) -> doc(). +set_field(FieldName, Value, _Doc = #{fields := Fields, name := Name}) -> + new_doc(Name, maps:put(FieldName, Value, Fields)). -%% @doc Returns a new schema. --spec new_schema(sumo:schema_name(), [field()]) -> schema(). -new_schema(Name, Fields) -> - #{name => Name, fields => Fields}. +%% @doc Returns name of field marked as ID for the given schema or doc name. +-spec id_field_name(sumo:schema_name()) -> sumo:field_name(). +id_field_name(DocName) -> + field_name(get_id_field(get_schema(DocName))). -%% @doc Returns a new field of the given type and attributes. --spec new_field( - sumo:field_name(), sumo:field_type(), sumo:field_attrs() -) -> field(). -new_field(Name, Type, Attributes) -> - #{name => Name, type => Type, attrs => Attributes}. +%% @doc Returns type of field marked as ID for the given schema or doc name. +-spec id_field_type(sumo:schema_name()) -> sumo:field_type(). +id_field_type(DocName) -> + field_type(get_id_field(get_schema(DocName))). %% @doc Checks the operator is known, throws otherwise. -spec check_operator(sumo:operator()) -> ok. @@ -213,3 +191,14 @@ check_operator(Op) -> throw({unknown_operator, Op}). -spec report_overrun(term()) -> ok. report_overrun(Report) -> lager:error("~p", [Report]). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +%% @doc Returns field marked as ID for the given schema or doc name. +%% @private +get_id_field(_Schema = #{fields := Fields}) -> + hd(lists:filter(fun(_Field = #{attrs := Attributes}) -> + length(lists:filter(fun(T) -> T =:= id end, Attributes)) > 0 + end, Fields)). diff --git a/src/sumo_store.erl b/src/sumo_store.erl index 68f7241..25ab43b 100644 --- a/src/sumo_store.erl +++ b/src/sumo_store.erl @@ -53,8 +53,8 @@ %%%============================================================================= -record(state, { - handler = undefined:: module(), - handler_state = undefined:: any() + handler = undefined :: module(), + handler_state = undefined :: any() }). -type state() :: #state{}. diff --git a/src/sumo_store_sup.erl b/src/sumo_store_sup.erl index 9201d86..4b498ea 100644 --- a/src/sumo_store_sup.erl +++ b/src/sumo_store_sup.erl @@ -24,15 +24,6 @@ -behaviour(supervisor). --define(CLD(Name, Module, Options), { - Name, - {sumo_store, start_link, [Name, Module, Options]}, - permanent, - 5000, - worker, - [Module] -}). - %%% API -export([start_link/0]). @@ -51,11 +42,23 @@ start_link() -> %%% Supervisor callbacks %%%============================================================================= --spec init(any()) -> - {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. +-spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> {ok, Stores} = application:get_env(sumo_db, stores), Children = lists:map(fun({Name, Module, Options}) -> - ?CLD(Name, Module, Options) + child_spec(Name, Module, Options) end, Stores), - {ok, { {one_for_one, 5, 10}, Children} }. + {ok, {{one_for_one, 5, 10}, Children}}. + +%%%============================================================================= +%%% Internal functions +%%%============================================================================= + +%% @private +child_spec(Name, Module, Options) -> + {Name, + {sumo_store, start_link, [Name, Module, Options]}, + permanent, + 5000, + worker, + [Module]}. diff --git a/src/sumo_sup.erl b/src/sumo_sup.erl index 152cd4a..7fc1f4d 100644 --- a/src/sumo_sup.erl +++ b/src/sumo_sup.erl @@ -35,7 +35,8 @@ %%%============================================================================= -spec start_link() -> {ok, pid()} | {error, term()}. -start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). %%%============================================================================= %%% Supervisor callbacks @@ -44,6 +45,7 @@ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). -spec init(any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> + ok = init_config_table(), Specs = [ sup(sumo_backend_sup), sup(sumo_store_sup), @@ -53,3 +55,14 @@ init([]) -> %% @private sup(I) -> {I, {I, start_link, []}, permanent, infinity, supervisor, [I]}. + +%% @private +init_config_table() -> + Docs = application:get_env(sumo_db, docs, []), + sumo_config = ets:new(sumo_config, [ + protected, + named_table, + {read_concurrency, true} + ]), + true = ets:insert(sumo_config, Docs), + ok. diff --git a/src/utils/sumo_utils.erl b/src/utils/sumo_utils.erl index 3683e75..4786411 100644 --- a/src/utils/sumo_utils.erl +++ b/src/utils/sumo_utils.erl @@ -119,9 +119,9 @@ is_datetime(_) -> false. -spec keyfind(Key, KVList) -> Val | undefined when - Key :: term(), - KVList :: [{Key, Val}], - Val :: term(). + Key :: term(), + KVList :: [{Key, Val}], + Val :: term(). keyfind(Key, KVList) -> keyfind(Key, KVList, undefined). diff --git a/test/conditional_logic_SUITE.erl b/test/conditional_logic_SUITE.erl index a50cafc..8aaac73 100644 --- a/test/conditional_logic_SUITE.erl +++ b/test/conditional_logic_SUITE.erl @@ -43,8 +43,8 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> sumo_test_utils:start_apps(), - sumo_conditionals_test_helper:init_store(sumo_test_people_mnesia), - [{module, sumo_test_people_mnesia} | Config]. + sumo_conditionals_test_helper:init_store(people), + [{name, people} | Config]. -spec end_per_suite(config()) -> config(). end_per_suite(Config) -> diff --git a/test/sumo_basic_SUITE.erl b/test/sumo_basic_SUITE.erl index da3e6bd..8fcab93 100644 --- a/test/sumo_basic_SUITE.erl +++ b/test/sumo_basic_SUITE.erl @@ -43,12 +43,12 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> ok = sumo_test_utils:start_apps(), - [{module, sumo_test_people_mnesia} | Config]. + [{name, people} | Config]. -spec init_per_testcase(atom(), config()) -> config(). init_per_testcase(_, Config) -> - {_, Module} = lists:keyfind(module, 1, Config), - sumo_basic_test_helper:init_store(Module), + {_, Name} = lists:keyfind(name, 1, Config), + sumo_basic_test_helper:init_store(Name), Config. -spec end_per_suite(config()) -> config(). diff --git a/test/sumo_test_people_mnesia.erl b/test/sumo_test_people_mnesia.erl index 575e094..1ae89f2 100644 --- a/test/sumo_test_people_mnesia.erl +++ b/test/sumo_test_people_mnesia.erl @@ -53,4 +53,4 @@ sumo_schema() -> sumo:new_field(profile_image, binary), sumo:new_field(weird_field, custom) ], - sumo:new_schema(?MODULE, Fields). + sumo:new_schema(people, Fields). diff --git a/test/test.config b/test/test.config index 41344b0..d7e3c23 100644 --- a/test/test.config +++ b/test/test.config @@ -14,7 +14,7 @@ ]} ]}, {docs, [ - {sumo_test_people_mnesia, sumo_test_mnesia} + {people, sumo_test_mnesia, #{module => sumo_test_people_mnesia}} ]}, {events, [ {sumo_test_people_mnesia, sumo_test_people_mnesia_events_manager}