summaryrefslogtreecommitdiff
path: root/src/odbc/ejabberd_odbc.erl
diff options
context:
space:
mode:
authorMickaël Rémond <mickael.remond@process-one.net>2006-01-02 17:39:04 +0000
committerMickaël Rémond <mickael.remond@process-one.net>2006-01-02 17:39:04 +0000
commit8401a5ac55e756f7a4e74afd7916b38e0d65e02a (patch)
treee3b8a442a437d3100f09473173addc92022e13d0 /src/odbc/ejabberd_odbc.erl
parent* src/ejabberd_logger_h.erl: Speed optimizations (diff)
Native MySQL support. The Erlang MySQL module is needed:
http://support.process-one.net/doc/display/CONTRIBS/Yxa SVN Revision: 482
Diffstat (limited to 'src/odbc/ejabberd_odbc.erl')
-rw-r--r--src/odbc/ejabberd_odbc.erl84
1 files changed, 68 insertions, 16 deletions
diff --git a/src/odbc/ejabberd_odbc.erl b/src/odbc/ejabberd_odbc.erl
index 47344678..4c259849 100644
--- a/src/odbc/ejabberd_odbc.erl
+++ b/src/odbc/ejabberd_odbc.erl
@@ -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]}.