aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ejabberd.hrl4
-rw-r--r--src/ejabberd_odbc.erl71
-rw-r--r--src/ejabberd_odbc_sup.erl44
-rw-r--r--test/ejabberd_SUITE.erl1
-rw-r--r--test/ejabberd_SUITE_data/ejabberd.yml1
5 files changed, 71 insertions, 50 deletions
diff --git a/include/ejabberd.hrl b/include/ejabberd.hrl
index c5f8dffe3..f07dc0aaf 100644
--- a/include/ejabberd.hrl
+++ b/include/ejabberd.hrl
@@ -33,10 +33,6 @@
-define(SQL_DIR, filename:join(["priv", "sql"])).
--define(SQLITE_DB, ejabberd_sqlite).
-
--define(DEFAULT_SQLITE_DB_PATH, <<"/tmp/ejabberd.db">>).
-
-define(CONFIG_PATH, <<"ejabberd.cfg">>).
-define(LOG_PATH, <<"ejabberd.log">>).
diff --git a/src/ejabberd_odbc.erl b/src/ejabberd_odbc.erl
index e0ec3ba00..09f17a635 100644
--- a/src/ejabberd_odbc.erl
+++ b/src/ejabberd_odbc.erl
@@ -40,6 +40,8 @@
escape/1,
escape_like/1,
to_bool/1,
+ sqlite_db/1,
+ sqlite_file/1,
encode_term/1,
decode_term/1,
keep_alive/1]).
@@ -199,6 +201,22 @@ decode_term(Bin) ->
{ok, Term} = erl_parse:parse_term(Tokens),
Term.
+-spec sqlite_db(binary()) -> atom().
+sqlite_db(Host) ->
+ list_to_atom("ejabberd_sqlite_" ++ binary_to_list(Host)).
+
+-spec sqlite_file(binary()) -> string().
+sqlite_file(Host) ->
+ case ejabberd_config:get_option({odbc_database, Host},
+ fun iolist_to_binary/1) of
+ undefined ->
+ {ok, Cwd} = file:get_cwd(),
+ filename:join([Cwd, "sqlite", atom_to_list(node()),
+ binary_to_list(Host), "ejabberd.db"]);
+ File ->
+ binary_to_list(File)
+ end.
+
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
%%%----------------------------------------------------------------------
@@ -329,7 +347,7 @@ terminate(_Reason, _StateName, State) ->
ejabberd_odbc_sup:remove_pid(State#state.host, self()),
case State#state.db_type of
mysql -> catch p1_mysql_conn:stop(State#state.db_ref);
- sqlite -> catch sqlite3:close(?SQLITE_DB);
+ sqlite -> catch sqlite3:close(sqlite_db(State#state.host));
_ -> ok
end,
ok.
@@ -458,9 +476,10 @@ sql_query_internal(Query) ->
[{timeout, (?TRANSACTION_TIMEOUT) - 1000},
{result_type, binary}])),
%% ?INFO_MSG("MySQL, Received result~n~p~n", [R]),
- R;
- sqlite ->
- sqlite_to_odbc(sqlite3:sql_exec(?SQLITE_DB, Query))
+ R;
+ sqlite ->
+ Host = State#state.host,
+ sqlite_to_odbc(Host, sqlite3:sql_exec(sqlite_db(Host), Query))
end,
case Res of
{error, <<"No SQL-driver information available.">>} ->
@@ -497,23 +516,30 @@ odbc_connect(SQLServer) ->
%% part of init/1
%% Open a database connection to SQLite
-sqlite_connect(DB) ->
- case sqlite3:open(?SQLITE_DB, [{file, binary_to_list(DB)}]) of
- {ok, Ref} ->
- sqlite3:sql_exec(?SQLITE_DB, "pragma foreign_keys = on"),
- {ok, Ref};
- {error, {already_started, Ref}} ->
- {ok, Ref};
- {error, Reason} ->
- {error, Reason}
+sqlite_connect(Host) ->
+ File = sqlite_file(Host),
+ case filelib:ensure_dir(File) of
+ ok ->
+ case sqlite3:open(sqlite_db(Host), [{file, File}]) of
+ {ok, Ref} ->
+ sqlite3:sql_exec(
+ sqlite_db(Host), "pragma foreign_keys = on"),
+ {ok, Ref};
+ {error, {already_started, Ref}} ->
+ {ok, Ref};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ Err ->
+ Err
end.
%% Convert SQLite query result to Erlang ODBC result formalism
-sqlite_to_odbc(ok) ->
- {updated, sqlite3:changes(?SQLITE_DB)};
-sqlite_to_odbc({rowid, _}) ->
- {updated, sqlite3:changes(?SQLITE_DB)};
-sqlite_to_odbc([{columns, Columns}, {rows, TRows}]) ->
+sqlite_to_odbc(Host, ok) ->
+ {updated, sqlite3:changes(sqlite_db(Host))};
+sqlite_to_odbc(Host, {rowid, _}) ->
+ {updated, sqlite3:changes(sqlite_db(Host))};
+sqlite_to_odbc(_Host, [{columns, Columns}, {rows, TRows}]) ->
Rows = [lists:map(
fun(I) when is_integer(I) ->
jlib:integer_to_binary(I);
@@ -521,9 +547,9 @@ sqlite_to_odbc([{columns, Columns}, {rows, TRows}]) ->
B
end, tuple_to_list(Row)) || Row <- TRows],
{selected, [list_to_binary(C) || C <- Columns], Rows};
-sqlite_to_odbc({error, _Code, Reason}) ->
+sqlite_to_odbc(_Host, {error, _Code, Reason}) ->
{error, Reason};
-sqlite_to_odbc(_) ->
+sqlite_to_odbc(_Host, _) ->
{updated, undefined}.
%% == Native PostgreSQL code
@@ -633,10 +659,7 @@ db_opts(Host) ->
odbc ->
[odbc, Server];
sqlite ->
- DB = ejabberd_config:get_option({odbc_database, Host},
- fun iolist_to_binary/1,
- ?DEFAULT_SQLITE_DB_PATH),
- [sqlite, DB];
+ [sqlite, Host];
_ ->
Port = ejabberd_config:get_option(
{odbc_port, Host},
diff --git a/src/ejabberd_odbc_sup.erl b/src/ejabberd_odbc_sup.erl
index c92e988ee..37128e265 100644
--- a/src/ejabberd_odbc_sup.erl
+++ b/src/ejabberd_odbc_sup.erl
@@ -75,10 +75,7 @@ init([Host]) ->
end, odbc),
case Type of
sqlite ->
- DB = ejabberd_config:get_option({odbc_database, Host},
- fun iolist_to_binary/1,
- ?DEFAULT_SQLITE_DB_PATH),
- check_sqlite_db(DB);
+ check_sqlite_db(Host);
_ ->
ok
end,
@@ -134,19 +131,26 @@ transform_options({odbc_server, {sqlite, DB}}, Opts) ->
transform_options(Opt, Opts) ->
[Opt|Opts].
-check_sqlite_db(DB) ->
- Ret = case sqlite3:open(?SQLITE_DB, [{file, binary_to_list(DB)}]) of
- {ok, _Ref} -> ok;
- {error, {already_started, _Ref}} -> ok;
- {error, R} -> {error, R}
- end,
+check_sqlite_db(Host) ->
+ DB = ejabberd_odbc:sqlite_db(Host),
+ File = ejabberd_odbc:sqlite_file(Host),
+ Ret = case filelib:ensure_dir(File) of
+ ok ->
+ case sqlite3:open(DB, [{file, File}]) of
+ {ok, _Ref} -> ok;
+ {error, {already_started, _Ref}} -> ok;
+ {error, R} -> {error, R}
+ end;
+ Err ->
+ Err
+ end,
case Ret of
ok ->
- sqlite3:sql_exec(?SQLITE_DB, "pragma foreign_keys = on"),
- case sqlite3:list_tables(?SQLITE_DB) of
+ sqlite3:sql_exec(DB, "pragma foreign_keys = on"),
+ case sqlite3:list_tables(DB) of
[] ->
- create_sqlite_tables(),
- sqlite3:close(?SQLITE_DB),
+ create_sqlite_tables(DB),
+ sqlite3:close(DB),
ok;
[_H | _] ->
ok
@@ -155,7 +159,7 @@ check_sqlite_db(DB) ->
?INFO_MSG("Failed open sqlite database, reason ~p", [Reason])
end.
-create_sqlite_tables() ->
+create_sqlite_tables(DB) ->
SqlDir = case code:priv_dir(ejabberd) of
{error, _} ->
?SQL_DIR;
@@ -166,12 +170,12 @@ create_sqlite_tables() ->
case file:open(File, [read, binary]) of
{ok, Fd} ->
Qs = read_lines(Fd, File, []),
- ok = sqlite3:sql_exec(?SQLITE_DB, "begin"),
- [ok = sqlite3:sql_exec(?SQLITE_DB, Q) || Q <- Qs],
- ok = sqlite3:sql_exec(?SQLITE_DB, "commit");
+ ok = sqlite3:sql_exec(DB, "begin"),
+ [ok = sqlite3:sql_exec(DB, Q) || Q <- Qs],
+ ok = sqlite3:sql_exec(DB, "commit");
{error, Reason} ->
- ?INFO_MSG("Not found sqlite database schema, reason: ~p", [Reason]),
- ok
+ ?INFO_MSG("Failed to read SQLite schema file: ~s",
+ [file:format_error(Reason)])
end.
read_lines(Fd, File, Acc) ->
diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl
index ec60b728d..a90ebdb69 100644
--- a/test/ejabberd_SUITE.erl
+++ b/test/ejabberd_SUITE.erl
@@ -35,7 +35,6 @@ init_per_suite(Config) ->
LDIFFile = filename:join([DataDir, "ejabberd.ldif"]),
{ok, _} = file:copy(ExtAuthScript, filename:join([CWD, "extauth.py"])),
{ok, _} = ldap_srv:start(LDIFFile),
- file:delete("/tmp/ejabberd_test.db"),
ok = application:start(ejabberd),
NewConfig.
diff --git a/test/ejabberd_SUITE_data/ejabberd.yml b/test/ejabberd_SUITE_data/ejabberd.yml
index 1714464d5..b23c69271 100644
--- a/test/ejabberd_SUITE_data/ejabberd.yml
+++ b/test/ejabberd_SUITE_data/ejabberd.yml
@@ -57,7 +57,6 @@ Welcome to this XMPP server."
mod_version: []
"sqlite.localhost":
odbc_type: sqlite
- odbc_database: "/tmp/ejabberd_test.db"
auth_method: odbc
modules:
mod_announce: