From a3886989b9e09ca5d01e18f1e39e9dae0f280530 Mon Sep 17 00:00:00 2001 From: "Damien F. Katz" Date: Fri, 25 Jun 2010 05:18:28 +0000 Subject: Added checking to ensure when a revpos is sent with a stub, it's correct. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@957800 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/attachments.js | 20 +++++++++++++------- src/couchdb/couch_doc.erl | 11 ++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/share/www/script/test/attachments.js b/share/www/script/test/attachments.js index 322a4f50..9d89d5d0 100644 --- a/share/www/script/test/attachments.js +++ b/share/www/script/test/attachments.js @@ -255,13 +255,19 @@ couchTests.attachments= function(debug) { } } } - var save_response = db.save(bin_doc6); - bin_doc6._rev = save_response["rev"]; + T(db.save(bin_doc6).ok); // stub out the attachment bin_doc6._attachments["foo.txt"] = { stub: true }; - - var xhr = CouchDB.request("PUT", "/test_suite_db/bin_doc6", { - body: JSON.stringify(bin_doc6) - }); - TEquals(201, xhr.status, "should send 201 Created when attachment stub contains only the 'stub' field"); + T(db.save(bin_doc6).ok == true); + + // wrong rev pos specified + + // stub out the attachment with the wrong revpos + bin_doc6._attachments["foo.txt"] = { stub: true, revpos: 10}; + try { + T(db.save(bin_doc6).ok == true); + T(false && "Shouldn't get here!"); + } catch (e) { + T(e.error == "missing_stub") + } }; diff --git a/src/couchdb/couch_doc.erl b/src/couchdb/couch_doc.erl index 0a71f2e3..50dbd9d0 100644 --- a/src/couchdb/couch_doc.erl +++ b/src/couchdb/couch_doc.erl @@ -198,7 +198,7 @@ transfer_fields([{<<"_attachments">>, {JsonBins}} | Rest], Doc) -> case couch_util:get_value(<<"stub">>, BinProps) of true -> Type = couch_util:get_value(<<"content_type">>, BinProps), - RevPos = couch_util:get_value(<<"revpos">>, BinProps, 0), + RevPos = couch_util:get_value(<<"revpos">>, BinProps, nil), DiskLen = couch_util:get_value(<<"length">>, BinProps), {Enc, EncLen} = att_encoding_info(BinProps), #att{name=Name, data=stub, type=Type, att_len=EncLen, @@ -309,8 +309,8 @@ att_foldl(#att{data=DataFun,att_len=Len}, Fun, Acc) when is_function(DataFun) -> att_foldl_decode(#att{data={Fd,Sp},md5=Md5,encoding=Enc}, Fun, Acc) -> couch_stream:foldl_decode(Fd, Sp, Md5, Enc, Fun, Acc); -att_foldl_decode(#att{data=Fun,att_len=Len, encoding=identity}, Fun, Acc) -> - fold_streamed_data(Fun, Len, Fun, Acc). +att_foldl_decode(#att{data=Fun2,att_len=Len, encoding=identity}, Fun, Acc) -> + fold_streamed_data(Fun2, Len, Fun, Acc). att_to_bin(#att{data=Bin}) when is_binary(Bin) -> Bin; @@ -357,9 +357,10 @@ has_stubs([_Att|Rest]) -> merge_stubs(#doc{id=Id,atts=MemBins}=StubsDoc, #doc{atts=DiskBins}) -> BinDict = dict:from_list([{Name, Att} || #att{name=Name}=Att <- DiskBins]), MergedBins = lists:map( - fun(#att{name=Name, data=stub}) -> + fun(#att{name=Name, data=stub, revpos=StubRevPos}) -> case dict:find(Name, BinDict) of - {ok, #att{}=DiskAtt} -> + {ok, #att{revpos=DiskRevPos}=DiskAtt} + when DiskRevPos == StubRevPos orelse StubRevPos == nil -> DiskAtt; _ -> throw({missing_stub, -- cgit v1.2.3