]> granicus.if.org Git - ejabberd/commitdiff
Native MySQL support. The Erlang MySQL module is needed:
authorMickaël Rémond <mickael.remond@process-one.net>
Mon, 2 Jan 2006 17:39:04 +0000 (17:39 +0000)
committerMickaël Rémond <mickael.remond@process-one.net>
Mon, 2 Jan 2006 17:39:04 +0000 (17:39 +0000)
http://support.process-one.net/doc/display/CONTRIBS/Yxa

SVN Revision: 482

ChangeLog
src/ejabberd_auth_odbc.erl
src/odbc/ejabberd_odbc.erl

index 8dba50b626b36cf6c39158d31bc08ce9fcb3594d..47bbd42b706173e374f57ae788613e8628a01cdc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * src/ejabberd_logger_h.erl: Speed optimizations
index c09133488970bdf3bb2215722804ce5e434156ac..4975b51047a8db69e900b6b0f82c1e1f07b9ad22 100644 (file)
@@ -49,7 +49,7 @@ check_password(User, Server, Password) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["select password from users "
-                         "where username='", Username, "'"]) of
+                         "where username='", Username, "';"]) of
                {selected, ["password"], [{Password}]} ->
                    true;
                _ ->
@@ -66,7 +66,7 @@ check_password(User, Server, Password, StreamID, Digest) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["select password from users "
-                         "where username='", Username, "'"]) of
+                         "where username='", Username, "';"]) of
                {selected, ["password"], [{Passwd}]} ->
                    DigRes = if
                                 Digest /= "" ->
@@ -110,7 +110,7 @@ try_register(User, Server, Password) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["insert into users(username, password) "
-                         "values ('", Username, "', '", Pass, "')"]) of
+                         "values ('", Username, "', '", Pass, "');"]) of
                {updated, 1} ->
                    {atomic, ok};
                _ ->
@@ -141,7 +141,7 @@ get_password(User, Server) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["select password from users "
-                         "where username='", Username, "'"]) of
+                         "where username='", Username, "';"]) of
                {selected, ["password"], [{Password}]} ->
                    Password;
                _ ->
@@ -158,7 +158,7 @@ get_password_s(User, Server) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["select password from users "
-                         "where username='", Username, "'"]) of
+                         "where username='", Username, "';"]) of
                {selected, ["password"], [{Password}]} ->
                    Password;
                _ ->
@@ -175,7 +175,7 @@ is_user_exists(User, Server) ->
            case catch ejabberd_odbc:sql_query(
                         jlib:nameprep(Server),
                         ["select password from users "
-                         "where username='", Username, "'"]) of
+                         "where username='", Username, "';"]) of
                {selected, ["password"], [{_Password}]} ->
                    true;
                _ ->
@@ -191,7 +191,7 @@ remove_user(User, Server) ->
            Username = ejabberd_odbc:escape(LUser),
            catch ejabberd_odbc:sql_query(
                    jlib:nameprep(Server),
-                   ["delete from users where username='", Username ,"'"]),
+                   ["delete from users where username='", Username ,"';"]),
            ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
                               [User, Server])
     end.
index 473446782c85fd7c1e5da4a8febc445055fb9b1b..4c2598493db91634a78323a72efc636b649b5a22 100644 (file)
@@ -33,6 +33,7 @@
 
 -define(STATE_KEY, ejabberd_odbc_state).
 -define(MAX_TRANSACTION_RESTARTS, 10).
+-define(MYSQL_PORT, 3306).
 
 %%%----------------------------------------------------------------------
 %%% API
@@ -114,24 +115,14 @@ init([Host]) ->
     SQLServer = ejabberd_config:get_local_option({odbc_server, Host}),
     case SQLServer of
        {pgsql, 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;
+           pgsql_connect(Server, DB, Username, Password);
+       {mysql, Server, DB, Username, Password} ->
+           mysql_connect(Server, DB, Username, Password);
        _ when is_list(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
+           odbc_connect(SQLServer)
     end.
 
+
 %%----------------------------------------------------------------------
 %% Func: handle_call/3
 %% Returns: {reply, Reply, State}          |
@@ -192,7 +183,9 @@ sql_query_internal(State, Query) ->
        odbc ->
            odbc:sql_query(State#state.db_ref, Query);
        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.
 
 execute_transaction(_State, _F, 0) ->
@@ -211,6 +204,35 @@ execute_transaction(State, F, NRestarts) ->
            {atomic, Res}
     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}) ->
     case PGSQLResult of
        [Item] ->
@@ -233,3 +255,33 @@ pgsql_item_to_odbc({error, Error}) ->
 pgsql_item_to_odbc(_) ->
     {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]}.