You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by cm...@apache.org on 2008/08/30 12:26:52 UTC

svn commit: r690487 - in /incubator/couchdb/trunk: src/couchdb/couch_config.erl src/couchdb/couch_config_writer.erl src/couchdb/couch_httpd.erl test/runner.sh

Author: cmlenz
Date: Sat Aug 30 03:26:51 2008
New Revision: 690487

URL: http://svn.apache.org/viewvc?rev=690487&view=rev
Log:
Some cosmetic cleanup (removed trailing whitespace, fixed indentation, make the test runner script executable).

Modified:
    incubator/couchdb/trunk/src/couchdb/couch_config.erl
    incubator/couchdb/trunk/src/couchdb/couch_config_writer.erl
    incubator/couchdb/trunk/src/couchdb/couch_httpd.erl
    incubator/couchdb/trunk/test/runner.sh   (props changed)

Modified: incubator/couchdb/trunk/src/couchdb/couch_config.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/src/couchdb/couch_config.erl?rev=690487&r1=690486&r2=690487&view=diff
==============================================================================
--- incubator/couchdb/trunk/src/couchdb/couch_config.erl (original)
+++ incubator/couchdb/trunk/src/couchdb/couch_config.erl Sat Aug 30 03:26:51 2008
@@ -11,9 +11,9 @@
 % the License.
 
 %% @doc Reads CouchDB's ini file and gets queried for configuration parameters.
-%%      This module is initialized with a list of ini files that it 
-%%      consecutively reads Key/Value pairs from and saves them in an ets 
-%%      table. If more an one ini file is specified, the last one is used to 
+%%      This module is initialized with a list of ini files that it
+%%      consecutively reads Key/Value pairs from and saves them in an ets
+%%      table. If more an one ini file is specified, the last one is used to
 %%      write changes that are made with store/2 back to that ini file.
 
 -module(couch_config).
@@ -21,13 +21,13 @@
 
 -behaviour(gen_server).
 -export([start_link/1, init/1,
-    handle_call/3, handle_cast/2, handle_info/2, 
+    handle_call/3, handle_cast/2, handle_info/2,
     terminate/2, code_change/3]).
