Skip to content

Commit

Permalink
[#275] – Remove the need for mnesia's start_phase magic
Browse files Browse the repository at this point in the history
  • Loading branch information
cabol committed Mar 29, 2017
1 parent 55341a6 commit 2b016ea
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 54 deletions.
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ And you can check all of our open-source projects at

These three concepts have a specific meaning in the context of sumo_db.

- **Backend**: holds the connection to a single instance of a database, which
can be MySql, MongoDB, ElasticSearch or any other that's implemented.
- **Backend**: establishes and holds a single Database instance connection.

- **Store**: implements the specific operations that modify the contents of the
backend and retrieves the information it holds.
Expand All @@ -71,10 +70,26 @@ These three concepts have a specific meaning in the context of sumo_db.
that bridges the model and the store.


## Supported Backends/Adapters

- [Mnesia](http://erlang.org/doc/man/mnesia.html) is built-in in `sumo`
- [Riak](https://github.com/inaka/sumo_db_riak)
- [PostgreSQL](https://github.com/inaka/sumo_db_pgsql)
- [MySQL](https://github.com/inaka/sumo_db_mysql)
- [MongoDB](https://github.com/inaka/sumo_db_mongo)
- [ElasticSearch](https://github.com/inaka/sumo_db_elasticsearch)


## Implementing an Adapter

TO implement an adapter, you must implement two behaviors: `sumo_backend` and
`sumo_store`.
To implement an adapter, you must implement two specific behaviours:

- [**sumo_backend**](./src/sumo_backend.erl) – DB connection
- [**sumo_store**](./src/sumo_store.erl) – implements the **Sumo API**

> You can check the implemented adapters mentioned above in order to have
a better idea about how to build a custom adapter from scratch.


## Events

Expand Down Expand Up @@ -119,6 +134,7 @@ Sumo requires users to add their own `gen_event`'s in order to handle those even
```
Sumo allows us to add a `gen_event` to one type of model (i.e. `people`) or for all (`'_'`).


## Example

See: [**examples/blog**][example-blog] for a full example. To run it, while
Expand Down
43 changes: 21 additions & 22 deletions elvis.config
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
[
{
elvis,
[
{config,
[#{dirs => ["src/*", "test"],
filter => "*.erl",
rules => [{elvis_style, dont_repeat_yourself, disable},
{elvis_style, invalid_dynamic_call, disable}],
ruleset => erl_files
},
#{dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config
},
#{dirs => ["."],
filter => "elvis.config",
ruleset => elvis_config
}
]
}
]
}
{elvis, [
{config, [
#{dirs => ["src/*", "test"],
filter => "*.erl",
rules => [
{elvis_style, dont_repeat_yourself, disable},
{elvis_style, invalid_dynamic_call, disable},
{elvis_style, line_length, #{limit => 100}}
],
ruleset => erl_files
},
#{dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config
},
#{dirs => ["."],
filter => "elvis.config",
ruleset => elvis_config
}
]}
]}
].
2 changes: 1 addition & 1 deletion src/adapter_test_helpers/sumo_test_people.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
%%%=============================================================================

-spec sumo_schema() -> no_return().
sumo_schema() -> throw(should_be_implemented_by_children).
sumo_schema() -> exit(should_be_implemented_by_children).

-spec sumo_sleep(Person :: person()) -> sumo:model().
sumo_sleep(Person) ->
Expand Down
10 changes: 9 additions & 1 deletion src/adapters/sumo_backend_mnesia.erl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,15 @@ start_link(Name, Options) ->
%%%=============================================================================

-spec init([term()]) -> {ok, state()}.
init(_Options) -> {ok, #{}}.
init(_Options) ->
Node = node(),
_ = application:stop(mnesia),
_ = case mnesia:create_schema([Node]) of
ok -> ok;
{error, {Node, {already_exists, Node}}} -> ok
end,
{ok, _} = application:ensure_all_started(mnesia),
{ok, #{}}.

-spec handle_call(term(), term(), state()) -> {reply, term(), state()}.
handle_call(Msg, _From, State) -> {reply, {unexpected_message, Msg}, State}.
Expand Down
8 changes: 3 additions & 5 deletions src/adapters/sumo_store_mnesia.erl
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ new_id(string) -> uuid:uuid_to_string(uuid:get_v4(), standard);
new_id(binary) -> uuid:uuid_to_string(uuid:get_v4(), binary_standard);
new_id(integer) -> <<Id:128>> = uuid:get_v4(), Id;
new_id(float) -> <<Id:128>> = uuid:get_v4(), Id * 1.0;
new_id(FieldType) -> throw({unimplemented, FieldType}).
new_id(FieldType) -> exit({unimplemented, FieldType}).

%% @doc http://www.erlang.org/doc/apps/erts/match_spec.html
%% @private
Expand Down Expand Up @@ -346,7 +346,7 @@ condition_to_guard({Name, Value}, FieldsMap) ->
condition_to_guard({Name, '==', Value}, FieldsMap).

%% @private
check_operator(like) -> throw({unsupported_operator, like});
check_operator(like) -> exit({unsupported_operator, like});
check_operator(Op) -> sumo_internal:check_operator(Op).

%% @private
Expand Down Expand Up @@ -379,9 +379,7 @@ result_to_doc(Result, Fields) ->

%% @private
transform_conditions(DocName, Conditions) ->
sumo_utils:transform_conditions(
fun validate_date/1, DocName, Conditions, [date]
).
sumo_utils:transform_conditions(fun validate_date/1, DocName, Conditions, [date]).

%% @private
validate_date({FieldType, _, FieldValue}) ->
Expand Down
11 changes: 3 additions & 8 deletions src/sumo.erl
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,7 @@ find_by(DocName, Conditions, Limit, Offset) ->
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
case sumo_store:find_by(Store, DocName, Conditions, NormalizedSortFields, Limit, Offset) of
{ok, Docs} -> docs_wakeup(Docs);
Error -> exit(Error)
end.
Expand Down Expand Up @@ -249,10 +247,7 @@ delete_by(DocName, Conditions) ->
{ok, 0} ->
0;
{ok, NumRows} ->
EventId = sumo_event:dispatch(DocName,
EventId,
deleted_total,
[NumRows, Conditions]),
EventId = sumo_event:dispatch(DocName, EventId, deleted_total, [NumRows, Conditions]),
NumRows;
Error ->
exit(Error)
Expand All @@ -263,7 +258,7 @@ delete_by(DocName, Conditions) ->
count(DocName) ->
case sumo_store:count(sumo_config:get_store(DocName), DocName) of
{ok, Total} -> Total;
Error -> throw(Error)
Error -> exit(Error)
end.

%% @doc Calls the given custom function of a store.
Expand Down
8 changes: 3 additions & 5 deletions src/sumo_internal.erl
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ new_schema(Name, Fields) ->
S.

%% @doc Returns a new field of the given type and attributes.
-spec new_field(
sumo:field_name(), sumo:field_type(), sumo:field_attrs()
) -> field().
-spec new_field(sumo:field_name(), sumo:field_type(), sumo:field_attrs()) -> field().
new_field(Name, Type, Attributes) ->
#{name => Name, type => Type, attrs => Attributes}.

Expand Down Expand Up @@ -179,7 +177,7 @@ id_field_name(DocName) ->
id_field_type(DocName) ->
field_type(get_id_field(get_schema(DocName))).

%% @doc Checks the operator is known, throws otherwise.
%% @doc Checks the operator is known, exit otherwise.
-spec check_operator(sumo:operator()) -> ok.
check_operator('<') -> ok;
check_operator('=<') -> ok;
Expand All @@ -188,7 +186,7 @@ check_operator('>=') -> ok;
check_operator('==') -> ok;
check_operator('/=') -> ok;
check_operator('like') -> ok;
check_operator(Op) -> throw({unknown_operator, Op}).
check_operator(Op) -> exit({unknown_operator, Op}).

-spec report_overrun(term()) -> ok.
report_overrun(Report) ->
Expand Down
2 changes: 1 addition & 1 deletion src/utils/sumo_sql_builder.erl
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ values_conditions({Name, Value}, {Values, CleanExprs, Count}) ->
values_conditions([], Acc) ->
Acc;
values_conditions(Expr, _) ->
throw({unsupported_expression, Expr}).
exit({unsupported_expression, Expr}).

-spec where_clause(sumo:conditions()) -> iodata().
where_clause(Exprs) ->
Expand Down
3 changes: 1 addition & 2 deletions src/utils/sumo_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ doc_transform(Fun, Doc) ->
FieldValue :: sumo:field_value(),
ResTuple :: {FieldName, FieldType, FieldValue},
Response :: [ResTuple].
doc_filter_fields_by(DocNameOrDoc, FilteredFieldTypes)
when is_atom(DocNameOrDoc) ->
doc_filter_fields_by(DocNameOrDoc, FilteredFieldTypes) when is_atom(DocNameOrDoc) ->
filter_fields(DocNameOrDoc, undefined, FilteredFieldTypes);
doc_filter_fields_by(DocNameOrDoc, FilteredFieldTypes) ->
DocName = sumo_internal:doc_name(DocNameOrDoc),
Expand Down
5 changes: 0 additions & 5 deletions test/sumo_test_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@

-spec start_apps() -> ok.
start_apps() ->
ok = case mnesia:create_schema([node()]) of
ok -> ok;
{error, {_Host, {already_exists, _Host}}} -> ok
end,
{ok, _} = application:ensure_all_started(mnesia),
{ok, _} = application:ensure_all_started(sumo_db),
init_events(),
ok.
Expand Down

0 comments on commit 2b016ea

Please sign in to comment.