mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
Add virtual host support for SQLite
This commit is contained in:
parent
fb0e82f743
commit
9b4942890d
@ -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">>).
|
||||
|
@ -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.
|
||||
@ -460,7 +478,8 @@ sql_query_internal(Query) ->
|
||||
%% ?INFO_MSG("MySQL, Received result~n~p~n", [R]),
|
||||
R;
|
||||
sqlite ->
|
||||
sqlite_to_odbc(sqlite3:sql_exec(?SQLITE_DB, Query))
|
||||
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
|
||||
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, "pragma foreign_keys = on"),
|
||||
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},
|
||||
|
@ -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
|
||||
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) ->
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user