Fix MSSQL support

This commit is contained in:
Evgeniy Khramtsov
2015-09-13 14:20:31 +03:00
parent 48c5e73321
commit 25791cfde8
6 changed files with 19 additions and 5028 deletions
BIN
View File
Binary file not shown.
-1095
View File
File diff suppressed because it is too large Load Diff
-1802
View File
File diff suppressed because it is too large Load Diff
-1782
View File
File diff suppressed because it is too large Load Diff
+19 -8
View File
@@ -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.
-341
View File
@@ -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;