You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ei...@apache.org on 2016/04/28 18:26:09 UTC

[3/8] couch commit: updated refs/heads/master to 78f575e

Move all functions related to file deletion in `couch_file` module


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/f8432a1d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/f8432a1d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/f8432a1d

Branch: refs/heads/master
Commit: f8432a1d51c61da52fd8cf8a4b9a41c093df5d02
Parents: bc3ecda
Author: Eric Avdey <ei...@eiri.ca>
Authored: Fri Apr 22 11:09:59 2016 -0300
Committer: Eric Avdey <ei...@eiri.ca>
Committed: Thu Apr 28 13:09:35 2016 -0300

----------------------------------------------------------------------
 src/couch_file.erl        | 61 +++++++++++++++++++++++++++++++++++++++++-
 src/couch_server.erl      | 27 ++-----------------
 test/couch_file_tests.erl | 47 ++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f8432a1d/src/couch_file.erl
----------------------------------------------------------------------
diff --git a/src/couch_file.erl b/src/couch_file.erl
index f6c5a4f..9a9c070 100644
--- a/src/couch_file.erl
+++ b/src/couch_file.erl
@@ -221,8 +221,16 @@ close(Fd) ->
 delete(RootDir, Filepath) ->
     delete(RootDir, Filepath, true).
 
+delete(RootDir, FullFilePath, Async) ->
+    RenameOnDelete = config:get_boolean("couchdb", "rename_on_delete", false),
+    case RenameOnDelete of
+        true ->
+            rename_file(FullFilePath);
+        false ->
+            delete_file(RootDir, FullFilePath, Async)
+    end.
 
-delete(RootDir, Filepath, Async) ->
+delete_file(RootDir, Filepath, Async) ->
     DelFile = filename:join([RootDir,".delete", ?b2l(couch_uuids:random())]),
     case file:rename(Filepath, DelFile) of
     ok ->
@@ -236,6 +244,17 @@ delete(RootDir, Filepath, Async) ->
         Error
     end.
 
+rename_file(Original) ->
+    DeletedFileName = deleted_filename(Original),
+    file:rename(Original, DeletedFileName).
+
+deleted_filename(Original) ->
+    {{Y, Mon, D}, {H, Min, S}} = calendar:universal_time(),
+    Suffix = lists:flatten(
+        io_lib:format(".~w~2.10.0B~2.10.0B."
+            ++ "~2.10.0B~2.10.0B~2.10.0B.deleted"
+            ++ filename:extension(Original), [Y, Mon, D, H, Min, S])),
+    filename:rootname(Original) ++ Suffix.
 
 nuke_dir(RootDelDir, Dir) ->
     FoldFun = fun(File) ->
@@ -610,3 +629,43 @@ process_info(Pid) ->
         {couch_file_fd, {Fd, InitialName}} ->
             {Fd, InitialName}
     end.
+
+
+-ifdef(TEST).
+-include_lib("couch/include/couch_eunit.hrl").
+
+deleted_filename_test_() ->
+    DbNames = ["dbname", "db.name", "user/dbname"],
+    Fixtures = make_filename_fixtures(DbNames),
+    lists:map(fun(Fixture) ->
+        should_create_proper_deleted_filename(Fixture)
+    end, Fixtures).
+
+should_create_proper_deleted_filename(Before) ->
+    {Before,
+    ?_test(begin
+        BeforeExtension = filename:extension(Before),
+        BeforeBasename = filename:basename(Before, BeforeExtension),
+        Re = "^" ++ BeforeBasename ++ "\.[0-9]{8}\.[0-9]{6}\.deleted\..*$",
+        After = deleted_filename(Before),
+        ?assertEqual(match,
+            re:run(filename:basename(After), Re, [{capture, none}])),
+        ?assertEqual(BeforeExtension, filename:extension(After))
+    end)}.
+
+make_filename_fixtures(DbNames) ->
+    Formats = [
+        "~s.couch",
+        ".~s_design/mrview/3133e28517e89a3e11435dd5ac4ad85a.view",
+        "shards/00000000-1fffffff/~s.1458336317.couch",
+        ".shards/00000000-1fffffff/~s.1458336317_design",
+        ".shards/00000000-1fffffff/~s.1458336317_design"
+            "/mrview/3133e28517e89a3e11435dd5ac4ad85a.view"
+    ],
+    lists:flatmap(fun(DbName) ->
+        lists:map(fun(Format) ->
+            filename:join("/srv/data", io_lib:format(Format, [DbName]))
+        end, Formats)
+    end, DbNames).
+
+-endif.

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f8432a1d/src/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_server.erl b/src/couch_server.erl
index dc50e82..f280eca 100644
--- a/src/couch_server.erl
+++ b/src/couch_server.erl
@@ -25,8 +25,6 @@
 % config_listener api
 -export([handle_config_change/5, handle_config_terminate/3]).
 
