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))
+ ].