sql_query_t/1,
sql_transaction/2,
escape/1,
- escape_like/1]).
+ escape_like/1,
+ keep_alive/1]).
%% gen_server callbacks
-export([init/1,
-define(PGSQL_PORT, 5432).
-define(MYSQL_PORT, 3306).
+-define(KEEPALIVE_QUERY, "SELECT 1;").
+
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
{sql_query, Query}, 60000).
%% SQL transaction based on a list of queries
-%% This function automatically
+%% This function automatically
sql_transaction(Host, Queries) when is_list(Queries) ->
F = fun() ->
lists:foreach(fun(Query) ->
%% {stop, Reason}
%%----------------------------------------------------------------------
init([Host]) ->
+ case ejabberd_config:get_local_option({odbc_keepalive_interval, Host}) of
+ Interval when is_integer(Interval) ->
+ timer:apply_interval(Interval*1000, ?MODULE, keep_alive, [self()]);
+ undefined ->
+ ok;
+ _Other ->
+ ?ERROR_MSG("Wrong odbc_keepalive_interval definition '~p' for host ~p.~n", [_Other, Host])
+ end,
SQLServer = ejabberd_config:get_local_option({odbc_server, Host}),
case SQLServer of
%% Default pgsql port
odbc_connect(SQLServer)
end.
-
%%----------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State} |
%% Open an ODBC database connection
odbc_connect(SQLServer) ->
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
- {ok, Ref} ->
+ {ok, Ref} ->
erlang:monitor(process, Ref),
{ok, #state{db_ref = Ref, db_type = odbc}};
{error, Reason} ->
%% Open a database connection to PostgreSQL
pgsql_connect(Server, Port, DB, Username, Password) ->
case pgsql:connect(Server, DB, Username, Password, Port) of
- {ok, Ref} ->
+ {ok, Ref} ->
{ok, #state{db_ref = Ref, db_type = pgsql}};
{error, Reason} ->
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
{selected,
[element(2, Column) || Column <- Columns],
[list_to_tuple(Rec) || Rec <- Recs]}.
+
+% perform a harmless query on all opened connexions to avoid connexion close.
+keep_alive(PID) ->
+ gen_server:call(PID, {sql_query, ?KEEPALIVE_QUERY}, 60000).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
+%% API
-export([start_link/1,
init/1,
get_pids/1,
-include("ejabberd.hrl").
+-define(DEFAULT_POOL_SIZE, 10).
+
start_link(Host) ->
supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
?MODULE, [Host]).
init([Host]) ->
- % TODO
- N = 10,
+ N = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of
+ I when is_integer(I) ->
+ I;
+ undefined ->
+ ?DEFAULT_POOL_SIZE;
+ Other ->
+ ?ERROR_MSG("Wrong odbc_pool_size definition '~p' for host ~p, default to ~p~n",
+ [Other, Host, ?DEFAULT_POOL_SIZE]),
+ ?DEFAULT_POOL_SIZE
+ end,
{ok, {{one_for_one, 10, 6},
lists:map(
fun(I) ->
get_random_pid(Host) ->
Pids = get_pids(Host),
lists:nth(erlang:phash(now(), length(Pids)), Pids).
-