summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_doc.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couchdb/couch_doc.erl')
-rw-r--r--src/couchdb/couch_doc.erl30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/couchdb/couch_doc.erl b/src/couchdb/couch_doc.erl
index 1eb1575a..9860ac0c 100644
--- a/src/couchdb/couch_doc.erl
+++ b/src/couchdb/couch_doc.erl
@@ -51,7 +51,13 @@ to_json_revs_info(Meta) ->
to_json_attachment_stubs(Attachments) ->
BinProps = lists:map(
- fun({Name, {Type, BinValue}}) ->
+ fun({Name, {Type, {_RcvFun, Length}}}) ->
+ {Name, {[
+ {<<"stub">>, true},
+ {<<"content_type">>, Type},
+ {<<"length">>, Length}
+ ]}};
+ ({Name, {Type, BinValue}}) ->
{Name, {[
{<<"stub">>, true},
{<<"content_type">>, Type},
@@ -66,7 +72,13 @@ to_json_attachment_stubs(Attachments) ->
to_json_attachments(Attachments) ->
BinProps = lists:map(
- fun({Name, {Type, BinValue}}) ->
+ fun({Name, {Type, {RcvFun, Length}}}) ->
+ Data = read_streamed_attachment(RcvFun, Length, _Acc = []),
+ {Name, {[
+ {<<"content_type">>, Type},
+ {<<"data">>, couch_util:encodeBase64(Data)}
+ ]}};
+ ({Name, {Type, BinValue}}) ->
{Name, {[
{<<"content_type">>, Type},
{<<"data">>, couch_util:encodeBase64(bin_to_binary(BinValue))}
@@ -100,7 +112,9 @@ from_json_obj({Props}) ->
Bins = lists:flatmap(fun({Name, {BinProps}}) ->
case proplists:get_value(<<"stub">>, BinProps) of
true ->
- [{Name, stub}];
+ Type = proplists:get_value(<<"content_type">>, BinProps),
+ Length = proplists:get_value(<<"length">>, BinProps),
+ [{Name, {stub, Type, Length}}];
_ ->
Value = proplists:get_value(<<"data">>, BinProps),
Type = proplists:get_value(<<"content_type">>, BinProps,
@@ -225,7 +239,7 @@ has_stubs(#doc{attachments=Bins}) ->
has_stubs(Bins);
has_stubs([]) ->
false;
-has_stubs([{_Name, stub}|_]) ->
+has_stubs([{_Name, {stub, _, _}}|_]) ->
true;
has_stubs([_Bin|Rest]) ->
has_stubs(Rest).
@@ -233,9 +247,15 @@ has_stubs([_Bin|Rest]) ->
merge_stubs(#doc{attachments=MemBins}=StubsDoc, #doc{attachments=DiskBins}) ->
BinDict = dict:from_list(DiskBins),
MergedBins = lists:map(
- fun({Name, stub}) ->
+ fun({Name, {stub, _, _}}) ->
{Name, dict:fetch(Name, BinDict)};
({Name, Value}) ->
{Name, Value}
end, MemBins),
StubsDoc#doc{attachments= MergedBins}.
+
+read_streamed_attachment(_RcvFun, 0, Acc) ->
+ list_to_binary(lists:reverse(Acc));
+read_streamed_attachment(RcvFun, LenLeft, Acc) ->
+ Bin = RcvFun(),
+ read_streamed_attachment(RcvFun, LenLeft - size(Bin), [Bin|Acc]).