From 3b6ad6e92dcb55833e9add829b2871be8468a68e Mon Sep 17 00:00:00 2001 From: Martin Sumner Date: Thu, 26 Jan 2023 23:38:44 +0000 Subject: [PATCH] Mas i1847 conditionalput (#410) * Add get_vtag support Tries to mirror vtag as defined by the riak HTTP API. The vtag is the vtag on a singleton metadata object, otherwise it is an bas62 encoded version of the vector clock * Update etag definition * Correct type --- src/riakc_obj.erl | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/riakc_obj.erl b/src/riakc_obj.erl index a4d1469c..bffd9ca1 100644 --- a/src/riakc_obj.erl +++ b/src/riakc_obj.erl @@ -42,6 +42,7 @@ get_content_types/1, get_value/1, get_values/1, + get_vtag/1, update_metadata/2, update_value/2, update_value/3, @@ -226,6 +227,55 @@ get_metadata(O=#riakc_obj{}) -> get_metadatas(#riakc_obj{contents=Contents}) -> [M || {M,_V} <- Contents]. +-spec get_vtag(riakc_obj()) -> binary(). +get_vtag(Obj) -> + case get_metadatas(Obj) of + [M] -> + case dict:find(?MD_VTAG, M) of + {ok, Vtag} -> + Vtag; + _ -> + throw(no_vtag) + end; + _Ms -> + vclock_etag(Obj) + end. + +-spec vclock_etag(riakc_obj()) -> string(). +vclock_etag(Obj) -> + <> + = crypto:hash( + md5, + zlib:unzip(riakc_obj:vclock(Obj))), + "\"" ++ integer_to_base(ETag, 62) ++ "\"". + +%% @doc based on riak_core_util:integer_to_list/2. +-spec integer_to_base(Integer :: integer(), Base :: integer()) -> string(). +integer_to_base(I, Base) + when is_integer(I), is_integer(Base), Base >= 2, Base =< 62 -> + integer_to_base(I, Base, []). + +-spec integer_to_base(integer(), integer(), string()) -> string(). +integer_to_base(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_base(I1, Base, R1) + end. + + %% @doc Return the content type of the value if there are no siblings. %% @see get_metadata/1 %% @throws siblings