diff options
Diffstat (limited to '')
-rw-r--r-- | src/mysql/mysql.erl | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/src/mysql/mysql.erl b/src/mysql/mysql.erl deleted file mode 100644 index 2920b450..00000000 --- a/src/mysql/mysql.erl +++ /dev/null @@ -1,692 +0,0 @@ -%%%------------------------------------------------------------------- -%%% File : mysql.erl -%%% Author : Magnus Ahltorp <ahltorp@nada.kth.se> -%%% Descrip.: MySQL client. -%%% -%%% Created : 4 Aug 2005 by Magnus Ahltorp <ahltorp@nada.kth.se> -%%% -%%% Copyright (c) 2001-2004 Kungliga Tekniska Högskolan -%%% See the file COPYING -%%% -%%% Usage: -%%% -%%% -%%% Call one of the start-functions before any call to fetch/2 -%%% -%%% start_link(Id, Host, User, Password, Database) -%%% start_link(Id, Host, Port, User, Password, Database) -%%% start_link(Id, Host, User, Password, Database, LogFun) -%%% start_link(Id, Host, Port, User, Password, Database, LogFun) -%%% -%%% Id is a connection group identifier. If you want to have more -%%% than one connection to a server (or a set of MySQL replicas), -%%% add more with -%%% -%%% connect(Id, Host, Port, User, Password, Database, Reconnect) -%%% -%%% use 'undefined' as Port to get default MySQL port number (3306). -%%% MySQL querys will be sent in a per-Id round-robin fashion. -%%% Set Reconnect to 'true' if you want the dispatcher to try and -%%% open a new connection, should this one die. -%%% -%%% When you have a mysql_dispatcher running, this is how you make a -%%% query : -%%% -%%% fetch(Id, "select * from hello") -> Result -%%% Result = {data, MySQLRes} | {updated, MySQLRes} | -%%% {error, MySQLRes} -%%% -%%% Actual data can be extracted from MySQLRes by calling the following API -%%% functions: -%%% - on data received: -%%% FieldInfo = mysql:get_result_field_info(MysqlRes) -%%% AllRows = mysql:get_result_rows(MysqlRes) -%%% with FieldInfo = list() of {Table, Field, Length, Name} -%%% and AllRows = list() of list() representing records -%%% - on update: -%%% Affected = mysql:get_result_affected_rows(MysqlRes) -%%% with Affected = integer() -%%% - on error: -%%% Reason = mysql:get_result_reason(MysqlRes) -%%% with Reason = string() -%%% -%%% If you just want a single MySQL connection, or want to manage your -%%% connections yourself, you can use the mysql_conn module as a -%%% stand-alone single MySQL connection. See the comment at the top of -%%% mysql_conn.erl. -%%% -%%%------------------------------------------------------------------- --module(mysql). - --behaviour(gen_server). - -%%-------------------------------------------------------------------- -%% External exports -%%-------------------------------------------------------------------- --export([start_link/5, - start_link/6, - start_link/7, - - fetch/2, - fetch/3, - - get_result_field_info/1, - get_result_rows/1, - get_result_affected_rows/1, - get_result_reason/1, - - quote/1, - asciz_binary/2, - - connect/7, - stop/0, - - gc_each/1 - ]). - -%%-------------------------------------------------------------------- -%% Internal exports - just for mysql_* modules -%%-------------------------------------------------------------------- --export([log/3, - log/4 - ]). - -%%-------------------------------------------------------------------- -%% Internal exports - gen_server callbacks -%%-------------------------------------------------------------------- --export([init/1, - handle_call/3, - handle_cast/2, - handle_info/2, - terminate/2, - code_change/3 - ]). - -%%-------------------------------------------------------------------- -%% Records -%%-------------------------------------------------------------------- --include("mysql.hrl"). --record(state, { - conn_list, %% list() of mysql_connection record() - log_fun, %% undefined | function for logging, - gc_tref %% undefined | timer:TRef - }). - --record(mysql_connection, { - id, %% term(), user of 'mysql' modules id of this socket group - conn_pid, %% pid(), mysql_conn process - reconnect, %% true | false, should mysql_dispatcher try to reconnect if this connection dies? - host, %% undefined | string() - port, %% undefined | integer() - user, %% undefined | string() - password, %% undefined | string() - database %% undefined | string() - }). - -%%-------------------------------------------------------------------- -%% Macros -%%-------------------------------------------------------------------- --define(SERVER, mysql_dispatcher). --define(CONNECT_TIMEOUT, 5000). --define(LOCAL_FILES, 128). - --define(PORT, 3306). - - -%%==================================================================== -%% External functions -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: start_link(Id, Host, User, Password, Database) -%% start_link(Id, Host, Port, User, Password, Database) -%% start_link(Id, Host, User, Password, Database, LogFun) -%% start_link(Id, Host, Port, User, Password, Database, -%% LogFun) -%% Id = term(), first connection-group Id -%% Host = string() -%% Port = integer() -%% User = string() -%% Password = string() -%% Database = string() -%% LogFun = undefined | function() of arity 3 -%% Descrip.: Starts the MySQL client gen_server process. -%% Returns : {ok, Pid} | ignore | {error, Error} -%%-------------------------------------------------------------------- -start_link(Id, Host, User, Password, Database) when is_list(Host), is_list(User), is_list(Password), - is_list(Database) -> - start_link(Id, Host, ?PORT, User, Password, Database, undefined). - -start_link(Id, Host, Port, User, Password, Database) when is_list(Host), is_integer(Port), is_list(User), - is_list(Password), is_list(Database) -> - start_link(Id, Host, Port, User, Password, Database, undefined); - -start_link(Id, Host, User, Password, Database, LogFun) when is_list(Host), is_list(User), is_list(Password), - is_list(Database) -> - start_link(Id, Host, ?PORT, User, Password, Database, LogFun). - -start_link(Id, Host, Port, User, Password, Database, LogFun) when is_list(Host), is_integer(Port), is_list(User), - is_list(Password), is_list(Database) -> - crypto:start(), - gen_server:start_link({local, ?SERVER}, ?MODULE, [Id, Host, Port, User, Password, Database, LogFun], []). - -stop() -> - gen_server:call(?SERVER, stop). - -gc_each(Millisec) -> - gen_server:call(?SERVER, {gc_each, Millisec}). - -%%-------------------------------------------------------------------- -%% Function: fetch(Id, Query) -%% fetch(Id, Query, Timeout) -%% Id = term(), connection-group Id -%% Query = string(), MySQL query in verbatim -%% Timeout = integer() | infinity, gen_server timeout value -%% Descrip.: Send a query and wait for the result. -%% Returns : {data, MySQLRes} | -%% {updated, MySQLRes} | -%% {error, MySQLRes} -%% MySQLRes = term() -%%-------------------------------------------------------------------- -fetch(Id, Query) when is_list(Query) -> - gen_server:call(?SERVER, {fetch, Id, Query}). -fetch(Id, Query, Timeout) when is_list(Query) -> - gen_server:call(?SERVER, {fetch, Id, Query}, Timeout). - -%%-------------------------------------------------------------------- -%% Function: get_result_field_info(MySQLRes) -%% MySQLRes = term(), result of fetch function on "data" -%% Descrip.: Extract the FieldInfo from MySQL Result on data received -%% Returns : FieldInfo -%% FieldInfo = list() of {Table, Field, Length, Name} -%%-------------------------------------------------------------------- -get_result_field_info(#mysql_result{fieldinfo = FieldInfo}) -> - FieldInfo. - -%%-------------------------------------------------------------------- -%% Function: get_result_rows(MySQLRes) -%% MySQLRes = term(), result of fetch function on "data" -%% Descrip.: Extract the Rows from MySQL Result on data received -%% Returns : Rows -%% Rows = list() of list() representing records -%%-------------------------------------------------------------------- -get_result_rows(#mysql_result{rows=AllRows}) -> - AllRows. - -%%-------------------------------------------------------------------- -%% Function: get_result_affected_rows(MySQLRes) -%% MySQLRes = term(), result of fetch function on "updated" -%% Descrip.: Extract the Rows from MySQL Result on update -%% Returns : AffectedRows -%% AffectedRows = integer() -%%-------------------------------------------------------------------- -get_result_affected_rows(#mysql_result{affectedrows=AffectedRows}) -> - AffectedRows. - -%%-------------------------------------------------------------------- -%% Function: get_result_reason(MySQLRes) -%% MySQLRes = term(), result of fetch function on "error" -%% Descrip.: Extract the error Reason from MySQL Result on error -%% Returns : Reason -%% Reason = string() -%%-------------------------------------------------------------------- -get_result_reason(#mysql_result{error=Reason}) -> - Reason. - -%%-------------------------------------------------------------------- -%% Function: quote(String) -%% String = string() -%% Descrip.: Quote a string so that it can be included safely in a -%% MySQL query. -%% Returns : Quoted = string() -%%-------------------------------------------------------------------- -quote(String) when is_list(String) -> - [34 | lists:reverse([34 | quote(String, [])])]. %% 34 is $" - -quote([], Acc) -> - Acc; -quote([0 | Rest], Acc) -> - quote(Rest, [$0, $\\ | Acc]); -quote([10 | Rest], Acc) -> - quote(Rest, [$n, $\\ | Acc]); -quote([13 | Rest], Acc) -> - quote(Rest, [$r, $\\ | Acc]); -quote([$\\ | Rest], Acc) -> - quote(Rest, [$\\ , $\\ | Acc]); -quote([39 | Rest], Acc) -> %% 39 is $' - quote(Rest, [39, $\\ | Acc]); %% 39 is $' -quote([34 | Rest], Acc) -> %% 34 is $" - quote(Rest, [34, $\\ | Acc]); %% 34 is $" -quote([26 | Rest], Acc) -> - quote(Rest, [$Z, $\\ | Acc]); -quote([C | Rest], Acc) -> - quote(Rest, [C | Acc]). - -%%-------------------------------------------------------------------- -%% Function: asciz_binary(Data, Acc) -%% Data = binary() -%% Acc = list(), input accumulator -%% Descrip.: Find the first zero-byte in Data and add everything -%% before it to Acc, as a string. -%% Returns : {NewList, Rest} -%% NewList = list(), Acc plus what we extracted from Data -%% Rest = binary(), whatever was left of Data, not -%% including the zero-byte -%%-------------------------------------------------------------------- -asciz_binary(<<>>, Acc) -> - {lists:reverse(Acc), <<>>}; -asciz_binary(<<0:8, Rest/binary>>, Acc) -> - {lists:reverse(Acc), Rest}; -asciz_binary(<<C:8, Rest/binary>>, Acc) -> - asciz_binary(Rest, [C | Acc]). - -%%-------------------------------------------------------------------- -%% Function: connect(Id, Host, Port, User, Password, Database, -%% Reconnect) -%% Id = term(), connection-group Id -%% Host = string() -%% Port = undefined | integer() -%% User = string() -%% Password = string() -%% Database = string() -%% Reconnect = true | false -%% Descrip.: Starts a MySQL connection and, if successfull, registers -%% it with the mysql_dispatcher. -%% Returns : {ok, ConnPid} | {error, Reason} -%%-------------------------------------------------------------------- -connect(Id, Host, undefined, User, Password, Database, Reconnect) -> - connect(Id, Host, ?PORT, User, Password, Database, Reconnect); -connect(Id, Host, Port, User, Password, Database, Reconnect) -> - {ok, LogFun} = gen_server:call(?SERVER, get_logfun), - case mysql_conn:start(Host, Port, User, Password, Database, LogFun) of - {ok, ConnPid} -> - MysqlConn = - case Reconnect of - true -> - #mysql_connection{id = Id, - conn_pid = ConnPid, - reconnect = true, - host = Host, - port = Port, - user = User, - password = Password, - database = Database - }; - false -> - #mysql_connection{id = Id, - conn_pid = ConnPid, - reconnect = false - } - end, - case gen_server:call(?SERVER, {add_mysql_connection, MysqlConn}) of - ok -> - {ok, ConnPid}; - Res -> - Res - end; - {error, Reason} -> - {error, Reason} - end. - -%%-------------------------------------------------------------------- -%% Function: log(LogFun, Level, Format) -%% log(LogFun, Level, Format, Arguments) -%% LogFun = undefined | function() with arity 3 -%% Level = debug | normal | error -%% Format = string() -%% Arguments = list() of term() -%% Descrip.: Either call the function LogFun with the Level, Format -%% and Arguments as parameters or log it to the console if -%% LogFun is undefined. -%% Returns : void() -%% -%% Note : Exported only for use by the mysql_* modules. -%% -%%-------------------------------------------------------------------- -log(LogFun, Level, Format) -> - log(LogFun, Level, Format, []). - -log(LogFun, Level, Format, Arguments) when is_function(LogFun) -> - LogFun(Level, Format, Arguments); -log(undefined, _Level, Format, Arguments) -> - %% default is to log to console - io:format(Format, Arguments), - io:format("~n", []). - - -%%==================================================================== -%% gen_server callbacks -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Args = [Id, Host, Port, User, Password, Database, LogFun] -%% Id = term(), connection-group Id -%% Host = string() -%% Port = integer() -%% User = string() -%% Password = string() -%% Database = string() -%% LogFun = undefined | function() with arity 3 -%% Descrip.: Initiates the gen_server (MySQL dispatcher). -%%-------------------------------------------------------------------- -init([Id, Host, Port, User, Password, Database, LogFun]) -> - case mysql_conn:start(Host, Port, User, Password, Database, LogFun) of - {ok, ConnPid} -> - MysqlConn = #mysql_connection{id = Id, - conn_pid = ConnPid, - reconnect = true, - host = Host, - port = Port, - user = User, - password = Password, - database = Database - }, - case add_mysql_conn(MysqlConn, []) of - {ok, ConnList} -> - {ok, #state{log_fun = LogFun, - conn_list = ConnList, - gc_tref = undefined - }}; - error -> - Msg = "mysql: Failed adding first MySQL connection handler to my list, exiting", - log(LogFun, error, Msg), - {error, Msg} - end; - {error, Reason} -> - log(LogFun, error, "mysql: Failed starting first MySQL connection handler, exiting"), - {stop, {error, Reason}} - end. - -%%-------------------------------------------------------------------- -%% Function: handle_call(Msg, From, State) -%% Descrip.: Handling call messages. -%% Returns : {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | (terminate/2 is called) -%% {stop, Reason, State} (terminate/2 is called) -%%-------------------------------------------------------------------- - - -%%-------------------------------------------------------------------- -%% Function: handle_call({fetch, Id, Query}, From, State) -%% Id = term(), connection-group id -%% Query = string(), MySQL query -%% Descrip.: Make a MySQL query. Use the first connection matching Id -%% in our connection-list. Don't block the mysql_dispatcher -%% by returning {noreply, ...} here and let the mysql_conn -%% do gen_server:reply(...) when it has an answer. -%% Returns : {noreply, NewState} | -%% {reply, {error, Reason}, State} -%% NewState = state record() -%% Reason = atom() | string() -%%-------------------------------------------------------------------- -handle_call({fetch, Id, Query}, From, State) -> - log(State#state.log_fun, debug, "mysql: fetch ~p (id ~p)", [Query, Id]), - case get_next_mysql_connection_for_id(Id, State#state.conn_list) of - {ok, MysqlConn, RestOfConnList} when is_record(MysqlConn, mysql_connection) -> - mysql_conn:fetch(MysqlConn#mysql_connection.conn_pid, Query, From), - %% move this mysql socket to the back of the list - NewConnList = RestOfConnList ++ [MysqlConn], - %% The ConnPid process does a gen_server:reply() when it has an answer - {noreply, State#state{conn_list = NewConnList}}; - nomatch -> - %% we have no active connection matching Id - {reply, {error, no_connection}, State} - end; - -%%-------------------------------------------------------------------- -%% Function: handle_call({add_mysql_connection, Conn}, From, State) -%% Conn = mysql_connection record() -%% Descrip.: Add Conn to our list of connections. -%% Returns : {reply, Reply, NewState} -%% Reply = ok | {error, Reason} -%% NewState = state record() -%% Reason = string() -%%-------------------------------------------------------------------- -handle_call({add_mysql_connection, Conn}, _From, State) when is_record(Conn, mysql_connection) -> - case add_mysql_conn(Conn, State#state.conn_list) of - {ok, NewConnList} -> - {Id, ConnPid} = {Conn#mysql_connection.id, Conn#mysql_connection.conn_pid}, - log(State#state.log_fun, normal, "mysql: Added connection with id '~p' (pid ~p) to my list", - [Id, ConnPid]), - {reply, ok, State#state{conn_list = NewConnList}}; - error -> - {reply, {error, "failed adding MySQL connection to my list"}, State} - end; - -%%-------------------------------------------------------------------- -%% Function: handle_call(get_logfun, From, State) -%% Descrip.: Fetch our logfun. -%% Returns : {reply, {ok, LogFun}, State} -%% LogFun = undefined | function() with arity 3 -%%-------------------------------------------------------------------- -handle_call(get_logfun, _From, State) -> - {reply, {ok, State#state.log_fun}, State}; - -handle_call(stop, _From, State) -> - {stop, normal, State}; - -handle_call({gc_each, Millisec}, _From, State) -> - case State#state.gc_tref of - undefined -> ok; - TRef -> - timer:cancel(TRef) - end, - case timer:send_interval(Millisec, gc) of - {ok, NewTRef} -> - {reply, ok, State#state{gc_tref = NewTRef}}; - {error, Reason} -> - {reply, {error, Reason}, State} - end; - -handle_call(Unknown, _From, State) -> - log(State#state.log_fun, error, "mysql: Received unknown gen_server call : ~p", [Unknown]), - {reply, {error, "unknown gen_server call in mysql client"}, State}. - - -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -%% Descrip.: Handling cast messages -%% Returns : {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} (terminate/2 is called) -%%-------------------------------------------------------------------- -handle_cast(Unknown, State) -> - log(State#state.log_fun, error, "mysql: Received unknown gen_server cast : ~p", [Unknown]), - {noreply, State}. - - -%%-------------------------------------------------------------------- -%% Function: handle_info(Msg, State) -%% Descrip.: Handling all non call/cast messages -%% Returns : {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} (terminate/2 is called) -%%-------------------------------------------------------------------- - -%%-------------------------------------------------------------------- -%% Function: handle_info({'DOWN', ...}, State) -%% Descrip.: Handle a message that one of our monitored processes -%% (mysql_conn processes in our connection list) has exited. -%% Remove the entry from our list. -%% Returns : {noreply, NewState} | -%% {stop, normal, State} -%% NewState = state record() -%% -%% Note : For now, we stop if our connection list becomes empty. -%% We should try to reconnect for a while first, to not -%% eventually stop the whole OTP application if the MySQL- -%% server is shut down and the mysql_dispatcher was super- -%% vised by an OTP supervisor. -%%-------------------------------------------------------------------- -handle_info({'DOWN', _MonitorRef, process, Pid, Info}, State) -> - LogFun = State#state.log_fun, - case remove_mysql_connection_using_pid(Pid, State#state.conn_list, []) of - {ok, Conn, NewConnList} -> - LogLevel = case Info of - normal -> normal; - _ -> error - end, - log(LogFun, LogLevel, "mysql: MySQL connection pid ~p exited : ~p", [Pid, Info]), - log(LogFun, normal, "mysql: Removed MySQL connection with pid ~p from list", - [Pid]), - case Conn#mysql_connection.reconnect of - true -> - start_reconnect(Conn, LogFun); - false -> - ok - end, - {noreply, State#state{conn_list = NewConnList}}; - nomatch -> - log(LogFun, error, "mysql: Received 'DOWN' signal from pid ~p not in my list", [Pid]), - {noreply, State} - end; - -handle_info(gc, #state{conn_list = Connections} = State) -> - [erlang:garbage_collect(C#mysql_connection.conn_pid) || C <- Connections], - erlang:garbage_collect(self()), - {noreply, State}; - - -handle_info(Info, State) -> - log(State#state.log_fun, error, "mysql: Received unknown signal : ~p", [Info]), - {noreply, State}. - -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -%% Descrip.: Shutdown the server -%% Returns : Reason -%%-------------------------------------------------------------------- -terminate(Reason, State) -> - LogFun = State#state.log_fun, - LogLevel = case Reason of - normal -> debug; - _ -> error - end, - log(LogFun, LogLevel, "mysql: Terminating with reason : ~p", [Reason]), - lists:foreach(fun(MysqlConn) -> - MysqlConn#mysql_connection.conn_pid ! close - end, State#state.conn_list), - Reason. - -%%-------------------------------------------------------------------- -%% Function: code_change(_OldVsn, State, _Extra) -%% Descrip.: Convert process state when code is changed -%% Returns : {ok, State} -%%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%==================================================================== -%% Internal functions -%%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: add_mysql_conn(Conn, ConnList) -%% Conn = mysql_connection record() -%% ConnList = list() of mysql_connection record() -%% Descrip.: Set up process monitoring of the mysql_conn process and -%% then add it (first) to ConnList. -%% Returns : NewConnList = list() of mysql_connection record() -%%-------------------------------------------------------------------- -add_mysql_conn(Conn, ConnList) when is_record(Conn, mysql_connection), is_list(ConnList) -> - erlang:monitor(process, Conn#mysql_connection.conn_pid), - {ok, [Conn | ConnList]}. - -%%-------------------------------------------------------------------- -%% Function: remove_mysql_connection_using_pid(Pid, ConnList) -%% Pid = pid() -%% ConnList = list() of mysql_connection record() -%% Descrip.: Removes the first mysql_connection in ConnList that has -%% a pid matching Pid. -%% Returns : {ok, Conn, NewConnList} | nomatch -%% Conn = mysql_connection record() -%% NewConnList = list() of mysql_connection record() -%%-------------------------------------------------------------------- -remove_mysql_connection_using_pid(Pid, [#mysql_connection{conn_pid = Pid} = H | T], Res) -> - {ok, H, lists:reverse(Res) ++ T}; -remove_mysql_connection_using_pid(Pid, [H | T], Res) when is_record(H, mysql_connection) -> - remove_mysql_connection_using_pid(Pid, T, [H | Res]); -remove_mysql_connection_using_pid(_Pid, [], _Res) -> - nomatch. - -%%-------------------------------------------------------------------- -%% Function: get_next_mysql_connection_for_id(Id, ConnList) -%% Id = term(), connection-group id -%% ConnList = list() of mysql_connection record() -%% Descrip.: Find the first mysql_connection in ConnList that has an -%% id matching Id. -%% Returns : {ok, Conn, NewConnList} | nomatch -%% Conn = mysql_connection record() -%% NewConnList = list() of mysql_connection record(), same -%% as ConnList but without Conn -%%-------------------------------------------------------------------- -get_next_mysql_connection_for_id(Id, ConnList) -> - get_next_mysql_connection_for_id(Id, ConnList, []). - -get_next_mysql_connection_for_id(Id, [#mysql_connection{id = Id} = H | T], Res) -> - {ok, H, lists:reverse(Res) ++ T}; -get_next_mysql_connection_for_id(Id, [H | T], Res) when is_record(H, mysql_connection) -> - get_next_mysql_connection_for_id(Id, T, [H | Res]); -get_next_mysql_connection_for_id(_Id, [], _Res) -> - nomatch. - -%%-------------------------------------------------------------------- -%% Function: start_reconnect(Conn, LogFun) -%% Conn = mysql_connection record() -%% LogFun = undefined | function() with arity 3 -%% Descrip.: Spawns a process that will try to re-establish a new -%% connection instead of the one in Conn which has just -%% died. -%% Returns : ok -%%-------------------------------------------------------------------- -start_reconnect(Conn, LogFun) when is_record(Conn, mysql_connection) -> - Pid = spawn(fun () -> - reconnect_loop(Conn#mysql_connection{conn_pid = undefined}, LogFun, 0) - end), - {Id, Host, Port} = {Conn#mysql_connection.id, Conn#mysql_connection.host, Conn#mysql_connection.port}, - log(LogFun, debug, "mysql: Started pid ~p to try and reconnect to ~p:~s:~p (replacing " - "connection with pid ~p)", [Pid, Id, Host, Port, Conn#mysql_connection.conn_pid]), - ok. - -%%-------------------------------------------------------------------- -%% Function: reconnect_loop(Conn, LogFun, 0) -%% Conn = mysql_connection record() -%% LogFun = undefined | function() with arity 3 -%% Descrip.: Loop indefinately until we are able to reconnect to the -%% server specified in the now dead connection Conn. -%% Returns : ok -%%-------------------------------------------------------------------- -reconnect_loop(Conn, LogFun, N) when is_record(Conn, mysql_connection) -> - {Id, Host, Port} = {Conn#mysql_connection.id, Conn#mysql_connection.host, Conn#mysql_connection.port}, - case connect(Id, - Host, - Port, - Conn#mysql_connection.user, - Conn#mysql_connection.password, - Conn#mysql_connection.database, - Conn#mysql_connection.reconnect) of - {ok, ConnPid} -> - log(LogFun, debug, "mysql_reconnect: Managed to reconnect to ~p:~s:~p (connection pid ~p)", - [Id, Host, Port, ConnPid]), - ok; - {error, Reason} -> - %% log every once in a while - NewN = case N of - 10 -> - log(LogFun, debug, "mysql_reconnect: Still unable to connect to ~p:~s:~p (~p)", - [Id, Host, Port, Reason]), - 0; - _ -> - N + 1 - end, - %% sleep between every unsuccessfull attempt - timer:sleep(20 * 1000), - reconnect_loop(Conn, LogFun, NewN) - end. |