Skip to content

Instantly share code, notes, and snippets.

@kellymclaughlin
Created June 9, 2011 23:17
Show Gist options
  • Save kellymclaughlin/1017976 to your computer and use it in GitHub Desktop.
Save kellymclaughlin/1017976 to your computer and use it in GitHub Desktop.
diff --git a/src/riak_index.erl b/src/riak_index.erl
index ca258bc..c94499d 100644
--- a/src/riak_index.erl
+++ b/src/riak_index.erl
@@ -93,18 +93,7 @@ parse_object(RObj) ->
parse_fields(IndexFields) ->
%% Call parse_field on each field, and accumulate in ResultAcc or
%% ErrorAcc, depending on whether the operation was successful.
- Types = field_types(),
- F = fun({Field, Value}, {ResultAcc, ErrorAcc}) ->
- case parse_field(Field, Value, Types) of
- {ok, ParsedValue} ->
- NewResultAcc = [{Field, ParsedValue} | ResultAcc],
- {NewResultAcc, ErrorAcc};
- {error, Reason} ->
- NewErrorAcc = [Reason | ErrorAcc],
- {ResultAcc, NewErrorAcc}
- end
- end,
- {Results, FailureReasons} = lists:foldl(F, {[],[]}, IndexFields),
+ {Results, FailureReasons} = lists:foldl(fun field_parser/2, {[],[]}, IndexFields),
%% Return the object, or a list of Reasons.
case FailureReasons == [] of
@@ -112,6 +101,15 @@ parse_fields(IndexFields) ->
false -> {error, lists:reverse(FailureReasons)}
end.
+field_parser({Field, Value}, {ResultAcc, ErrorAcc}) ->
+ case parse_field(Field, Value) of
+ {ok, ParsedValue} ->
+ NewResultAcc = [{Field, ParsedValue} | ResultAcc],
+ {NewResultAcc, ErrorAcc};
+ {error, Reason} ->
+ NewErrorAcc = [Reason | ErrorAcc],
+ {ResultAcc, NewErrorAcc}
+ end.
%% @spec parse_field(Key::string(), Value::string(), Types::data_type_defs()) ->
%% {ok, Value} | {error, Reason}.
@@ -120,26 +118,33 @@ parse_fields(IndexFields) ->
%% {error, Reason} if there is a problem. Reason is either
%% `{unknown_field_type, Field}` or `{field_parsing_failed,
%% {Field, Value}}.`
-parse_field(Key, Value, [Type|Types]) ->
- %% Run the regex to check if the key suffix matches this data
- %% type.
- {RE, Function} = Type,
- case re:run(Key, RE) of
- {match, _} ->
- %% We have a match. Parse the value.
- case Function(Value) of
+parse_field(Key, Value) ->
+ case lists:reverse(Key) of
+ "di_" ++ _ -> % parse as id
+ case parse_id(Value) of
{ok, ParsedValue} ->
{ok, ParsedValue};
_ ->
{error, {field_parsing_failed, {Key, Value}}}
end;
- nomatch ->
- %% Try the next data type.
- parse_field(Key, Value, Types)
- end;
-parse_field(Key, _Value, []) ->
- %% No matching data types, return an error.
- {error, {unknown_field_type, Key}}.
+ "tni_" ++ _ -> % parse as int
+ case parse_integer(Value) of
+ {ok, ParsedValue} ->
+ {ok, ParsedValue};
+ _ ->
+ {error, {field_parsing_failed, {Key, Value}}}
+ end;
+ "taolf_" ++ _ -> % parse as float
+ case parse_float(Value) of
+ {ok, ParsedValue} ->
+ {ok, ParsedValue};
+ _ ->
+ {error, {field_parsing_failed, {Key, Value}}}
+ end;
+ _ ->
+ %% No matching data types, return an error.
+ {error, {unknown_field_type, Key}}
+ end.
%% @spec format_failure_reason(FailureReason :: {atom(), term()}) -> string().
%%
@@ -160,21 +165,6 @@ timestamp() ->
{MegaSeconds,Seconds,MilliSeconds}=erlang:now(),
(MegaSeconds * 1000000000000) + (Seconds * 1000000) + MilliSeconds.
-%% @spec field_types() -> data_type_defs().
-%%
-%% @doc Return a list of {Regex, Function} records that map a
-%% field name to a field type.
-field_types() ->
- F = fun(S) ->
- {ok, RE} = re:compile(S),
- RE
- end,
- [
- {F(".*_id"), fun parse_id/1},
- {F(".*_int"), fun parse_integer/1},
- {F(".*_float"), fun parse_float/1}
- ].
-
%% @private
%% @spec parse_id(string()) -> {ok, string()}
%%
@@ -256,85 +246,77 @@ parse_float_test() ->
parse_field_id_test() ->
%% Test parsing of "*_id" fields...
- Types = field_types(),
- F = fun(Key, Value) -> parse_field(Key, Value, Types) end,
?assertMatch(
{ok, ""},
- F("field_id", "")),
+ parse_field("field_id", "")),
?assertMatch(
{ok, "A"},
- F("field_id", "A")),
+ parse_field("field_id", "A")),
?assertMatch(
{ok, "123"},
- F("field_id", "123")).
+ parse_field("field_id", "123")).
parse_field_integer_test() ->
%% Test parsing of "*_int" fields...
- Types = field_types(),
- F = fun(Key, Value) -> parse_field(Key, Value, Types) end,
?assertMatch(
{error, {field_parsing_failed, {"field_int", ""}}},
- F("field_int", "")),
+ parse_field("field_int", "")),
?assertMatch(
{error, {field_parsing_failed, {"field_int", "A"}}},
- F("field_int", "A")),
+ parse_field("field_int", "A")),
?assertMatch(
{ok, 123},
- F("field_int", "123")),
+ parse_field("field_int", "123")),
?assertMatch(
{error, {field_parsing_failed, {"field_int", "4.56"}}},
- F("field_int", "4.56")),
+ parse_field("field_int", "4.56")),
?assertMatch(
{error, {field_parsing_failed, {"field_int", ".789"}}},
- F("field_int", ".789")).
+ parse_field("field_int", ".789")).
validate_field_float_test() ->
%% Test parsing of "*_float" fields...
- Types = field_types(),
- F = fun(Key, Value) -> parse_field(Key, Value, Types) end,
?assertMatch(
{error, {field_parsing_failed, {"field_float", ""}}},
- F("field_float", "")),
+ parse_field("field_float", "")),
?assertMatch(
{error, {field_parsing_failed, {"field_float", "A"}}},
- F("field_float", "A")),
+ parse_field("field_float", "A")),
?assertMatch(
{ok, 123.0},
- F("field_float", "123")),
+ parse_field("field_float", "123")),
?assertMatch(
{ok, 4.56},
- F("field_float", "4.56")),
+ parse_field("field_float", "4.56")),
?assertMatch(
{ok, 0.789},
- F("field_float", ".789")),
+ parse_field("field_float", ".789")),
?assertMatch(
{ok, 1.0e5},
- F("field_float", "1.0e5")).
+ parse_field("field_float", "1.0e5")).
validate_unknown_field_type_test() ->
%% Test error on unknown field types.
- Types = field_types(),
- F = fun(Key, Value) -> parse_field(Key, Value, Types) end,
?assertMatch(
{error, {unknown_field_type, "unknowntype"}},
- F("unknowntype", "A")).
+ parse_field("unknowntype", "A")).
validate_object_test() ->
%% Helper function to create an object using a proplist of
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment