diff --git a/apps/ejabberd/src/ejabberd_binary.erl b/apps/ejabberd/src/ejabberd_binary.erl index af7bec3ff4b..4e1c9f22b81 100644 --- a/apps/ejabberd/src/ejabberd_binary.erl +++ b/apps/ejabberd/src/ejabberd_binary.erl @@ -20,3 +20,4 @@ string_to_binary(S) when is_list(S) -> list_to_binary(S); string_to_binary(B) when is_binary(B) -> B. + diff --git a/apps/ejabberd/src/ejabberd_odbc.erl b/apps/ejabberd/src/ejabberd_odbc.erl index 6f47416c48e..2cb08dea053 100644 --- a/apps/ejabberd/src/ejabberd_odbc.erl +++ b/apps/ejabberd/src/ejabberd_odbc.erl @@ -494,14 +494,14 @@ 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 -> %% Retry outer transaction upto NRestarts times. - sql_query_internal(<<"rollback;">>), + sql_query_internal([<<"rollback;">>]), outer_transaction(F, NRestarts - 1, Reason); {aborted, Reason} when NRestarts =:= 0 -> %% Too many retries of outer transaction. @@ -512,15 +512,15 @@ outer_transaction(F, NRestarts, _Reason) -> "** When State == ~p", [?MAX_TRANSACTION_RESTARTS, Reason, erlang:get_stacktrace(), get(?STATE_KEY)]), - sql_query_internal(<<"rollback;">>), + sql_query_internal([<<"rollback;">>]), {aborted, Reason}; {'EXIT', Reason} -> %% Abort sql transaction on EXIT from outer txn only. - sql_query_internal(<<"rollback;">>), + sql_query_internal([<<"rollback;">>]), {aborted, Reason}; Res -> %% Commit successful outer txn - sql_query_internal(<<"commit;">>), + sql_query_internal([<<"commit;">>]), {atomic, Res} end. @@ -541,7 +541,7 @@ sql_query_internal(Query) -> State = get(?STATE_KEY), Res = case State#state.db_type of odbc -> - odbc:sql_query(State#state.db_ref, Query); + binaryze_odbc(odbc:sql_query(State#state.db_ref, Query)); pgsql -> ?DEBUG("Postres, Send query~n~p~n", [Query]), pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query)); @@ -585,6 +585,20 @@ odbc_connect(SQLServer) -> application:start(odbc), odbc:connect(SQLServer, [{scrollable_cursors, off}]). +binaryze_odbc(ODBCResults) when is_list(ODBCResults) -> + lists:map(fun binaryze_odbc/1, ODBCResults); +binaryze_odbc({selected, ColNames, Rows}) -> + ColNamesB = lists:map(fun ejabberd_binary:string_to_binary/1, ColNames), + RowsB = lists:map(fun binaryze_tuple/1, Rows), + {selected, ColNamesB, RowsB}; +binaryze_odbc(ODBCResult) -> + ODBCResult. + +binaryze_tuple(Tuple) when is_tuple(Tuple) -> + Binarized = lists:map(fun try_binaryze/1, + tuple_to_list(Tuple)), + list_to_tuple(Binarized). + %% == Native PostgreSQL code %% part of init/1 @@ -736,3 +750,14 @@ fsm_limit_opts() -> _ -> [] end. + +-spec try_binaryze(term()) -> term(). +try_binaryze(List) when is_list(List) -> + case io_lib:printable_unicode_list(List) of + true -> + ejabberd_binary:string_to_binary(List); + _ -> + List + end; +try_binaryze(Other) -> + Other. \ No newline at end of file diff --git a/apps/ejabberd/src/odbc_queries.erl b/apps/ejabberd/src/odbc_queries.erl index e38a085f053..09e0f423f01 100644 --- a/apps/ejabberd/src/odbc_queries.erl +++ b/apps/ejabberd/src/odbc_queries.erl @@ -734,7 +734,7 @@ escape_character($\n) -> "\\n"; escape_character($\t) -> "\\t"; escape_character($\b) -> "\\b"; escape_character($\r) -> "\\r"; -escape_character($') -> "\\'"; +escape_character($') -> "''"; escape_character($") -> "\\\""; escape_character($\\) -> "\\\\"; escape_character(C) -> C. diff --git a/rel/reltool.config b/rel/reltool.config index 820f82f7ce4..94b70610bbe 100644 --- a/rel/reltool.config +++ b/rel/reltool.config @@ -53,6 +53,7 @@ {app, runtime_tools, [{incl_cond, include}]}, {app, mysql, [{incl_cond, include}]}, {app, pgsql, [{incl_cond, include}]}, + {app, odbc, [{incl_cond, include}]}, {app, redo, [{incl_cond, include}]}, {app, cuesport, [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]},