--export([store/2, register/1, register/2, 
+-export([store/2, register/1, register/2,
     get/1, get/2,
     lookup_match/1, lookup_match/2,
     all/0, unset/1, load_ini_file/1]).
-    
+
 -record(config,
     {notify_funs=[],
     writeback_filename=""
@@ -37,7 +37,7 @@
 
 %% @type etstable() = integer().
 
-start_link(IniFiles) -> gen_server:start_link({local, ?MODULE}, ?MODULE, IniFiles, []).  
+start_link(IniFiles) -> gen_server:start_link({local, ?MODULE}, ?MODULE, IniFiles, []).
 
 %% @spec store(Key::any(), Value::any()) -> {ok, Tab::etsatable()}
 %% @doc Public API function that triggers storage of a Key/Value pair into the
@@ -57,12 +57,12 @@
     fix_lookup_result(ets:lookup(?MODULE, Key), Default).
 
 %% @spec lookup_match(Key::any()) -> Value::any() | undefined:atom()
-%% @doc Lets you look for a Key's Value specifying a pattern that gets passed 
+%% @doc Lets you look for a Key's Value specifying a pattern that gets passed
 %%      to ets::match(). Returns undefined::atom() if no Key is found.
 lookup_match(Key) -> gen_server:call(?MODULE, {lookup_match, Key}).
 
 %% @spec lookup_match(Key::any(), Default::any()) -> Value::any() | Default
-%% @doc Lets you look for a Key's Value specifying a pattern that gets passed 
+%% @doc Lets you look for a Key's Value specifying a pattern that gets passed
 %%      to ets::match(). Returns Default::any() if no Key is found
 lookup_match(Key, Default) -> gen_server:call(?MODULE, {lookup_match, Key, Default}).
 
@@ -74,7 +74,7 @@
 register(Fun, Pid) -> gen_server:call(?MODULE, {register, Fun, Pid}).
 
 %% @spec unset(Key::any) -> ok
-%% @doc Public API call to remove the configuration entry from the internal 
+%% @doc Public API call to remove the configuration entry from the internal
 %%      ets table. This change is _not_ written to the storage ini file.
 unset(Key) -> gen_server:call(?MODULE, {unset, Key}).
 
@@ -115,7 +115,7 @@
 handle_call({register, Fun, Pid}, _From, #config{notify_funs=PidFuns}=Config) ->
     erlang:monitor(process, Pid),
     {reply, ok, Config#config{notify_funs=[{Pid, Fun}|PidFuns]}}.
-    
+
 
 fix_lookup_result([{_Key, Value}], _Default) ->
     Value;
@@ -125,7 +125,7 @@
     [list_to_tuple(Value) || Value <- Values].
 
 %% @spec insert_and_commit(Tab::etstable(), Config::any()) -> ok
-%% @doc Inserts a Key/Value pair into the ets table, writes it to the storage 
+%% @doc Inserts a Key/Value pair into the ets table, writes it to the storage
 %%      ini file and calls all registered callback functions for Key.
 insert_and_commit(Config, KV) ->
     true = ets:insert(?MODULE, KV),
@@ -146,7 +146,7 @@
            io:format("~s~n", [Msg]),
            throw({startup_error, Msg})
     end,
-    
+
     {ok, Lines} = regexp:split(binary_to_list(IniBin), "\r\n|\n|\r|\032"),
     {_, ParsedIniValues} =
     lists:foldl(fun(Line, {AccSectionName, AccValues}) ->
@@ -173,7 +173,7 @@
                 end
             end
         end, {"", []}, Lines),
-        
+
         [ets:insert(?MODULE, {Key, Value}) || {Key, Value} <- ParsedIniValues],
     ok.
 

Modified: incubator/couchdb/trunk/src/couchdb/couch_config_writer.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/src/couchdb/couch_config_writer.erl?rev=690487&r1=690486&r2=690487&view=diff
==============================================================================
--- incubator/couchdb/trunk/src/couchdb/couch_config_writer.erl (original)
+++ incubator/couchdb/trunk/src/couchdb/couch_config_writer.erl Sat Aug 30 03:26:51 2008
@@ -24,24 +24,24 @@
 -export([save_to_file/2]).
 
 %% @spec save_to_file(
-%%           Config::{{Module::string(), Variable::string()}, Value::string()}, 
+%%           Config::{{Module::string(), Variable::string()}, Value::string()},
 %%           File::filename()) -> ok
 %% @doc Saves a Module/Key/Value triple to the ini file File::filename()
 save_to_file({{Module, Variable}, Value}, File) ->
-    
+
     ?LOG_DEBUG("saving to file '~s', Congif: '~p'", [File, {{Module, Variable}, Value}]),
-    
+
     % open file and create a list of lines
     {ok, Stream} = file:read_file(File),
     OldFileContents = binary_to_list(Stream),
     {ok, Lines} = regexp:split(OldFileContents, "\r\n|\n|\r|\032"),
-    
+
     % prepare input variables
     ModuleName = "[" ++ Module ++ "]",
     VariableList = Variable,
-    
+
     % produce the contents for the config file
-    NewFileContents = 
+    NewFileContents =
     case NewFileContents2 = save_loop({{ModuleName, VariableList}, Value}, Lines, "", "", []) of
         % we didn't change anything, that means we couldn't find a matching
         % [ini section] in which case we just append a new one.
@@ -50,7 +50,7 @@
         _ ->
             NewFileContents2
     end,
-    
+
     % do the save, close the config file and get out
     save_file(File, NewFileContents),
     file:close(Stream),
@@ -102,7 +102,7 @@
 
     % go to next line
     save_loop({{Module, Variable}, Value}, Rest, NewCurrentModule, Contents2 ++ NewContents, DoneVariables2);
-    
+
 save_loop(_Config, [], _OldModule, NewFileContents, _DoneVariable) ->
     % we're out of new lines, just return the new file's contents
     NewFileContents.
@@ -111,7 +111,7 @@
     OldFileContents ++ "\n\n" ++ ModuleName ++ "\n" ++  Variable ++ "=" ++ Value ++ "\n".
 
 %% @spec parse_module(Lins::string(), OldModule::string()) -> string()
-%% @doc Tries to match a line against a pattern specifying a ini module or 
+%% @doc Tries to match a line against a pattern specifying a ini module or
 %%      section ("[Module]"). Returns OldModule if no match is found.
 parse_module(Line, OldModule) ->
     case regexp:match(Line, "^\\[([a-zA-Z0-9_-]*)\\]$") of
@@ -140,7 +140,7 @@
             Variable ++ "=" ++ Value
     end.
 
-%% @spec save_file(File::filename(), Contents::string()) -> 
+%% @spec save_file(File::filename(), Contents::string()) ->
 %%           ok | {error, Reason::string()}
 %% @doc Writes Contents to File
 save_file(File, Contents) ->

Modified: incubator/couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=690487&r1=690486&r2=690487&view=diff
==============================================================================
--- incubator/couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ incubator/couchdb/trunk/src/couchdb/couch_httpd.erl Sat Aug 30 03:26:51 2008
@@ -40,14 +40,14 @@
 
 start_link() ->
     % read config and register for configuration changes
-    
+
     % just stop if one of the config settings change. couch_server_sup
     % will restart us and then we will pick up the new settings.
-    
+
     BindAddress = couch_config:get({"HTTPd", "BindAddress"}, any),
     Port = couch_config:get({"HTTPd", "Port"}, "5984"),
     DocumentRoot = couch_config:get({"HTTPd", "DocumentRoot"}, "../../share/www"),
-    
+
     % and off we go
     Loop = fun (Req) -> apply(couch_httpd, handle_request, [Req, DocumentRoot]) end,
     {ok, Pid} = mochiweb_http:start([
@@ -64,7 +64,7 @@
         ({"HTTPd", "DocumentRoot"}) ->
             ?MODULE:stop()
         end, Pid),
-    
+
     {ok, Pid}.
 
 stop() ->
@@ -77,7 +77,7 @@
     % alias HEAD to GET as mochiweb takes care of stripping the body
     Method = case Req:get(method) of
         'HEAD' -> 'GET';
-        Other -> 
+        Other ->
           % handling of non standard HTTP verbs. Should be fixe din gen_tcp:recv()
           case Other of
             "COPY" -> 'COPY';
@@ -110,7 +110,7 @@
         Path,
         Resp:get(code)
     ]).
-    
+
 handle_request(Req, DocumentRoot, Method, Path) ->
     % Start = erlang:now(),
     X = handle_request0(Req, DocumentRoot, Method, Path),
@@ -222,11 +222,11 @@
     Error ->
         throw(Error)
     end;
-    
+
 handle_db_request(Req, Method, {DbName, Rest}) ->
     case couch_db:open(DbName, []) of
         {ok, Db} ->
-            try 
+            try
                 handle_db_request(Req, Method, {DbName, Db, Rest})
             after
                 couch_db:close(Db)
@@ -526,8 +526,8 @@
             Resp:write_chunk(AccSeparator ++ Json),
             {ok, {",",0,AccCount-1}};
         (Key, Red, {AccSeparator,0,AccCount})
-                when is_integer(GroupLevel) 
-                andalso is_tuple(Key) 
+                when is_integer(GroupLevel)
+                andalso is_tuple(Key)
                 andalso element(1, Key) /= obj  ->
             Json = lists:flatten(cjson:encode(
                 {obj, [{key, list_to_tuple(lists:sublist(tuple_to_list(Key), GroupLevel))},
@@ -641,57 +641,57 @@
     ]});
 
 handle_doc_request(Req, 'COPY', _DbName, Db, SourceDocId) ->
-  SourceRev = case extract_header_rev(Req) of
-    missing_rev -> [];
-    Rev -> Rev
-  end,
-  
-  {TargetDocId, TargetRev} = parse_copy_destination_header(Req),
-  
-  % open revision Rev or Current
-  {Doc, _DocRev} = couch_doc_open(Db, SourceDocId, SourceRev, []),
-
-  % save new doc
-  {ok, NewTargetRev} = couch_db:update_doc(Db, Doc#doc{id=TargetDocId, revs=TargetRev}, []),
-
-  send_json(Req, 201, [{"Etag", "\"" ++ NewTargetRev ++ "\""}], {obj, [
-      {ok, true},
-      {id, TargetDocId},
-      {rev, NewTargetRev}
-  ]});
+    SourceRev = case extract_header_rev(Req) of
+      missing_rev -> [];
+      Rev -> Rev
+    end,
+
+    {TargetDocId, TargetRev} = parse_copy_destination_header(Req),
+
+    % open revision Rev or Current
+    {Doc, _DocRev} = couch_doc_open(Db, SourceDocId, SourceRev, []),
+
+    % save new doc
+    {ok, NewTargetRev} = couch_db:update_doc(Db, Doc#doc{id=TargetDocId, revs=TargetRev}, []),
+
+    send_json(Req, 201, [{"Etag", "\"" ++ NewTargetRev ++ "\""}], {obj, [
+        {ok, true},
+        {id, TargetDocId},
+        {rev, NewTargetRev}
+    ]});
 
 handle_doc_request(Req, 'MOVE', _DbName, Db, SourceDocId) ->
-  SourceRev = case extract_header_rev(Req) of
-    missing_rev -> 
-      throw({
-        bad_request, 
-        "MOVE requires a specified rev parameter for the origin resource."}
-      );
-    Rev -> Rev
-  end,
-  
-  {TargetDocId, TargetRev} = parse_copy_destination_header(Req),
-
-  % open revision Rev or Current
-  {Doc, _DocRev} = couch_doc_open(Db, SourceDocId, SourceRev, []),
-
-  % save new doc & delete old doc in one operation
-  Docs = [
-    Doc#doc{id=TargetDocId, revs=TargetRev},
-    #doc{id=SourceDocId, revs=[SourceRev], deleted=true}
-  ],
-
-  {ok, ResultRevs} = couch_db:update_docs(Db, Docs, []),
-
-  DocResults = lists:zipwith(
-      fun(FDoc, NewRev) ->
-          {obj, [{"id", FDoc#doc.id}, {"rev", NewRev}]}
-      end,
-      Docs, ResultRevs),
-  send_json(Req, 201, {obj, [
-      {ok, true},
-      {new_revs, list_to_tuple(DocResults)}
-  ]});
+    SourceRev = case extract_header_rev(Req) of
+      missing_rev ->
+        throw({
+          bad_request,
+          "MOVE requires a specified rev parameter for the origin resource."}
+        );
+      Rev -> Rev
+    end,
+
+    {TargetDocId, TargetRev} = parse_copy_destination_header(Req),
+
+    % open revision Rev or Current
+    {Doc, _DocRev} = couch_doc_open(Db, SourceDocId, SourceRev, []),
+
+    % save new doc & delete old doc in one operation
+    Docs = [
+      Doc#doc{id=TargetDocId, revs=TargetRev},
+      #doc{id=SourceDocId, revs=[SourceRev], deleted=true}
+    ],
+
+    {ok, ResultRevs} = couch_db:update_docs(Db, Docs, []),
+
+    DocResults = lists:zipwith(
+        fun(FDoc, NewRev) ->
+            {obj, [{"id", FDoc#doc.id}, {"rev", NewRev}]}
+        end,
+        Docs, ResultRevs),
+    send_json(Req, 201, {obj, [
+        {ok, true},
+        {new_revs, list_to_tuple(DocResults)}
+    ]});
 
 handle_doc_request(_Req, _Method, _DbName, _Db, _DocId) ->
     throw({method_not_allowed, "DELETE,GET,HEAD,PUT,COPY,MOVE"}).
@@ -699,35 +699,24 @@
 % Useful for debugging
 % couch_doc_open(Db, DocId) ->
 %   couch_doc_open(Db, DocId, [], []).
-  
-couch_doc_open(Db, DocId, Rev, Options) ->
-  case Rev of
-  "" -> % open most recent rev
-      case couch_db:open_doc(Db, DocId, Options) of
-          {ok, #doc{revs=[DocRev|_]}=Doc} ->
-              {Doc, DocRev};
-          Error ->
-              throw(Error)
-      end;
-  _ -> % open a specific rev (deletions come back as stubs)
-      case couch_db:open_doc_revs(Db, DocId, [Rev], Options) of
-          {ok, [{ok, Doc}]} ->
-              {Doc, Rev};
-          {ok, [Else]} ->
-              throw(Else)
-      end
-  end.
 
-parse_copy_destination_header(Req) ->
-  Destination = Req:get_header_value("Destination"),
-  case regexp:match(Destination, "\\?") of
-    nomatch -> 
-      {Destination, []};
-    {match, _, _} ->
-      {ok, [DocId, RevQueryOptions]} = regexp:split(Destination, "\\?"),
-      {ok, [_RevQueryKey, Rev]} = regexp:split(RevQueryOptions, "="),
-      {DocId, [Rev]}
-  end.
+couch_doc_open(Db, DocId, Rev, Options) ->
+    case Rev of
+    "" -> % open most recent rev
+        case couch_db:open_doc(Db, DocId, Options) of
+            {ok, #doc{revs=[DocRev|_]}=Doc} ->
+                {Doc, DocRev};
+            Error ->
+                throw(Error)
+        end;
+    _ -> % open a specific rev (deletions come back as stubs)
+        case couch_db:open_doc_revs(Db, DocId, [Rev], Options) of
+            {ok, [{ok, Doc}]} ->
+                {Doc, Rev};
+            {ok, [Else]} ->
+                throw(Else)
+        end
+    end.
 
 % Attachment request handlers
 
@@ -761,7 +750,7 @@
     when (Method == 'PUT') or (Method == 'DELETE') ->
 
     Rev = extract_header_rev(Req),
-    
+
     NewAttachment = case Method of
         'DELETE' ->
             [];
@@ -772,20 +761,20 @@
             }}]
     end,
 
-    Doc =
-    case Rev of
-    missing_rev -> % make the new doc
-        #doc{id=DocId};
-    _ ->
-        case couch_db:open_doc_revs(Db, DocId, [Rev], []) of
-        {ok, [{ok, Doc0}]}   -> Doc0#doc{revs=[Rev]};
-        {ok, [Error]}       -> throw(Error)
-        end
+    Doc = case Rev of
+        missing_rev -> % make the new doc
+            #doc{id=DocId};
+        _ ->
+            case couch_db:open_doc_revs(Db, DocId, [Rev], []) of
+            {ok, [{ok, Doc0}]}   -> Doc0#doc{revs=[Rev]};
+            {ok, [Error]}       -> throw(Error)
+            end
     end,
-    
+
     #doc{attachments=Attachments} = Doc,
     DocEdited = Doc#doc{
-        attachments = NewAttachment ++ proplists:delete(FileName, Attachments)},
+        attachments = NewAttachment ++ proplists:delete(FileName, Attachments)
+    },
     {ok, UpdatedRev} = couch_db:update_doc(Db, DocEdited, []),
     send_json(Req, case Method of 'DELETE' -> 200; _ -> 201 end, {obj, [
         {ok, true},
@@ -796,28 +785,12 @@
 handle_attachment_request(_Req, _Method, _DbName, _Db, _DocId, _FileName) ->
     throw({method_not_allowed, "GET,HEAD,DELETE,PUT"}).
 
-extract_header_rev(Req) ->
-    QueryRev = proplists:get_value("rev", Req:parse_qs()),
-    Etag = case Req:get_header_value("If-Match") of
-        undefined -> undefined;
-        Tag -> string:strip(Tag, both, $")
-    end,
-    case {QueryRev, Etag} of
-    {undefined, undefined} -> missing_rev;
-    {_, undefined} -> QueryRev;
-    {undefined, _} -> Etag;
-    _ when QueryRev == Etag -> Etag;
-    _ ->
-        throw({bad_request, "Document rev and etag have different values"})
-    end.
-
 % Config request handlers
 
 handle_config_request(_Req, Method, {config, Config}) ->
     [Module, Key] = string:tokens(Config, "/"),
     handle_config_request(_Req, Method, {[Module, Key]});
 
-
 % PUT /_config/Module/Key
 % "value"
 handle_config_request(_Req, 'PUT', {[Module, Key]}) ->
@@ -825,7 +798,6 @@
 
 % POST,PUT /_config/Module/Key
 % "value"
- 
 handle_config_request(Req, 'POST', {[Module, Key]}) ->
     Value = binary_to_list(Req:recv_body()),
     ok = couch_config:store({Module, Key}, Value),
@@ -835,7 +807,7 @@
         {key, Key},
         {value, Value}
     ]});
-    
+
 % GET /_config/Module/Key
 handle_config_request(Req, 'GET', {[Module, Key]}) ->
     case couch_config:get({Module, Key},null) of
@@ -850,8 +822,7 @@
          ]})
     end;
 
-    
-% DELETE /_config/Key
+% DELETE /_config/Module/Key
 handle_config_request(Req, 'DELETE', {[Module, Key]}) ->
     case couch_config:get({Module, Key}, null) of
     null ->
@@ -870,7 +841,7 @@
 % TODO:
 % POST,PUT /_config/
 % [{Key, Value}, {K2, V2}, {K3, V3}]
-% 
+%
 % POST,PUT/_config/Key?value=Value
 
 
@@ -1141,6 +1112,32 @@
 error_to_json0(Error) ->
     {500, error, Error}.
 
+extract_header_rev(Req) ->
+    QueryRev = proplists:get_value("rev", Req:parse_qs()),
+    Etag = case Req:get_header_value("If-Match") of
+        undefined -> undefined;
+        Tag -> string:strip(Tag, both, $")
+    end,
+    case {QueryRev, Etag} of
+    {undefined, undefined} -> missing_rev;
+    {_, undefined} -> QueryRev;
+    {undefined, _} -> Etag;
+    _ when QueryRev == Etag -> Etag;
+    _ ->
+        throw({bad_request, "Document rev and etag have different values"})
+    end.
+
+parse_copy_destination_header(Req) ->
+    Destination = Req:get_header_value("Destination"),
+    case regexp:match(Destination, "\\?") of
+        nomatch ->
+            {Destination, []};
+        {match, _, _} ->
+            {ok, [DocId, RevQueryOptions]} = regexp:split(Destination, "\\?"),
+            {ok, [_RevQueryKey, Rev]} = regexp:split(RevQueryOptions, "="),
+            {DocId, [Rev]}
+    end.
+
 send_error(Req, {method_not_allowed, Methods}) ->
     {ok, Req:respond({405, [{"Allow", Methods}] ++ server_header(), <<>>})};
 send_error(Req, {modified, Etag}) ->

Propchange: incubator/couchdb/trunk/test/runner.sh
------------------------------------------------------------------------------
    svn:executable = *