Skip to content

Commit

Permalink
Automatically create and update SQL schema
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyshch committed Oct 16, 2023
1 parent f6e8eb5 commit c1af36a
Show file tree
Hide file tree
Showing 28 changed files with 1,733 additions and 19 deletions.
17 changes: 17 additions & 0 deletions include/ejabberd_sql.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,20 @@
boolean :: fun((boolean()) -> binary()),
in_array_string :: fun((binary()) -> binary()),
like_escape :: fun(() -> binary())}).


-record(sql_index, {columns,
unique = false :: boolean()}).
-record(sql_column, {name :: binary(),
type,
default = false,
opts = []}).
-record(sql_table, {name :: binary(),
columns :: [#sql_column{}],
indices = [] :: [#sql_index{}],
post_create}).
-record(sql_schema, {version :: integer(),
tables :: [#sql_table{}],
update = []}).
-record(sql_references, {table :: binary(),
column :: binary()}).
26 changes: 25 additions & 1 deletion src/ejabberd_auth_sql.erl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,31 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(_Host) -> ok.
start(Host) ->
ejabberd_sql_schema:update_schema(Host, ?MODULE, schemas()),
ok.

schemas() ->
[#sql_schema{
version = 1,
tables =
[#sql_table{
name = <<"users">>,
columns =
[#sql_column{name = <<"username">>, type = text},
#sql_column{name = <<"server_host">>, type = text},
#sql_column{name = <<"password">>, type = text},
#sql_column{name = <<"serverkey">>, type = {text, 128},
default = true},
#sql_column{name = <<"salt">>, type = {text, 128},
default = true},
#sql_column{name = <<"iterationcount">>, type = integer,
default = true},
#sql_column{name = <<"created_at">>, type = timestamp,
default = true}],
indices = [#sql_index{
columns = [<<"server_host">>, <<"username">>],
unique = true}]}]}].

stop(_Host) -> ok.

Expand Down
27 changes: 27 additions & 0 deletions src/ejabberd_oauth_sql.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,35 @@
-include("logger.hrl").

init() ->
ejabberd_sql_schema:update_schema(
ejabberd_config:get_myname(), ?MODULE, schemas()),
ok.

schemas() ->
[#sql_schema{
version = 1,
tables =
[#sql_table{
name = <<"oauth_token">>,
columns =
[#sql_column{name = <<"token">>, type = text},
#sql_column{name = <<"jid">>, type = text},
#sql_column{name = <<"scope">>, type = text},
#sql_column{name = <<"expire">>, type = bigint}],
indices = [#sql_index{
columns = [<<"token">>],
unique = true}]},
#sql_table{
name = <<"oauth_client">>,
columns =
[#sql_column{name = <<"client_id">>, type = text},
#sql_column{name = <<"client_name">>, type = text},
#sql_column{name = <<"grant_type">>, type = text},
#sql_column{name = <<"options">>, type = text}],
indices = [#sql_index{
columns = [<<"client_id">>],
unique = true}]}]}].

store(R) ->
Token = R#oauth_token.token,
{User, Server} = R#oauth_token.us,
Expand Down
5 changes: 5 additions & 0 deletions src/ejabberd_option.erl
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
-export([sql_type/0, sql_type/1]).
-export([sql_username/0, sql_username/1]).
-export([trusted_proxies/0]).
-export([update_sql_schema/0]).
-export([use_cache/0, use_cache/1]).
-export([validate_stream/0]).
-export([version/0]).
Expand Down Expand Up @@ -1096,6 +1097,10 @@ sql_username(Host) ->
trusted_proxies() ->
ejabberd_config:get_option({trusted_proxies, global}).

-spec update_sql_schema() -> boolean().
update_sql_schema() ->
ejabberd_config:get_option({update_sql_schema, global}).

