diff --git a/include/riak_pb_kv_codec.hrl b/include/riak_pb_kv_codec.hrl index 45d2adc5..80dca5e4 100644 --- a/include/riak_pb_kv_codec.hrl +++ b/include/riak_pb_kv_codec.hrl @@ -29,6 +29,7 @@ -define(MD_LASTMOD, <<"X-Riak-Last-Modified">>). -define(MD_USERMETA, <<"X-Riak-Meta">>). -define(MD_INDEX, <<"index">>). +-define(MD_DELETED, <<"X-Riak-Deleted">>). %% Content-Type for Erlang term_to_binary format -define(CTYPE_ERLANG_BINARY, "application/x-erlang-binary"). diff --git a/src/riak_kv.proto b/src/riak_kv.proto index 43198760..9e8fe2a4 100644 --- a/src/riak_kv.proto +++ b/src/riak_kv.proto @@ -186,6 +186,7 @@ message RpbContent { optional uint32 last_mod_usecs = 8; repeated RpbPair usermeta = 9; // user metadata stored with the object repeated RpbPair indexes = 10; // user metadata stored with the object + optional bool deleted = 11; } // Link metadata diff --git a/src/riak_pb_kv_codec.erl b/src/riak_pb_kv_codec.erl index 53389037..d496c56a 100644 --- a/src/riak_pb_kv_codec.erl +++ b/src/riak_pb_kv_codec.erl @@ -96,11 +96,25 @@ encode_content_meta(?MD_USERMETA, UserMeta, PbContent) when is_list(UserMeta) -> PbContent#rpbcontent{usermeta = [encode_pair(E) || E <- UserMeta]}; encode_content_meta(?MD_INDEX, Indexes, PbContent) when is_list(Indexes) -> PbContent#rpbcontent{indexes = [encode_pair(E) || E <- Indexes]}; +encode_content_meta(?MD_DELETED, DeletedVal, PbContent) -> + PbContent#rpbcontent{deleted=header_val_to_bool(DeletedVal)}; encode_content_meta(_Key, _Value, PbContent) -> %% Ignore unknown metadata - need to add to RpbContent if it needs to make it %% to/from the client PbContent. +%% @doc Return a boolean based on a header value. +%% Representations of `true' return `true'; anything +%% else returns `false'. +-spec header_val_to_bool(term()) -> boolean(). +header_val_to_bool(<<"true">>) -> + true; +header_val_to_bool("true") -> + true; +header_val_to_bool(true) -> + true; +header_val_to_bool(_) -> + false. %% @doc Convert a list of rpbcontent pb messages to a list of [{MetaData,Value}] tuples -spec decode_contents(PBContents::[tuple()]) -> contents(). @@ -136,7 +150,10 @@ decode_content_meta(usermeta, PbUserMeta, _Pb) -> [{?MD_USERMETA, UserMeta}]; decode_content_meta(indexes, PbIndexes, _Pb) -> Indexes = [decode_pair(E) || E <- PbIndexes], - [{?MD_INDEX, Indexes}]. + [{?MD_INDEX, Indexes}]; +decode_content_meta(deleted, DeletedVal, _Pb) -> + [{?MD_DELETED, DeletedVal}]. + %% @doc Convert an rpccontent pb message to an erlang {MetaData,Value} tuple -spec decode_content(PBContent::tuple()) -> {riakc_obj:metadata(), riakc_obj:value()}. @@ -148,7 +165,8 @@ decode_content(PbC) -> decode_content_meta(links, PbC#rpbcontent.links, PbC) ++ decode_content_meta(last_mod, PbC#rpbcontent.last_mod, PbC) ++ decode_content_meta(usermeta, PbC#rpbcontent.usermeta, PbC) ++ - decode_content_meta(indexes, PbC#rpbcontent.indexes, PbC), + decode_content_meta(indexes, PbC#rpbcontent.indexes, PbC) ++ + decode_content_meta(deleted, PbC#rpbcontent.deleted, PbC), {dict:from_list(MD), PbC#rpbcontent.value}. diff --git a/test/encoding_test.erl b/test/encoding_test.erl index 0186b879..672bc9ca 100644 --- a/test/encoding_test.erl +++ b/test/encoding_test.erl @@ -18,7 +18,8 @@ pb_test_() -> {?MD_USERMETA, [{"X-Riak-Meta-MyMetaData1","here it is"}, {"X-Riak-Meta-MoreMd", "have some more"} ]}, - {?MD_INDEX, []} + {?MD_INDEX, []}, + {?MD_DELETED, true} ]), Value = <<"test value">>, {MetaData2, Value2} = riak_pb_kv_codec:decode_content( @@ -30,6 +31,24 @@ pb_test_() -> ?assertEqual(true, MdSame), Value = Value2 end)}, +{"deleted header encode decode", + ?_test(begin + InputMD = [dict:from_list([{?MD_DELETED, DelVal}]) || + DelVal <- [true, "true", false, <<"rubbish">>]], + Value = <<"test value">>, + {OutputMD, _} = lists:unzip( + [riak_pb_kv_codec:decode_content( + riak_kv_pb:decode_rpbcontent( + riak_kv_pb:encode_rpbcontent( + riak_pb_kv_codec:encode_content({MD, Value})))) || + MD <- InputMD]), + MdSame1 = (lists:sort(dict:to_list(lists:nth(1, OutputMD))) =:= + lists:sort(dict:to_list(lists:nth(2, OutputMD)))), + MdSame2 = (lists:sort(dict:to_list(lists:nth(3, OutputMD))) =:= + lists:sort(dict:to_list(lists:nth(4, OutputMD)))), + ?assertEqual(true, MdSame1), + ?assertEqual(true, MdSame2) + end)}, {"empty content encode decode", ?_test(begin MetaData = dict:new(),