mirror of
https://github.com/processone/ejabberd.git
synced 2024-09-19 14:03:03 +02:00
Native MySQL support. The Erlang MySQL module is needed:
http://support.process-one.net/doc/display/CONTRIBS/Yxa SVN Revision: 482
This commit is contained in:
parent
7ee3e45df1
commit
8401a5ac55
@ -1,3 +1,7 @@
|
|||||||
|
2006-01-02 Mickael Remond <mickael.remond@process-one.net>
|
||||||
|
|
||||||
|
* src/odbc/ejabberd_odbc.erl: Native MySQL support
|
||||||
|
|
||||||
2005-12-24 Alexey Shchepin <alexey@sevcom.net>
|
2005-12-24 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/ejabberd_logger_h.erl: Speed optimizations
|
* src/ejabberd_logger_h.erl: Speed optimizations
|
||||||
|
@ -49,7 +49,7 @@ check_password(User, Server, Password) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["select password from users "
|
["select password from users "
|
||||||
"where username='", Username, "'"]) of
|
"where username='", Username, "';"]) of
|
||||||
{selected, ["password"], [{Password}]} ->
|
{selected, ["password"], [{Password}]} ->
|
||||||
true;
|
true;
|
||||||
_ ->
|
_ ->
|
||||||
@ -66,7 +66,7 @@ check_password(User, Server, Password, StreamID, Digest) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["select password from users "
|
["select password from users "
|
||||||
"where username='", Username, "'"]) of
|
"where username='", Username, "';"]) of
|
||||||
{selected, ["password"], [{Passwd}]} ->
|
{selected, ["password"], [{Passwd}]} ->
|
||||||
DigRes = if
|
DigRes = if
|
||||||
Digest /= "" ->
|
Digest /= "" ->
|
||||||
@ -110,7 +110,7 @@ try_register(User, Server, Password) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["insert into users(username, password) "
|
["insert into users(username, password) "
|
||||||
"values ('", Username, "', '", Pass, "')"]) of
|
"values ('", Username, "', '", Pass, "');"]) of
|
||||||
{updated, 1} ->
|
{updated, 1} ->
|
||||||
{atomic, ok};
|
{atomic, ok};
|
||||||
_ ->
|
_ ->
|
||||||
@ -141,7 +141,7 @@ get_password(User, Server) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["select password from users "
|
["select password from users "
|
||||||
"where username='", Username, "'"]) of
|
"where username='", Username, "';"]) of
|
||||||
{selected, ["password"], [{Password}]} ->
|
{selected, ["password"], [{Password}]} ->
|
||||||
Password;
|
Password;
|
||||||
_ ->
|
_ ->
|
||||||
@ -158,7 +158,7 @@ get_password_s(User, Server) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["select password from users "
|
["select password from users "
|
||||||
"where username='", Username, "'"]) of
|
"where username='", Username, "';"]) of
|
||||||
{selected, ["password"], [{Password}]} ->
|
{selected, ["password"], [{Password}]} ->
|
||||||
Password;
|
Password;
|
||||||
_ ->
|
_ ->
|
||||||
@ -175,7 +175,7 @@ is_user_exists(User, Server) ->
|
|||||||
case catch ejabberd_odbc:sql_query(
|
case catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["select password from users "
|
["select password from users "
|
||||||
"where username='", Username, "'"]) of
|
"where username='", Username, "';"]) of
|
||||||
{selected, ["password"], [{_Password}]} ->
|
{selected, ["password"], [{_Password}]} ->
|
||||||
true;
|
true;
|
||||||
_ ->
|
_ ->
|
||||||
@ -191,7 +191,7 @@ remove_user(User, Server) ->
|
|||||||
Username = ejabberd_odbc:escape(LUser),
|
Username = ejabberd_odbc:escape(LUser),
|
||||||
catch ejabberd_odbc:sql_query(
|
catch ejabberd_odbc:sql_query(
|
||||||
jlib:nameprep(Server),
|
jlib:nameprep(Server),
|
||||||
["delete from users where username='", Username ,"'"]),
|
["delete from users where username='", Username ,"';"]),
|
||||||
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
|
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
|
||||||
[User, Server])
|
[User, Server])
|
||||||
end.
|
end.
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
-define(STATE_KEY, ejabberd_odbc_state).
|
-define(STATE_KEY, ejabberd_odbc_state).
|
||||||
-define(MAX_TRANSACTION_RESTARTS, 10).
|
-define(MAX_TRANSACTION_RESTARTS, 10).
|
||||||
|
-define(MYSQL_PORT, 3306).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
@ -114,24 +115,14 @@ init([Host]) ->
|
|||||||
SQLServer = ejabberd_config:get_local_option({odbc_server, Host}),
|
SQLServer = ejabberd_config:get_local_option({odbc_server, Host}),
|
||||||
case SQLServer of
|
case SQLServer of
|
||||||
{pgsql, Server, DB, Username, Password} ->
|
{pgsql, Server, DB, Username, Password} ->
|
||||||
case pgsql:connect(Server, DB, Username, Password) of
|
pgsql_connect(Server, DB, Username, Password);
|
||||||
{ok, Ref} ->
|
{mysql, Server, DB, Username, Password} ->
|
||||||
{ok, #state{db_ref = Ref, db_type = pgsql}};
|
mysql_connect(Server, DB, Username, Password);
|
||||||
{error, Reason} ->
|
|
||||||
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
|
|
||||||
{stop, pgsql_connection_failed}
|
|
||||||
end;
|
|
||||||
_ when is_list(SQLServer) ->
|
_ when is_list(SQLServer) ->
|
||||||
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
|
odbc_connect(SQLServer)
|
||||||
{ok, Ref} ->
|
|
||||||
{ok, #state{db_ref = Ref, db_type = odbc}};
|
|
||||||
{error, Reason} ->
|
|
||||||
?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
|
|
||||||
[SQLServer, Reason]),
|
|
||||||
{stop, odbc_connection_failed}
|
|
||||||
end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
%% Func: handle_call/3
|
%% Func: handle_call/3
|
||||||
%% Returns: {reply, Reply, State} |
|
%% Returns: {reply, Reply, State} |
|
||||||
@ -192,7 +183,9 @@ sql_query_internal(State, Query) ->
|
|||||||
odbc ->
|
odbc ->
|
||||||
odbc:sql_query(State#state.db_ref, Query);
|
odbc:sql_query(State#state.db_ref, Query);
|
||||||
pgsql ->
|
pgsql ->
|
||||||
pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query))
|
pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query));
|
||||||
|
mysql ->
|
||||||
|
mysql_to_odbc(mysql_conn:fetch(State#state.db_ref, Query, self()))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
execute_transaction(_State, _F, 0) ->
|
execute_transaction(_State, _F, 0) ->
|
||||||
@ -211,6 +204,35 @@ execute_transaction(State, F, NRestarts) ->
|
|||||||
{atomic, Res}
|
{atomic, Res}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% == pure ODBC code
|
||||||
|
|
||||||
|
%% part of init/1
|
||||||
|
%% Open an ODBC database connection
|
||||||
|
odbc_connect(SQLServer) ->
|
||||||
|
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
|
||||||
|
{ok, Ref} ->
|
||||||
|
{ok, #state{db_ref = Ref, db_type = odbc}};
|
||||||
|
{error, Reason} ->
|
||||||
|
?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
|
||||||
|
[SQLServer, Reason]),
|
||||||
|
{stop, odbc_connection_failed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% == Native PostgreSQL code
|
||||||
|
|
||||||
|
%% part of init/1
|
||||||
|
%% Open a database connection to PostgreSQL
|
||||||
|
pgsql_connect(Server, DB, Username, Password) ->
|
||||||
|
case pgsql:connect(Server, DB, Username, Password) of
|
||||||
|
{ok, Ref} ->
|
||||||
|
{ok, #state{db_ref = Ref, db_type = pgsql}};
|
||||||
|
{error, Reason} ->
|
||||||
|
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
|
||||||
|
{stop, pgsql_connection_failed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Convert PostgreSQL query result to Erlang ODBC result formalism
|
||||||
pgsql_to_odbc({ok, PGSQLResult}) ->
|
pgsql_to_odbc({ok, PGSQLResult}) ->
|
||||||
case PGSQLResult of
|
case PGSQLResult of
|
||||||
[Item] ->
|
[Item] ->
|
||||||
@ -233,3 +255,33 @@ pgsql_item_to_odbc({error, Error}) ->
|
|||||||
pgsql_item_to_odbc(_) ->
|
pgsql_item_to_odbc(_) ->
|
||||||
{updated,undefined}.
|
{updated,undefined}.
|
||||||
|
|
||||||
|
%% == Native MySQL code
|
||||||
|
|
||||||
|
%% part of init/1
|
||||||
|
%% Open a database connection to MySQL
|
||||||
|
mysql_connect(Server, DB, Username, Password) ->
|
||||||
|
NoLogFun = fun(_Level,_Format,_Argument) -> ok end,
|
||||||
|
case mysql_conn:start(Server, ?MYSQL_PORT, Username, Password, DB, NoLogFun) of
|
||||||
|
{ok, Ref} ->
|
||||||
|
{ok, #state{db_ref = Ref, db_type = mysql}};
|
||||||
|
{error, Reason} ->
|
||||||
|
?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
||||||
|
{stop, mysql_connection_failed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Convert MySQL query result to Erlang ODBC result formalism
|
||||||
|
mysql_to_odbc({updated, MySQLRes}) ->
|
||||||
|
{updated, mysql:get_result_affected_rows(MySQLRes)};
|
||||||
|
mysql_to_odbc({data, MySQLRes}) ->
|
||||||
|
mysql_item_to_odbc(mysql:get_result_field_info(MySQLRes),
|
||||||
|
mysql:get_result_rows(MySQLRes));
|
||||||
|
mysql_to_odbc({error, MySQLRes}) ->
|
||||||
|
{error, mysql:get_result_reason(MySQLRes)}.
|
||||||
|
|
||||||
|
%% When tabular data is returned, convert it to the ODBC formalism
|
||||||
|
mysql_item_to_odbc(Columns, Recs) ->
|
||||||
|
%% For now, there is a bug and we do not get the correct value from MySQL
|
||||||
|
%% module:
|
||||||
|
{selected,
|
||||||
|
[element(2, Column) || Column <- Columns],
|
||||||
|
[list_to_tuple(Rec) || Rec <- Recs]}.
|
||||||
|
Loading…
Reference in New Issue
Block a user