Skip to content

Commit eeb78f0

Browse files
author
Evan Miller
committed
Validate model parameter types
New functions: boss_db:validate_record_types/1 and Rec:validate_types/0
1 parent 69caf5b commit eeb78f0

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

src/boss_db.erl

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
execute/1,
2626
transaction/1,
2727
validate_record/1,
28+
validate_record_types/1,
2829
type/1,
2930
data_type/2]).
3031

@@ -228,12 +229,58 @@ save_record(Record) ->
228229
%% if the `TestFunction' returns `false' on this particular BossRecord.
229230
validate_record(Record) ->
230231
Type = element(1, Record),
231-
Errors = case erlang:function_exported(Type, validation_tests, 1) of
232-
true -> [String || {TestFun, String} <- Record:validation_tests(), not TestFun()];
233-
false -> []
232+
Errors1 = case validate_record_types(Record) of
233+
ok -> [];
234+
{error, Errors} -> Errors
234235
end,
235-
case length(Errors) of
236+
Errors2 = case Errors1 of
237+
[] ->
238+
case erlang:function_exported(Type, validation_tests, 1) of
239+
true -> [String || {TestFun, String} <- Record:validation_tests(), not TestFun()];
240+
false -> []
241+
end;
242+
_ -> Errors1
243+
end,
244+
case length(Errors2) of
236245
0 -> ok;
246+
_ -> {error, Errors2}
247+
end.
248+
249+
%% @spec validate_record_types( BossRecord ) -> ok | {error, [ErrorMessages]}
250+
%% @doc Validate the parameter types of the given BossRecord without saving it
251+
%% to the database.
252+
validate_record_types(Record) ->
253+
Errors = lists:foldl(fun
254+
({Attr, Type}, Acc) ->
255+
Data = Record:Attr(),
256+
GreatSuccess = case {Data, Type} of
257+
{Data, string} when is_list(Data) ->
258+
true;
259+
{Data, binary} when is_binary(Data) ->
260+
true;
261+
{{{D1, D2, D3}, {T1, T2, T3}}, datetime} when is_integer(D1), is_integer(D2), is_integer(D3),
262+
is_integer(T1), is_integer(T2), is_integer(T3) ->
263+
true;
264+
{Data, integer} when is_integer(Data) ->
265+
true;
266+
{Data, float} when is_float(Data) ->
267+
true;
268+
{Data, number} when is_number(Data) ->
269+
true;
270+
{{N1, N2, N3}, now} when is_integer(N1), is_integer(N2), is_integer(N3) ->
271+
true;
272+
{_Data, Type} ->
273+
false
274+
end,
275+
if
276+
GreatSuccess ->
277+
Acc;
278+
true ->
279+
[lists:concat(["Invalid data type for ", Attr])|Acc]
280+
end
281+
end, [], Record:attribute_types()),
282+
case Errors of
283+
[] -> ok;
237284
_ -> {error, Errors}
238285
end.
239286

src/boss_record_compiler.erl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ trick_out_forms(LeadingForms, Forms, ModuleName, Parameters, TokenInfo) ->
6464
GeneratedForms =
6565
attribute_names_forms(ModuleName, Parameters) ++
6666
attribute_types_forms(ModuleName, TokenInfo) ++
67+
validate_types_forms(ModuleName) ++
6768
validate_forms(ModuleName) ++
6869
save_forms(ModuleName) ++
6970
set_attributes_forms(ModuleName, Parameters) ++
@@ -137,6 +138,20 @@ attribute_types_forms(ModuleName, TypeInfo) ->
137138
fun({P, T}) -> erl_syntax:tuple([erl_syntax:atom(parameter_to_colname(P)), erl_syntax:atom(T)]) end,
138139
TypeInfo))])]))].
139140

141+
validate_types_forms(ModuleName) ->
142+
[erl_syntax:add_precomments([erl_syntax:comment(
143+
["% @spec validate_types() -> ok | {error, [ErrorMessages]}",
144+
lists:concat(["% @doc Validates the parameter types of `", ModuleName, "' without saving to the database."])
145+
])],
146+
erl_syntax:function(
147+
erl_syntax:atom(validate_types),
148+
[erl_syntax:clause([], none,
149+
[erl_syntax:application(
150+
erl_syntax:atom(?DATABASE_MODULE),
151+
erl_syntax:atom(validate_record_types),
152+
[erl_syntax:variable("THIS")]
153+
)])]))].
154+
140155
validate_forms(ModuleName) ->
141156
[erl_syntax:add_precomments([erl_syntax:comment(
142157
["% @spec validate() -> ok | {error, [ErrorMessages]}",

0 commit comments

Comments
 (0)