--export([delete_file/3]).
-
 -include_lib("couch/include/couch_db.hrl").
 
 -define(MAX_DBS_OPEN, 100).
@@ -461,7 +459,8 @@ handle_call({delete, DbName, Options}, _From, Server) ->
 
         couch_db_plugin:on_delete(DbName, Options),
 
-        case delete_file(Server#server.root_dir, FullFilepath, Options) of
+        Async = not lists:member(sync, Options),
+        case couch_file:delete(Server#server.root_dir, FullFilepath, Async) of
         ok ->
             couch_event:notify(DbName, deleted),
             {reply, ok, Server2};
@@ -538,25 +537,3 @@ db_closed(Server, Options) ->
         false -> Server#server{dbs_open=Server#server.dbs_open - 1};
         true -> Server
     end.
-
-delete_file(RootDir, FullFilePath, Options) ->
-    Async = not lists:member(sync, Options),
-    RenameOnDelete = config:get_boolean("couchdb", "rename_on_delete", false),
-    case RenameOnDelete of
-        true ->
-            rename_on_delete(FullFilePath);
-        false ->
-            couch_file:delete(RootDir, FullFilePath, Async)
-    end.
-
-rename_on_delete(Original) ->
-    DeletedFileName = deleted_filename(Original),
-    file:rename(Original, DeletedFileName).
-
-deleted_filename(Original) ->
-    {{Y,Mon,D}, {H,Min,S}} = calendar:universal_time(),
-    Suffix = lists:flatten(
-        io_lib:format(".~w~2.10.0B~2.10.0B."
-            ++ "~2.10.0B~2.10.0B~2.10.0B.deleted"
-            ++ filename:extension(Original), [Y,Mon,D,H,Min,S])),
-    filename:rootname(Original) ++ Suffix.

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f8432a1d/test/couch_file_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_file_tests.erl b/test/couch_file_tests.erl
index 4d0bbac..df122b0 100644
--- a/test/couch_file_tests.erl
+++ b/test/couch_file_tests.erl
@@ -274,3 +274,50 @@ write_random_data(Fd, N) ->
     Term = lists:nth(random:uniform(4) + 1, Choices),
     {ok, _, _} = couch_file:append_term(Fd, Term),
     write_random_data(Fd, N - 1).
+
+
+delete_test_() ->
+    {
+        "File delete tests",
+        {
+            foreach,
+            fun() ->
+                meck:new(config, [passthrough]),
+                File = ?tempfile() ++ ".couch",
+                RootDir = filename:dirname(File),
+                ok = couch_file:init_delete_dir(RootDir),
+                ok = file:write_file(File, <<>>),
+                {RootDir, File}
+            end,
+            fun({_, File}) ->
+                meck:unload(config),
+                file:delete(File)
+            end,
+            [
+                fun(Cfg) ->
+                    {"rename_on_delete = false",
+                    make_delete_test_case(Cfg, false)}
+                end,
+                fun(Cfg) ->
+                    {"rename_on_delete = true",
+                    make_delete_test_case(Cfg, true)}
+                end
+            ]
+        }
+    }.
+
+
+make_delete_test_case({RootDir, File}, RenameOnDelete) ->
+    meck:expect(config, get_boolean, fun
+        ("couchdb", "rename_on_delete", _) -> RenameOnDelete
+    end),
+    FileExistsBefore = filelib:is_regular(File),
+    couch_file:delete(RootDir, File, false),
+    FileExistsAfter = filelib:is_regular(File),
+    RenamedFiles = filelib:wildcard(filename:rootname(File) ++ "*.deleted.*"),
+    ExpectRenamedCount = if RenameOnDelete -> 1; true -> 0 end,
+    [
+        ?_assert(FileExistsBefore),
+        ?_assertNot(FileExistsAfter),
+        ?_assertEqual(ExpectRenamedCount, length(RenamedFiles))
+    ].