You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2009/01/16 00:12:57 UTC

svn commit: r734849 - in /couchdb/trunk/src/couchdb: couch_db.erl couch_httpd.erl couch_httpd_db.erl

Author: damien
Date: Thu Jan 15 15:12:56 2009
New Revision: 734849

URL: http://svn.apache.org/viewvc?rev=734849&view=rev
Log:
Support for streaming attachment writes.

Modified:
    couchdb/trunk/src/couchdb/couch_db.erl
    couchdb/trunk/src/couchdb/couch_httpd.erl
    couchdb/trunk/src/couchdb/couch_httpd_db.erl

Modified: couchdb/trunk/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.erl?rev=734849&r1=734848&r2=734849&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db.erl Thu Jan 15 15:12:56 2009
@@ -400,7 +400,9 @@
                 % written to a different file
                 SizeAcc + Len;
             {_Key, {_Type, Bin}} when is_binary(Bin) ->
-                SizeAcc + size(Bin)
+                SizeAcc + size(Bin);
+            {_Key, {_Type, {Fun, Len}}} when is_function(Fun) ->
+                SizeAcc + Len
             end
         end,
         0, Bins),
@@ -433,7 +435,11 @@
                 {Fd, NewStreamPointer, Len};
             Bin when is_binary(Bin) ->
                 {ok, StreamPointer} = couch_stream:write(OutputStream, Bin),
-                {Fd, StreamPointer, size(Bin)}
+                {Fd, StreamPointer, size(Bin)};
+            {Fun, Len} when is_function(Fun) ->
+                {ok, StreamPointer} =
+                        write_streamed_attachment(OutputStream, Fun, Len, nil),
+                {Fd, StreamPointer, Len}
             end,
             {Key, {Type, NewBinValue}}
         end, Bins),
@@ -441,6 +447,17 @@
     {ok, _FinalPos} = couch_stream:close(OutputStream),
 
     Doc#doc{attachments = NewBins}.
+    
+write_streamed_attachment(_Stream, _F, 0, SpAcc) ->
+    {ok, SpAcc};
+write_streamed_attachment(Stream, F, LenLeft, nil) ->
+    Bin = F(),
+    {ok, StreamPointer} = couch_stream:write(Stream, Bin),
+    write_streamed_attachment(Stream, F, LenLeft - size(Bin), StreamPointer);
+write_streamed_attachment(Stream, F, LenLeft, SpAcc) ->
+    Bin = F(),
+    {ok, _} = couch_stream:write(Stream, Bin),
+    write_streamed_attachment(Stream, F, LenLeft - size(Bin), SpAcc).
 
 enum_docs_since_reduce_to_count(Reds) ->
     couch_btree:final_reduce(

Modified: couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=734849&r1=734848&r2=734849&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd.erl Thu Jan 15 15:12:56 2009
@@ -16,7 +16,7 @@
 -export([start_link/0, stop/0, handle_request/3]).
 
 -export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1]).
--export([verify_is_server_admin/1,unquote/1]).
+-export([verify_is_server_admin/1,unquote/1,recv/2]).
 -export([parse_form/1,json_body/1,body/1,doc_etag/1]).
 -export([primary_header_value/2,partition/1,serve_file/3]).
 -export([start_chunked_response/3,send_chunk/2]).
@@ -244,6 +244,9 @@
 parse_form(#httpd{mochi_req=MochiReq}) ->
     mochiweb_multipart:parse_form(MochiReq).
 
+recv(#httpd{mochi_req=MochiReq}, Len) ->
+    MochiReq:recv(Len).
+
 body(#httpd{mochi_req=MochiReq}) ->
     MochiReq:recv_body(?MAX_DOC_SIZE).
 

Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=734849&r1=734848&r2=734849&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Thu Jan 15 15:12:56 2009
@@ -255,7 +255,7 @@
 
 % Special case to enable using an unencoded slash in the URL of design docs, 
 % as slashes in document IDs must otherwise be URL encoded.
-db_req(#httpd{method='GET',mochi_req=MochiReq, path_parts=[DbName,<<"_design/",Name/binary>>|Rest]}=Req, Db) ->
+db_req(#httpd{method='GET',mochi_req=MochiReq, path_parts=[DbName,<<"_design/",_/binary>>|_]}=Req, _Db) ->
     PathFront = "/" ++ binary_to_list(DbName) ++ "/_design",
     {ok, [PathFront|PathTail]} = regexp:split(MochiReq:get(raw_path),"%2F"),
     RedirectTo = PathFront ++ "/" ++ mochiweb_util:join(PathTail, "%2F"),
@@ -279,7 +279,6 @@
         start_key = StartKey,
         start_docid = StartDocId,
         end_key = EndKey,
-        end_docid = EndDocId,
         limit = Limit,
         skip = SkipCount,
         direction = Dir
@@ -590,7 +589,12 @@
         _ ->
             [{FileName, {
                 list_to_binary(couch_httpd:header_value(Req,"Content-Type")),
-                couch_httpd:body(Req)
+                case couch_httpd:header_value(Req,"Content-Length") of
+                undefined -> 
+                    throw({bad_request, "Attachment uploads must be fixed length"});
+                Length -> 
+                    {fun() -> couch_httpd:recv(Req, 0) end, list_to_integer(Length)}
+                end
             }}]
     end,