-spec use_cache() -> boolean().
use_cache() ->
use_cache(global).
Expand Down
4 changes: 4 additions & 0 deletions src/ejabberd_options.erl
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ opt_type(net_ticktime) ->
econf:timeout(second);
opt_type(new_sql_schema) ->
econf:bool();
opt_type(update_sql_schema) ->
econf:bool();
opt_type(oauth_access) ->
econf:acl();
opt_type(oauth_cache_life_time) ->
Expand Down Expand Up @@ -607,6 +609,7 @@ options() ->
{negotiation_timeout, timer:seconds(30)},
{net_ticktime, timer:seconds(60)},
{new_sql_schema, ?USE_NEW_SQL_SCHEMA_DEFAULT},
{update_sql_schema, true},
{oauth_access, none},
{oauth_cache_life_time,
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
Expand Down Expand Up @@ -756,6 +759,7 @@ globals() ->
negotiation_timeout,
net_ticktime,
new_sql_schema,
update_sql_schema,
node_start,
oauth_cache_life_time,
oauth_cache_missed,
Expand Down
5 changes: 5 additions & 0 deletions src/ejabberd_options_doc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,11 @@ doc() ->
"configuration flag '--enable-new-sql-schema' which is set "
"at compile time."),
[binary:part(ejabberd_config:version(), {0,5})]}}},
{update_sql_schema,
#{value => "true | false",
desc =>
?T("Allow ejabberd to update SQL schema. "
"The default value is 'true'.")}},
{oauth_access,
#{value => ?T("AccessName"),
desc => ?T("By default creating OAuth tokens is not allowed. "
Expand Down
19 changes: 19 additions & 0 deletions src/ejabberd_router_sql.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
%%% API
%%%===================================================================
init() ->
ejabberd_sql_schema:update_schema(
ejabberd_config:get_myname(), ?MODULE, schemas()),
Node = erlang:atom_to_binary(node(), latin1),
?DEBUG("Cleaning SQL 'route' table...", []),
case ejabberd_sql:sql_query(
Expand All @@ -48,6 +50,23 @@ init() ->
Err
end.

schemas() ->
[#sql_schema{
version = 1,
tables =
[#sql_table{
name = <<"route">>,
columns =
[#sql_column{name = <<"domain">>, type = text},
#sql_column{name = <<"server_host">>, type = text},
#sql_column{name = <<"node">>, type = text},
#sql_column{name = <<"pid">>, type = text},
#sql_column{name = <<"local_hint">>, type = text}],
indices = [#sql_index{
columns = [<<"domain">>, <<"server_host">>,
<<"node">>, <<"pid">>],
unique = true}]}]}].

register_route(Domain, ServerHost, LocalHint, _, Pid) ->
PidS = misc:encode_pid(Pid),
LocalHintS = enc_local_hint(LocalHint),
Expand Down
24 changes: 24 additions & 0 deletions src/ejabberd_sm_sql.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ init() ->
?DEBUG("Cleaning SQL SM table...", []),
lists:foldl(
fun(Host, ok) ->
ejabberd_sql_schema:update_schema(Host, ?MODULE, schemas()),
case ejabberd_sql:sql_query(
Host, ?SQL("delete from sm where node=%(Node)s")) of
{updated, _} ->
Expand All @@ -60,6 +61,29 @@ init() ->
Err
end, ok, ejabberd_sm:get_vh_by_backend(?MODULE)).

schemas() ->
[#sql_schema{
version = 1,
tables =
[#sql_table{
name = <<"sm">>,
columns =
[#sql_column{name = <<"usec">>, type = bigint},
#sql_column{name = <<"pid">>, type = text},
#sql_column{name = <<"node">>, type = text},
#sql_column{name = <<"username">>, type = text},
#sql_column{name = <<"server_host">>, type = text},
#sql_column{name = <<"resource">>, type = text},
#sql_column{name = <<"priority">>, type = text},
#sql_column{name = <<"info">>, type = text}],
indices = [#sql_index{
columns = [<<"usec">>, <<"pid">>],
unique = true},
#sql_index{
columns = [<<"node">>]},
#sql_index{
columns = [<<"server_host">>, <<"username">>]}]}]}].

set_session(#session{sid = {Now, Pid}, usr = {U, LServer, R},
priority = Priority, info = Info}) ->
InfoS = misc:term_to_expr(Info),
Expand Down
Loading

0 comments on commit c1af36a

Please sign in to comment.