Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #74 from nifoc/fixes/riak_search

Riak Adapter Improvements
  • Loading branch information...
commit e2764be51bcff99f2d4d4199a64bb1c646b9f2fd 2 parents ddd88ac + 22f2ee8
@evanmiller evanmiller authored
Showing with 46 additions and 78 deletions.
  1. +46 −78 src/db_adapters/boss_db_adapter_riak.erl
View
124 src/db_adapters/boss_db_adapter_riak.erl
@@ -8,10 +8,8 @@
-define(HUGE_INT, 1000 * 1000 * 1000 * 1000).
-start(_Options) ->
- % TODO: crypto is needed for unique_id_62/0. Remove it when
- % unique_id_62/0 is not needed.
- crypto:start().
+start(_) ->
+ ok.
stop() ->
ok.
@@ -28,11 +26,12 @@ find(Conn, Id) ->
{Type, Bucket, Key} = infer_type_from_id(Id),
case riakc_pb_socket:get(Conn, Bucket, Key) of
{ok, Res} ->
- Value = riakc_obj:get_value (Res),
+ Value = riakc_obj:get_value(Res),
Data = binary_to_term(Value),
+ ConvertedData = riak_search_decode_data(Data),
AttributeTypes = boss_record_lib:attribute_types(Type),
Record = apply(Type, new, lists:map(fun (AttrName) ->
- Val = proplists:get_value(AttrName, Data),
+ Val = proplists:get_value(AttrName, ConvertedData),
AttrType = proplists:get_value(AttrName, AttributeTypes),
boss_record_lib:convert_value_to_type(Val, AttrType)
end, boss_record_lib:attribute_names(Type))),
@@ -56,12 +55,14 @@ find_acc(Conn, Prefix, [Id | Rest], Acc) ->
find(Conn, Type, Conditions, Max, Skip, Sort, SortOrder) ->
Bucket = type_to_bucket_name(Type),
{ok, Keys} = case Conditions of
- [] ->
+ [] ->
riakc_pb_socket:list_keys(Conn, Bucket);
_ ->
{ok, {search_results, KeysExt, _, _}} = riakc_pb_socket:search(
Conn, Bucket, build_search_query(Conditions)),
- {ok, lists:map(fun ([{_,X}])-> X end, KeysExt)}
+ {ok, lists:map(fun ({_,X})->
+ proplists:get_value(<<"id">>, X)
+ end, KeysExt)}
end,
Records = find_acc(Conn, atom_to_list(Type) ++ "-", Keys, []),
Sorted = if
@@ -78,10 +79,9 @@ find(Conn, Type, Conditions, Max, Skip, Sort, SortOrder) ->
case Max of
all -> lists:nthtail(Skip, Sorted);
Max when Skip < length(Sorted) ->
- lists:sublist(Sorted, Skip + 1, Max);
- _ ->
- []
-
+ lists:sublist(Sorted, Skip + 1, Max);
+ _ ->
+ []
end.
% this is a stub just to make the tests runable
@@ -104,26 +104,22 @@ delete(Conn, Id) ->
save_record(Conn, Record) ->
Type = element(1, Record),
Bucket = list_to_binary(type_to_bucket_name(Type)),
- PropList = [{K, V} || {K, V} <- Record:attributes(), K =/= id],
- Key = case Record:id() of
- id ->
- % TODO: The next release of Riak will support server-side ID
- % generating. Get rid of unique_id_62/0.
- unique_id_62();
- DefinedId when is_list(DefinedId) ->
+ PropList = [{riak_search_encode_key(K), riak_search_encode_value(V)} || {K, V} <- Record:attributes(), K =/= id],
+ RiakKey = case Record:id() of
+ id -> % New entry
+ O = riakc_obj:new(Bucket, undefined, PropList),
+ {ok, RO} = riakc_pb_socket:put(Conn, O),
+ binary_to_list(element(3, RO));
+ DefinedId when is_list(DefinedId) -> % Existing Entry
[_ | Tail] = string:tokens(DefinedId, "-"),
- string:join(Tail, "-")
- end,
- BinKey = list_to_binary(Key),
- ok = case riakc_pb_socket:get(Conn, Bucket, BinKey) of
- {ok, O} ->
+ Key = string:join(Tail, "-"),
+ BinKey = list_to_binary(Key),
+ {ok, O} = riakc_pb_socket:get(Conn, Bucket, BinKey),
O2 = riakc_obj:update_value(O, PropList),
- riakc_pb_socket:put(Conn, O2);
- {error, _} ->
- O = riakc_obj:new(Bucket, BinKey, PropList, <<"application/x-erlang-term">>),
- riakc_pb_socket:put(Conn, O)
+ ok = riakc_pb_socket:put(Conn, O2),
+ Key
end,
- {ok, Record:set(id, lists:concat([Type, "-", Key]))}.
+ {ok, Record:set(id, lists:concat([Type, "-", RiakKey]))}.
% These 2 functions are not part of the behaviour but are required for
% tests to pass
@@ -147,53 +143,6 @@ type_to_bucket_name(Type) when is_atom(Type) ->
type_to_bucket_name(Type) when is_list(Type) ->
inflector:pluralize(Type).
-% Unique key generator (copy&pasted from riak_core_util.erl)
-% see https://github.com/basho/riak_core/blob/master/src/riak_core_util.erl#L131
-% for details.
-% TODO: Get rid of this code when server-side ID generating is available
-% in Riak.
-
-%% @spec integer_to_list0(Integer :: integer(), Base :: integer()) ->
-%% string()
-%% @doc Convert an integer to its string representation in the given
-%% base. Bases 2-62 are supported.
-integer_to_list0(I, 10) ->
- erlang:integer_to_list(I);
-integer_to_list0(I, Base)
- when is_integer(I), is_integer(Base),Base >= 2, Base =< 1+$Z-$A+10+1+$z-$a ->
- if I < 0 ->
- [$-|integer_to_list0(-I, Base, [])];
- true ->
- integer_to_list0(I, Base, [])
- end;
-integer_to_list0(I, Base) ->
- erlang:error(badarg, [I, Base]).
-
-%% @spec integer_to_list0(integer(), integer(), string()) -> string()
-integer_to_list0(I0, Base, R0) ->
- D = I0 rem Base,
- I1 = I0 div Base,
- R1 = if D >= 36 ->
- [D-36+$a|R0];
- D >= 10 ->
- [D-10+$A|R0];
- true ->
- [D+$0|R0]
- end,
- if I1 =:= 0 ->
- R1;
- true ->
- integer_to_list0(I1, Base, R1)
- end.
-
-%% @spec unique_id_62() -> string()
-%% @doc Create a random identifying integer, returning its string
-%% representation in base 62.
-unique_id_62() ->
- Rand = crypto:sha(term_to_binary({make_ref(), now()})),
- <<I:160/integer>> = Rand,
- integer_to_list0(I, 62).
-
build_search_query(Conditions) ->
Terms = build_search_query(Conditions, []),
string:join(Terms, " AND ").
@@ -264,9 +213,28 @@ escape_value(Value) ->
escape_value([], Acc) ->
lists:reverse(Acc);
-escape_value([H|T], Acc) when H=:=$+; H=:=$-; H=:=$&; H=:=$|; H=:=$!; H=:=$(; H=:=$);
- H=:=$[; H=:=$]; H=:=${; H=:=$}; H=:=$^; H=:=$"; H=:=$~;
+escape_value([H|T], Acc) when H=:=$+; H=:=$-; H=:=$&; H=:=$|; H=:=$!; H=:=$(; H=:=$);
+ H=:=$[; H=:=$]; H=:=${; H=:=$}; H=:=$^; H=:=$"; H=:=$~;
H=:=$*; H=:=$?; H=:=$:; H=:=$\\ ->
escape_value(T, lists:reverse([$\\, H], Acc));
escape_value([H|T], Acc) ->
escape_value(T, [H|Acc]).
+
+riak_search_encode_key(K) ->
+ list_to_binary(atom_to_list(K)).
+
+riak_search_encode_value(V) when is_list(V) ->
+ list_to_binary(V);
+riak_search_encode_value(V) ->
+ V.
+
+riak_search_decode_data(Data) ->
+ [{riak_search_decode_key(K), riak_search_decode_value(V)} || {K, V} <- Data].
+
+riak_search_decode_key(K) ->
+ list_to_atom(binary_to_list(K)).
+
+riak_search_decode_value(V) when is_binary(V) ->
+ binary_to_list(V);
+riak_search_decode_value(V) ->
+ V.
Please sign in to comment.
Something went wrong with that request. Please try again.