Merge remote-tracking branch 'upstream/master' into 1843-feature-bigcouch
Conflicts:
src/config.erl
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index c57e7cf..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-ebin
-deps
-.eunit
-*~
-*.swp
diff --git a/rebar b/rebar
deleted file mode 100755
index ceabf62..0000000
--- a/rebar
+++ /dev/null
Binary files differ
diff --git a/rebar.config b/rebar.config
deleted file mode 100644
index d65fc31..0000000
--- a/rebar.config
+++ /dev/null
@@ -1,17 +0,0 @@
-% Copyright 2011 Cloudant
-%
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-{deps, [
- {twig, ".*", {git, "https://github.com/cloudant/twig.git", master}}
-]}.
diff --git a/src/config.app.src b/src/config.app.src
index 2841202..7f8eef6 100644
--- a/src/config.app.src
+++ b/src/config.app.src
@@ -1,3 +1,15 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
{application, config, [
{description, "INI file configuration system for Apache CouchDB"},
{vsn, git},
diff --git a/src/config.erl b/src/config.erl
index 1a728b0..d123b12 100644
--- a/src/config.erl
+++ b/src/config.erl
@@ -20,7 +20,7 @@
-behaviour(gen_server).
-vsn(1).
--export([start_link/1, stop/0]).
+-export([start_link/1, stop/0, reload/0]).
-export([all/0]).
-export([get/1, get/2, get/3]).
@@ -39,6 +39,7 @@
-record(config, {
notify_funs=[],
+ ini_files=undefined,
write_filename=undefined
}).
@@ -50,6 +51,9 @@
gen_server:cast(?MODULE, stop).
+reload() ->
+ gen_server:call(?MODULE, reload).
+
all() ->
lists:sort(gen_server:call(?MODULE, all, infinity)).
@@ -183,7 +187,8 @@
[_|_] -> lists:last(IniFiles);
_ -> undefined
end,
- {ok, #config{write_filename=WriteFile}}.
+ debug_config(),
+ {ok, #config{ini_files=IniFiles, write_filename=WriteFile}}.
terminate(_Reason, _State) ->
@@ -195,11 +200,8 @@
{reply, Resp, Config};
handle_call({set, Sec, Key, Val, Persist, Reason}, _From, Config) ->
true = ets:insert(?MODULE, {{Sec, Key}, Val}),
- twig:log(
- notice,
- "~p: [~s] ~s set to ~s for reason ~p",
- [?MODULE, Sec, Key, Val, Reason]
- ),
+ couch_log:notice("~p: [~s] ~s set to ~s for reason ~p",
+ [?MODULE, Sec, Key, Val, Reason]),
case {Persist, Config#config.write_filename} of
{true, undefined} ->
ok;
@@ -213,11 +215,8 @@
{reply, ok, Config};
handle_call({delete, Sec, Key, Persist, Reason}, _From, Config) ->
true = ets:delete(?MODULE, {Sec,Key}),
- twig:log(
- notice,
- "~p: [~s] ~s deleted for reason ~p",
- [?MODULE, Sec, Key, Reason]
- ),
+ couch_log:notice("~p: [~s] ~s deleted for reason ~p",
+ [?MODULE, Sec, Key, Reason]),
case {Persist, Config#config.write_filename} of
{true, undefined} ->
ok;
@@ -228,6 +227,29 @@
end,
Event = {config_change, Sec, Key, deleted, Persist},
gen_event:sync_notify(config_event, Event),
+ {reply, ok, Config};
+handle_call(reload, _From, Config) ->
+ DiskKVs = lists:foldl(fun(IniFile, DiskKVs0) ->
+ {ok, ParsedIniValues} = parse_ini_file(IniFile),
+ lists:foldl(fun({K, V}, DiskKVs1) ->
+ dict:store(K, V, DiskKVs1)
+ end, DiskKVs0, ParsedIniValues)
+ end, dict:new(), Config#config.ini_files),
+ % Update ets with anything we just read
+ % from disk
+ dict:fold(fun(K, V, _) ->
+ ets:insert(?MODULE, {K, V})
+ end, nil, DiskKVs),
+ % And remove anything in ets that wasn't
+ % on disk.
+ ets:foldl(fun({K, _}, _) ->
+ case dict:is_key(K, DiskKVs) of
+ true ->
+ ok;
+ false ->
+ ets:delete(?MODULE, K)
+ end
+ end, nil, ?MODULE),
{reply, ok, Config}.
@@ -237,7 +259,7 @@
{noreply, State}.
handle_info(Info, State) ->
- twig:log(error, "config:handle_info Info: ~p~n", [Info]),
+ couch_log:error("config:handle_info Info: ~p~n", [Info]),
{noreply, State}.
code_change(_OldVsn, State, _Extra) ->
@@ -253,7 +275,7 @@
{error, enoent} ->
Fmt = "Couldn't find server configuration file ~s.",
Msg = list_to_binary(io_lib:format(Fmt, [IniFilename])),
- twig:log(error, "~s~n", [Msg]),
+ couch_log:error("~s~n", [Msg]),
throw({startup_error, Msg})
end,
@@ -312,3 +334,16 @@
end
end, {"", []}, Lines),
{ok, ParsedIniValues}.
+
+
+debug_config() ->
+ case ?MODULE:get("log", "level") of
+ "debug" ->
+ io:format("Configuration Settings:~n", []),
+ lists:foreach(fun({{Mod, Key}, Val}) ->
+ io:format(" [~s] ~s=~p~n", [Mod, Key, Val])
+ end, lists:sort(ets:tab2list(?MODULE)));
+ _ ->
+ ok
+ end.
+
diff --git a/src/config_app.erl b/src/config_app.erl
index 54f2433..5c5515a 100644
--- a/src/config_app.erl
+++ b/src/config_app.erl
@@ -28,14 +28,25 @@
ok.
get_ini_files() ->
+ hd([L || L <- [command_line(), env(), default()], L =/= skip]).
+
+env() ->
+ case application:get_env(config, ini_files) of
+ undefined ->
+ skip;
+ {ok, IniFiles} ->
+ IniFiles
+ end.
+
+command_line() ->
+ case init:get_argument(couch_ini) of
+ error ->
+ skip;
+ {ok, [IniFiles]} ->
+ IniFiles
+ end.
+
+default() ->
Etc = filename:join(code:root_dir(), "etc"),
Default = [filename:join(Etc,"default.ini"), filename:join(Etc,"local.ini")],
- DefaultExists = lists:filter(fun filelib:is_file/1, Default),
- case init:get_argument(couch_ini) of
- error ->
- DefaultExists;
- {ok, [[]]} ->
- DefaultExists;
- {ok, [Values]} ->
- Values
- end.
+ lists:filter(fun filelib:is_file/1, Default).
diff --git a/src/config_listener.erl b/src/config_listener.erl
index 2f2c68e..79d3806 100644
--- a/src/config_listener.erl
+++ b/src/config_listener.erl
@@ -1,3 +1,15 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
-module(config_listener).
-behaviour(gen_event).