]> granicus.if.org Git - ejabberd/commitdiff
Add SQL as mod_proxy65 RAM backend
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 31 Mar 2017 05:16:28 +0000 (08:16 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 31 Mar 2017 05:16:28 +0000 (08:16 +0300)
sql/lite.sql
sql/mysql.sql
sql/pg.sql
src/mod_proxy65_sql.erl [new file with mode: 0644]

index ddfb91ff0b256d2fc093cd6568051a269960c5ed..1d057407f50b82d9a2aa2a838a8d8dca27e1009f 100644 (file)
@@ -369,3 +369,15 @@ CREATE TABLE carboncopy (
 
 CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy (username, resource);
 CREATE INDEX i_carboncopy_user ON carboncopy (username);
+
+CREATE TABLE proxy65 (
+    sid text NOT NULL,
+    pid_t text NOT NULL,
+    pid_i text NOT NULL,
+    node_t text NOT NULL,
+    node_i text NOT NULL,
+    jid_i text NOT NULL
+);
+
+CREATE UNIQUE INDEX i_proxy65_sid ON proxy65 (sid);
+CREATE INDEX i_proxy65_jid ON proxy65 (jid_i);
index e09c39be55e124b0cc9f278413e6f380c48b99d3..c591cb761f149cc052c211d962ea638fe2038787 100644 (file)
@@ -385,3 +385,15 @@ CREATE TABLE carboncopy (
 
 CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy (username(75), resource(75));
 CREATE INDEX i_carboncopy_user ON carboncopy (username(75));
+
+CREATE TABLE proxy65 (
+    sid text NOT NULL,
+    pid_t text NOT NULL,
+    pid_i text NOT NULL,
+    node_t text NOT NULL,
+    node_i text NOT NULL,
+    jid_i text NOT NULL
+) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+CREATE UNIQUE INDEX i_proxy65_sid ON proxy65 (sid(191));
+CREATE INDEX i_proxy65_jid ON proxy65 (jid_i(191));
index 796391c74db2baa1df41226f8b3d3061d96b938b..539c1263a9b393b3cf7bda2fd4e15f1d88f42701 100644 (file)
@@ -389,3 +389,15 @@ CREATE TABLE carboncopy (
 
 CREATE UNIQUE INDEX i_carboncopy_ur ON carboncopy USING btree (username, resource);
 CREATE INDEX i_carboncopy_user ON carboncopy USING btree (username);
+
+CREATE TABLE proxy65 (
+    sid text NOT NULL,
+    pid_t text NOT NULL,
+    pid_i text NOT NULL,
+    node_t text NOT NULL,
+    node_i text NOT NULL,
+    jid_i text NOT NULL
+);
+
+CREATE UNIQUE INDEX i_proxy65_sid ON proxy65 USING btree (sid);
+CREATE INDEX i_proxy65_jid ON proxy65 USING btree (jid_i);
diff --git a/src/mod_proxy65_sql.erl b/src/mod_proxy65_sql.erl
new file mode 100644 (file)
index 0000000..5007bd0
--- /dev/null
@@ -0,0 +1,142 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%% Created : 30 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%%
+%%%
+%%% ejabberd, Copyright (C) 2002-2017   ProcessOne
+%%%
+%%% This program is free software; you can redistribute it and/or
+%%% modify it under the terms of the GNU General Public License as
+%%% published by the Free Software Foundation; either version 2 of the
+%%% License, or (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%%% General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License along
+%%% with this program; if not, write to the Free Software Foundation, Inc.,
+%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+%%%
+%%%-------------------------------------------------------------------
+-module(mod_proxy65_sql).
+-behaviour(mod_proxy65).
+
+-compile([{parse_transform, ejabberd_sql_pt}]).
+
+%% API
+-export([init/0, register_stream/2, unregister_stream/1, activate_stream/4]).
+
+-include("ejabberd.hrl").
+-include("logger.hrl").
+-include("ejabberd_sql_pt.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init() ->
+    NodeS = erlang:atom_to_binary(node(), latin1),
+    ?INFO_MSG("Cleaning SQL 'proxy65' table...", []),
+    case ejabberd_sql:sql_query(
+          ?MYNAME,
+          ?SQL("delete from proxy65 where "
+               "node_i=%(NodeS)s or node_t=%(NodeS)s")) of
+       {updated, _} ->
+           ok;
+       Err ->
+           ?ERROR_MSG("failed to clean 'proxy65' table: ~p", [Err]),
+           Err
+    end.
+
+register_stream(SID, Pid) ->
+    PidS = aux:encode_pid(Pid),
+    NodeS = erlang:atom_to_binary(node(Pid), latin1),
+    F = fun() ->
+               case ejabberd_sql:sql_query_t(
+                      ?SQL("update proxy65 set pid_i=%(PidS)s, "
+                           "node_i=%(NodeS)s where sid=%(SID)s")) of
+                   {updated, 1} ->
+                       ok;
+                   _ ->
+                       ejabberd_sql:sql_query_t(
+                         ?SQL("insert into proxy65"
+                              "(sid, pid_t, node_t, pid_i, node_i, jid_i) "
+                              "values (%(SID)s, %(PidS)s, %(NodeS)s, '', '', '')"))
+               end
+       end,
+    case ejabberd_sql:sql_transaction(?MYNAME, F) of
+       {atomic, _} ->
+           ok;
+       {aborted, Reason} ->
+           ?ERROR_MSG("failed to register stream: ~p", [Reason]),
+           {error, Reason}
+    end.
+
+unregister_stream(SID) ->
+    F = fun() ->
+               ejabberd_sql:sql_query_t(
+                 ?SQL("delete from proxy65 where sid=%(SID)s"))
+       end,
+    case ejabberd_sql:sql_transaction(?MYNAME, F) of
+       {atomic, _} ->
+           ok;
+       {aborted, Reason} ->
+           ?ERROR_MSG("failed to unregister stream: ~p", [Reason]),
+           {error, Reason}
+    end.
+
+activate_stream(SID, IJID, MaxConnections, _Node) ->
+    F = fun() ->
+               case ejabberd_sql:sql_query_t(
+                      ?SQL("select @(pid_t)s, @(node_t)s, @(pid_i)s, "
+                           "@(node_i)s, @(jid_i)s from proxy65 where "
+                           "sid=%(SID)s")) of
+                   {selected, [{TPidS, TNodeS, IPidS, INodeS, <<"">>}]}
+                     when IPidS /= <<"">> ->
+                       try {aux:decode_pid(TPidS, TNodeS),
+                            aux:decode_pid(IPidS, INodeS)} of
+                           {TPid, IPid} ->
+                               case ejabberd_sql:sql_query_t(
+                                      ?SQL("update proxy65 set jid_i=%(IJID)s "
+                                           "where sid=%(SID)s")) of
+                                   {updated, 1} when is_integer(MaxConnections) ->
+                                       case ejabberd_sql:sql_query_t(
+                                              ?SQL("select @(count(*))d from proxy65 "
+                                                   "where jid_i=%(IJID)s")) of
+                                           {selected, [{Num}]} when Num > MaxConnections ->
+                                               exit({limit, IPid, TPid});
+                                           {selected, _} ->
+                                               {ok, IPid, TPid};
+                                           Err ->
+                                               exit(Err)
+                                       end;
+                                   {updated, _} ->
+                                       {ok, IPid, TPid};
+                                   Err ->
+                                       exit(Err)
+                               end
+                       catch _:{bad_node, _} ->
+                               {error, notfound}
+                       end;
+                   {selected, [{_, _, _, _, JID}]} when JID /= <<"">> ->
+                       {error, conflict};
+                   {selected, _} ->
+                       {error, notfound};
+                   Err ->
+                       exit(Err)
+               end
+       end,
+    case ejabberd_sql:sql_transaction(?MYNAME, F) of
+       {atomic, Result} ->
+           Result;
+       {aborted, {limit, _, _} = Limit} ->
+           {error, Limit};
+       {aborted, Reason} ->
+           ?ERROR_MSG("failed to activate bytestream: ~p", [Reason]),
+           {error, Reason}
+    end.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================