mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
Fix MSSQL support
This commit is contained in:
parent
48c5e73321
commit
25791cfde8
BIN
sql/mssql.sql
Normal file
BIN
sql/mssql.sql
Normal file
Binary file not shown.
1095
sql/mssql2000.sql
1095
sql/mssql2000.sql
File diff suppressed because it is too large
Load Diff
1802
sql/mssql2005.sql
1802
sql/mssql2005.sql
File diff suppressed because it is too large
Load Diff
1782
sql/mssql2012.sql
1782
sql/mssql2012.sql
File diff suppressed because it is too large
Load Diff
@ -432,13 +432,13 @@ outer_transaction(F, NRestarts, _Reason) ->
|
||||
[T]),
|
||||
erlang:exit(implementation_faulty)
|
||||
end,
|
||||
sql_query_internal(<<"begin;">>),
|
||||
sql_query_internal([<<"begin;">>]),
|
||||
put(?NESTING_KEY, PreviousNestingLevel + 1),
|
||||
Result = (catch F()),
|
||||
put(?NESTING_KEY, PreviousNestingLevel),
|
||||
case Result of
|
||||
{aborted, Reason} when NRestarts > 0 ->
|
||||
sql_query_internal(<<"rollback;">>),
|
||||
sql_query_internal([<<"rollback;">>]),
|
||||
outer_transaction(F, NRestarts - 1, Reason);
|
||||
{aborted, Reason} when NRestarts =:= 0 ->
|
||||
?ERROR_MSG("SQL transaction restarts exceeded~n** "
|
||||
@ -447,11 +447,11 @@ outer_transaction(F, NRestarts, _Reason) ->
|
||||
"== ~p",
|
||||
[?MAX_TRANSACTION_RESTARTS, Reason,
|
||||
erlang:get_stacktrace(), get(?STATE_KEY)]),
|
||||
sql_query_internal(<<"rollback;">>),
|
||||
sql_query_internal([<<"rollback;">>]),
|
||||
{aborted, Reason};
|
||||
{'EXIT', Reason} ->
|
||||
sql_query_internal(<<"rollback;">>), {aborted, Reason};
|
||||
Res -> sql_query_internal(<<"commit;">>), {atomic, Res}
|
||||
sql_query_internal([<<"rollback;">>]), {aborted, Reason};
|
||||
Res -> sql_query_internal([<<"commit;">>]), {atomic, Res}
|
||||
end.
|
||||
|
||||
execute_bloc(F) ->
|
||||
@ -463,6 +463,7 @@ execute_bloc(F) ->
|
||||
|
||||
sql_query_internal(Query) ->
|
||||
State = get(?STATE_KEY),
|
||||
?DEBUG("SQL: \"~s\"", [Query]),
|
||||
Res = case State#state.db_type of
|
||||
odbc ->
|
||||
to_odbc(odbc:sql_query(State#state.db_ref, Query,
|
||||
@ -512,8 +513,10 @@ abort_on_driver_error(Reply, From) ->
|
||||
%% Open an ODBC database connection
|
||||
odbc_connect(SQLServer) ->
|
||||
ejabberd:start_app(odbc),
|
||||
odbc:connect(binary_to_list(SQLServer), [{scrollable_cursors, off},
|
||||
{binary_strings, on}]).
|
||||
odbc:connect(binary_to_list(SQLServer),
|
||||
[{scrollable_cursors, off},
|
||||
{tuple_row, off},
|
||||
{binary_strings, on}]).
|
||||
|
||||
%% == Native SQLite code
|
||||
|
||||
@ -638,7 +641,15 @@ mysql_item_to_odbc(Columns, Recs) ->
|
||||
{selected, [element(2, Column) || Column <- Columns], Recs}.
|
||||
|
||||
to_odbc({selected, Columns, Recs}) ->
|
||||
{selected, [list_to_binary(Column) || Column <- Columns], [tuple_to_list(Rec) || Rec <- Recs]};
|
||||
Rows = [lists:map(
|
||||
fun(I) when is_integer(I) ->
|
||||
jlib:integer_to_binary(I);
|
||||
(B) ->
|
||||
B
|
||||
end, Row) || Row <- Recs],
|
||||
{selected, [list_to_binary(C) || C <- Columns], Rows};
|
||||
to_odbc({error, Reason}) when is_list(Reason) ->
|
||||
{error, list_to_binary(Reason)};
|
||||
to_odbc(Res) ->
|
||||
Res.
|
||||
|
||||
|
@ -58,17 +58,6 @@
|
||||
escape/1, count_records_where/3, get_roster_version/2,
|
||||
set_roster_version/2, opt_type/1]).
|
||||
|
||||
%% We have only two compile time options for db queries:
|
||||
%-define(generic, true).
|
||||
%-define(mssql, true).
|
||||
-ifndef(mssql).
|
||||
|
||||
-undef(generic).
|
||||
|
||||
-define(generic, true).
|
||||
|
||||
-endif.
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
@ -78,10 +67,6 @@
|
||||
join([], _Sep) -> [];
|
||||
join([H | T], Sep) -> [H, [[Sep, X] || X <- T]].
|
||||
|
||||
%% -----------------
|
||||
%% Generic queries
|
||||
-ifdef(generic).
|
||||
|
||||
get_db_type() -> generic.
|
||||
|
||||
%% Safe atomic update.
|
||||
@ -662,332 +647,6 @@ set_roster_version(LUser, Version) ->
|
||||
[<<"username">>, <<"version">>], [LUser, Version],
|
||||
[<<"username = '">>, LUser, <<"'">>]).
|
||||
|
||||
-endif.
|
||||
|
||||
%% -----------------
|
||||
%% MSSQL queries
|
||||
-ifdef(mssql).
|
||||
|
||||
%% Queries can be either a fun or a list of queries
|
||||
get_db_type() -> mssql.
|
||||
|
||||
sql_transaction(LServer, Queries)
|
||||
when is_list(Queries) ->
|
||||
F = fun () ->
|
||||
lists:foreach(fun (Query) ->
|
||||
ejabberd_odbc:sql_query(LServer, Query)
|
||||
end,
|
||||
Queries)
|
||||
end,
|
||||
{atomic, catch F()};
|
||||
sql_transaction(_LServer, FQueries) ->
|
||||
{atomic, catch FQueries()}.
|
||||
|
||||
get_last(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_last '">>, Username, <<"'">>]).
|
||||
|
||||
set_last_t(LServer, Username, Seconds, State) ->
|
||||
Result = ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.set_last '">>, Username,
|
||||
<<"', '">>, Seconds, <<"', '">>, State,
|
||||
<<"'">>]),
|
||||
{atomic, Result}.
|
||||
|
||||
del_last(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_last '">>, Username, <<"'">>]).
|
||||
|
||||
get_password(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_password '">>, Username,
|
||||
<<"'">>]).
|
||||
|
||||
set_password_t(LServer, Username, Pass) ->
|
||||
Result = ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.set_password '">>,
|
||||
Username, <<"', '">>, Pass, <<"'">>]),
|
||||
{atomic, Result}.
|
||||
|
||||
add_user(LServer, Username, Pass) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.add_user '">>, Username, <<"', '">>,
|
||||
Pass, <<"'">>]).
|
||||
|
||||
del_user(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_user '">>, Username, <<"'">>]).
|
||||
|
||||
del_user_return_password(LServer, Username, Pass) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_user_return_password '">>,
|
||||
Username, <<"'">>]),
|
||||
Pass.
|
||||
|
||||
list_users(LServer) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
<<"EXECUTE dbo.list_users">>).
|
||||
|
||||
list_users(LServer, _) -> list_users(LServer).
|
||||
|
||||
users_number(LServer) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
<<"select count(*) from users with (nolock)">>).
|
||||
|
||||
users_number(LServer, _) -> users_number(LServer).
|
||||
|
||||
add_spool_sql(Username, XML) ->
|
||||
[<<"EXECUTE dbo.add_spool '">>, Username, <<"' , '">>,
|
||||
XML, <<"'">>].
|
||||
|
||||
add_spool(LServer, Queries) ->
|
||||
lists:foreach(fun (Query) ->
|
||||
ejabberd_odbc:sql_query(LServer, Query)
|
||||
end,
|
||||
Queries).
|
||||
|
||||
get_and_del_spool_msg_t(LServer, Username) ->
|
||||
[Result] = case ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_and_del_spool_msg '">>,
|
||||
Username, <<"'">>])
|
||||
of
|
||||
Rs when is_list(Rs) ->
|
||||
lists:filter(fun ({selected, _Header, _Row}) -> true;
|
||||
({updated, _N}) -> false
|
||||
end,
|
||||
Rs);
|
||||
Rs -> [Rs]
|
||||
end,
|
||||
{atomic, Result}.
|
||||
|
||||
del_spool_msg(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_spool_msg '">>, Username,
|
||||
<<"'">>]).
|
||||
|
||||
get_roster(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_roster '">>, Username,
|
||||
<<"'">>]).
|
||||
|
||||
get_roster_jid_groups(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_roster_jid_groups '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
get_roster_groups(LServer, Username, SJID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_roster_groups '">>, Username,
|
||||
<<"' , '">>, SJID, <<"'">>]).
|
||||
|
||||
del_user_roster_t(LServer, Username) ->
|
||||
Result = ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_user_roster '">>,
|
||||
Username, <<"'">>]),
|
||||
{atomic, Result}.
|
||||
|
||||
get_roster_by_jid(LServer, Username, SJID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_roster_by_jid '">>, Username,
|
||||
<<"' , '">>, SJID, <<"'">>]).
|
||||
|
||||
get_rostergroup_by_jid(LServer, Username, SJID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_rostergroup_by_jid '">>,
|
||||
Username, <<"' , '">>, SJID, <<"'">>]).
|
||||
|
||||
del_roster(LServer, Username, SJID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_roster '">>, Username,
|
||||
<<"', '">>, SJID, <<"'">>]).
|
||||
|
||||
del_roster_sql(Username, SJID) ->
|
||||
[<<"EXECUTE dbo.del_roster '">>, Username, <<"', '">>,
|
||||
SJID, <<"'">>].
|
||||
|
||||
update_roster(LServer, Username, SJID, ItemVals,
|
||||
ItemGroups) ->
|
||||
Query1 = [<<"EXECUTE dbo.del_roster '">>, Username,
|
||||
<<"', '">>, SJID, <<"' ">>],
|
||||
ejabberd_odbc:sql_query(LServer, lists:flatten(Query1)),
|
||||
Query2 = [<<"EXECUTE dbo.add_roster_user ">>, ItemVals],
|
||||
ejabberd_odbc:sql_query(LServer, lists:flatten(Query2)),
|
||||
Query3 = [<<"EXECUTE dbo.del_roster_groups '">>,
|
||||
Username, <<"', '">>, SJID, <<"' ">>],
|
||||
ejabberd_odbc:sql_query(LServer, lists:flatten(Query3)),
|
||||
lists:foreach(fun (ItemGroup) ->
|
||||
Query = [<<"EXECUTE dbo.add_roster_group ">>,
|
||||
ItemGroup],
|
||||
ejabberd_odbc:sql_query(LServer, lists:flatten(Query))
|
||||
end,
|
||||
ItemGroups).
|
||||
|
||||
update_roster_sql(Username, SJID, ItemVals,
|
||||
ItemGroups) ->
|
||||
[<<"BEGIN TRANSACTION ">>,
|
||||
<<"EXECUTE dbo.del_roster_groups '">>, Username,
|
||||
<<"','">>, SJID, <<"' ">>,
|
||||
<<"EXECUTE dbo.add_roster_user ">>, ItemVals, <<" ">>]
|
||||
++
|
||||
[lists:flatten(<<"EXECUTE dbo.add_roster_group ">>,
|
||||
ItemGroup, <<" ">>)
|
||||
|| ItemGroup <- ItemGroups]
|
||||
++ [<<"COMMIT">>].
|
||||
|
||||
roster_subscribe(LServer, _Username, _SJID, ItemVals) ->
|
||||
catch ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.add_roster_user ">>,
|
||||
ItemVals]).
|
||||
|
||||
get_subscription(LServer, Username, SJID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_subscription '">>, Username,
|
||||
<<"' , '">>, SJID, <<"'">>]).
|
||||
|
||||
set_private_data(LServer, Username, LXMLNS, SData) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
set_private_data_sql(Username, LXMLNS, SData)).
|
||||
|
||||
set_private_data_sql(Username, LXMLNS, SData) ->
|
||||
[<<"EXECUTE dbo.set_private_data '">>, Username,
|
||||
<<"' , '">>, LXMLNS, <<"' , '">>, SData, <<"'">>].
|
||||
|
||||
get_private_data(LServer, Username, LXMLNS) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_private_data '">>, Username,
|
||||
<<"' , '">>, LXMLNS, <<"'">>]).
|
||||
|
||||
del_user_private_storage(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_user_storage '">>, Username,
|
||||
<<"'">>]).
|
||||
|
||||
set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN,
|
||||
SFamily, SGiven, SLBDay, SLCTRY, SLEMail, SLFN,
|
||||
SLFamily, SLGiven, SLLocality, SLMiddle, SLNickname,
|
||||
SLOrgName, SLOrgUnit, SLocality, SMiddle, SNickname,
|
||||
SOrgName, SOrgUnit, SVCARD, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.set_vcard '">>, SVCARD, <<"' , '">>,
|
||||
Username, <<"' , '">>, LUsername, <<"' , '">>, SFN,
|
||||
<<"' , '">>, SLFN, <<"' , '">>, SFamily,
|
||||
<<"' , '">>, SLFamily, <<"' , '">>, SGiven,
|
||||
<<"' , '">>, SLGiven, <<"' , '">>, SMiddle,
|
||||
<<"' , '">>, SLMiddle, <<"' , '">>, SNickname,
|
||||
<<"' , '">>, SLNickname, <<"' , '">>, SBDay,
|
||||
<<"' , '">>, SLBDay, <<"' , '">>, SCTRY,
|
||||
<<"' , '">>, SLCTRY, <<"' , '">>, SLocality,
|
||||
<<"' , '">>, SLLocality, <<"' , '">>, SEMail,
|
||||
<<"' , '">>, SLEMail, <<"' , '">>, SOrgName,
|
||||
<<"' , '">>, SLOrgName, <<"' , '">>, SOrgUnit,
|
||||
<<"' , '">>, SLOrgUnit, <<"'">>]).
|
||||
|
||||
get_vcard(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_vcard '">>, Username, <<"'">>]).
|
||||
|
||||
get_default_privacy_list(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_default_privacy_list '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
get_default_privacy_list_t(Username) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.get_default_privacy_list '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
get_privacy_list_names(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_privacy_list_names '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
get_privacy_list_names_t(Username) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.get_privacy_list_names '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
get_privacy_list_id(LServer, Username, SName) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_privacy_list_id '">>, Username,
|
||||
<<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
get_privacy_list_id_t(Username, SName) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.get_privacy_list_id '">>,
|
||||
Username, <<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
get_privacy_list_data(LServer, Username, SName) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_privacy_list_data '">>,
|
||||
Username, <<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
get_privacy_list_data_by_id(LServer, ID) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_privacy_list_data_by_id '">>,
|
||||
ID, <<"'">>]).
|
||||
|
||||
get_privacy_list_data_by_id_t(ID) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.get_privacy_list_data_by_id '">>,
|
||||
ID, <<"'">>]).
|
||||
|
||||
set_default_privacy_list(Username, SName) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.set_default_privacy_list '">>,
|
||||
Username, <<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
unset_default_privacy_list(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.unset_default_privacy_list '">>,
|
||||
Username, <<"'">>]).
|
||||
|
||||
remove_privacy_list(Username, SName) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.remove_privacy_list '">>,
|
||||
Username, <<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
add_privacy_list(Username, SName) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.add_privacy_list '">>,
|
||||
Username, <<"' , '">>, SName, <<"'">>]).
|
||||
|
||||
set_privacy_list(ID, RItems) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.del_privacy_list_by_id '">>,
|
||||
ID, <<"'">>]),
|
||||
lists:foreach(fun (Items) ->
|
||||
ejabberd_odbc:sql_query_t([<<"EXECUTE dbo.set_privacy_list '">>,
|
||||
ID, <<"', '">>,
|
||||
join(Items, <<"', '">>),
|
||||
<<"'">>])
|
||||
end,
|
||||
RItems).
|
||||
|
||||
del_privacy_lists(LServer, Server, Username) ->
|
||||
%% Characters to escape
|
||||
%% Count number of records in a table given a where clause
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.del_privacy_lists @Server='">>,
|
||||
Server, <<"' @username='">>, Username, <<"'">>]).
|
||||
|
||||
escape($\000) -> <<"\\0">>;
|
||||
escape($\t) -> <<"\\t">>;
|
||||
escape($\b) -> <<"\\b">>;
|
||||
escape($\r) -> <<"\\r">>;
|
||||
escape($') -> <<"''">>;
|
||||
escape($") -> <<"\\\"">>;
|
||||
escape(C) -> C.
|
||||
|
||||
count_records_where(LServer, Table, WhereClause) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"select count(*) from ">>, Table,
|
||||
<<" with (nolock) ">>, WhereClause]).
|
||||
|
||||
get_roster_version(LServer, LUser) ->
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.get_roster_version '">>, LUser,
|
||||
<<"'">>]).
|
||||
|
||||
set_roster_version(Username, Version) ->
|
||||
LServer = (?MYNAME),
|
||||
ejabberd_odbc:sql_query(LServer,
|
||||
[<<"EXECUTE dbo.set_roster_version '">>, Username,
|
||||
<<"', '">>, Version, <<"'">>]).
|
||||
|
||||
-endif.
|
||||
|
||||
opt_type(odbc_type) ->
|
||||
fun (pgsql) -> pgsql;
|
||||
(mysql) -> mysql;
|
||||
|
Loading…
Reference in New Issue
Block a user