]> granicus.if.org Git - ejabberd/commitdiff
Clean mod_caps.erl from DB specific code
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 13 Apr 2016 08:41:04 +0000 (11:41 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 13 Apr 2016 08:41:04 +0000 (11:41 +0300)
include/mod_caps.hrl [new file with mode: 0644]
src/mod_caps.erl
src/mod_caps_mnesia.erl [new file with mode: 0644]
src/mod_caps_riak.erl [new file with mode: 0644]
src/mod_caps_sql.erl [new file with mode: 0644]

diff --git a/include/mod_caps.hrl b/include/mod_caps.hrl
new file mode 100644 (file)
index 0000000..067df94
--- /dev/null
@@ -0,0 +1,4 @@
+-record(caps_features,
+       {node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
+        features  = []               :: [binary()] | pos_integer()
+       }).
index 0646d3812412ff06070196c8a19912375855424e..bd0f14f5eb4f7818f6fc485f93b113518e714232 100644 (file)
 
 -record(state, {host = <<"">> :: binary()}).
 
+-callback init(binary(), gen_mod:opts()) -> any().
+-callback caps_read(binary(), {binary(), binary()}) ->
+    {ok, non_neg_integer() | [binary()]} | error.
+-callback caps_write(binary(), {binary(), binary()},
+                    non_neg_integer() | [binary()]) -> any().
+
 start_link(Host, Opts) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
     gen_server:start_link({local, Proc}, ?MODULE,
@@ -300,28 +306,9 @@ c2s_broadcast_recipients(InAcc, Host, C2SState,
     end;
 c2s_broadcast_recipients(Acc, _, _, _, _, _) -> Acc.
 
-init_db(mnesia, _Host) ->
-    case catch mnesia:table_info(caps_features, storage_type) of
-        {'EXIT', _} ->
-            ok;
-        disc_only_copies ->
-            ok;
-        _ ->
-            mnesia:delete_table(caps_features)
-    end,
-    mnesia:create_table(caps_features,
-                        [{disc_only_copies, [node()]},
-                         {local_content, true},
-                         {attributes,
-                          record_info(fields, caps_features)}]),
-    update_table(),
-    mnesia:add_table_copy(caps_features, node(),
-                          disc_only_copies);
-init_db(_, _) ->
-    ok.
-
 init([Host, Opts]) ->
-    init_db(gen_mod:db_type(Host, Opts), Host),
+    Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
+    Mod:init(Host, Opts),
     MaxSize = gen_mod:get_opt(cache_size, Opts,
                               fun(I) when is_integer(I), I>0 -> I end,
                               1000),
@@ -450,65 +437,13 @@ feature_response(_IQResult, Host, From, Caps,
 
 caps_read_fun(Host, Node) ->
     LServer = jid:nameprep(Host),
-    DBType = gen_mod:db_type(LServer, ?MODULE),
-    caps_read_fun(LServer, Node, DBType).
-
-caps_read_fun(_LServer, Node, mnesia) ->
-    fun () ->
-           case mnesia:dirty_read({caps_features, Node}) of
-             [#caps_features{features = Features}] -> {ok, Features};
-             _ -> error
-           end
-    end;
-caps_read_fun(_LServer, Node, riak) ->
-    fun() ->
-            case ejabberd_riak:get(caps_features, caps_features_schema(), Node) of
-                {ok, #caps_features{features = Features}} -> {ok, Features};
-                _ -> error
-            end
-    end;
-caps_read_fun(LServer, {Node, SubNode}, odbc) ->
-    fun() ->
-            SNode = ejabberd_odbc:escape(Node),
-            SSubNode = ejabberd_odbc:escape(SubNode),
-            case ejabberd_odbc:sql_query(
-                   LServer, [<<"select feature from caps_features where ">>,
-                             <<"node='">>, SNode, <<"' and subnode='">>,
-                             SSubNode, <<"';">>]) of
-                {selected, [<<"feature">>], [[H]|_] = Fs} ->
-                    case catch jlib:binary_to_integer(H) of
-                        Int when is_integer(Int), Int>=0 ->
-                            {ok, Int};
-                        _ ->
-                            {ok, lists:flatten(Fs)}
-                    end;
-                _ ->
-                    error
-            end
-    end.
+    Mod = gen_mod:db_mod(LServer, ?MODULE),
+    fun() -> Mod:caps_read(LServer, Node) end.
 
 caps_write_fun(Host, Node, Features) ->
     LServer = jid:nameprep(Host),
-    DBType = gen_mod:db_type(LServer, ?MODULE),
-    caps_write_fun(LServer, Node, Features, DBType).
-
-caps_write_fun(_LServer, Node, Features, mnesia) ->
-    fun () ->
-           mnesia:dirty_write(#caps_features{node_pair = Node,
-                                             features = Features})
-    end;
-caps_write_fun(_LServer, Node, Features, riak) ->
-    fun () ->
-            ejabberd_riak:put(#caps_features{node_pair = Node,
-                                             features = Features},
-                             caps_features_schema())
-    end;
-caps_write_fun(LServer, NodePair, Features, odbc) ->
-    fun () ->
-            ejabberd_odbc:sql_transaction(
-              LServer,
-              sql_write_features_t(NodePair, Features))
-    end.
+    Mod = gen_mod:db_mod(LServer, ?MODULE),
+    fun() -> Mod:caps_write(LServer, Node, Features) end.
 
 make_my_disco_hash(Host) ->
     JID = jid:make(<<"">>, Host, <<"">>),
@@ -658,61 +593,20 @@ is_valid_node(Node) ->
             false
     end.
 
-update_table() ->
-    Fields = record_info(fields, caps_features),
-    case mnesia:table_info(caps_features, attributes) of
-        Fields ->
-            ejabberd_config:convert_table_to_binary(
-              caps_features, Fields, set,
-              fun(#caps_features{node_pair = {N, _}}) -> N end,
-              fun(#caps_features{node_pair = {N, P},
-                                 features = Fs} = R) ->
-                      NewFs = if is_integer(Fs) ->
-                                      Fs;
-                                 true ->
-                                      [iolist_to_binary(F) || F <- Fs]
-                              end,
-                      R#caps_features{node_pair = {iolist_to_binary(N),
-                                                   iolist_to_binary(P)},
-                                      features = NewFs}
-              end);
-        _ ->
-            ?INFO_MSG("Recreating caps_features table", []),
-            mnesia:transform_table(caps_features, ignore, Fields)
-    end.
-
-sql_write_features_t({Node, SubNode}, Features) ->
-    SNode = ejabberd_odbc:escape(Node),
-    SSubNode = ejabberd_odbc:escape(SubNode),
-    NewFeatures = if is_integer(Features) ->
-                          [jlib:integer_to_binary(Features)];
-                     true ->
-                          Features
-                  end,
-    [[<<"delete from caps_features where node='">>,
-      SNode, <<"' and subnode='">>, SSubNode, <<"';">>]|
-     [[<<"insert into caps_features(node, subnode, feature) ">>,
-       <<"values ('">>, SNode, <<"', '">>, SSubNode, <<"', '">>,
-       ejabberd_odbc:escape(F), <<"');">>] || F <- NewFeatures]].
-
 caps_features_schema() ->
     {record_info(fields, caps_features), #caps_features{}}.
 
-export(_Server) ->
-    [{caps_features,
-      fun(_Host, #caps_features{node_pair = NodePair,
-                                features = Features}) ->
-              sql_write_features_t(NodePair, Features);
-         (_Host, _R) ->
-              []
-      end}].
+export(LServer) ->
+    Mod = gen_mod:db_mod(LServer, ?MODULE),
+    Mod:export(LServer).
 
 import_info() ->
     [{<<"caps_features">>, 4}].
 
 import_start(LServer, DBType) ->
     ets:new(caps_features_tmp, [private, named_table, bag]),
-    init_db(DBType, LServer),
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []),
     ok.
 
 import(_LServer, {odbc, _}, _DBType, <<"caps_features">>,
diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl
new file mode 100644 (file)
index 0000000..0bf04b2
--- /dev/null
@@ -0,0 +1,73 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2016, Evgeny Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+-module(mod_caps_mnesia).
+-behaviour(mod_caps).
+
+%% API
+-export([init/2, caps_read/2, caps_write/3]).
+
+-include("mod_caps.hrl").
+-include("logger.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init(_Host, _Opts) ->
+    case catch mnesia:table_info(caps_features, storage_type) of
+        {'EXIT', _} ->
+            ok;
+        disc_only_copies ->
+            ok;
+        _ ->
+            mnesia:delete_table(caps_features)
+    end,
+    mnesia:create_table(caps_features,
+                        [{disc_only_copies, [node()]},
+                         {local_content, true},
+                         {attributes,
+                          record_info(fields, caps_features)}]),
+    update_table(),
+    mnesia:add_table_copy(caps_features, node(),
+                          disc_only_copies).
+
+caps_read(_LServer, Node) ->
+    case mnesia:dirty_read({caps_features, Node}) of
+       [#caps_features{features = Features}] -> {ok, Features};
+       _ -> error
+    end.
+
+caps_write(_LServer, Node, Features) ->
+    mnesia:dirty_write(#caps_features{node_pair = Node,
+                                     features = Features}).
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+update_table() ->
+    Fields = record_info(fields, caps_features),
+    case mnesia:table_info(caps_features, attributes) of
+        Fields ->
+            ejabberd_config:convert_table_to_binary(
+              caps_features, Fields, set,
+              fun(#caps_features{node_pair = {N, _}}) -> N end,
+              fun(#caps_features{node_pair = {N, P},
+                                 features = Fs} = R) ->
+                      NewFs = if is_integer(Fs) ->
+                                      Fs;
+                                 true ->
+                                      [iolist_to_binary(F) || F <- Fs]
+                              end,
+                      R#caps_features{node_pair = {iolist_to_binary(N),
+                                                   iolist_to_binary(P)},
+                                      features = NewFs}
+              end);
+        _ ->
+            ?INFO_MSG("Recreating caps_features table", []),
+            mnesia:transform_table(caps_features, ignore, Fields)
+    end.
diff --git a/src/mod_caps_riak.erl b/src/mod_caps_riak.erl
new file mode 100644 (file)
index 0000000..6e59ba8
--- /dev/null
@@ -0,0 +1,38 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2016, Evgeny Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+-module(mod_caps_riak).
+-behaviour(mod_caps).
+
+%% API
+-export([init/2, caps_read/2, caps_write/3]).
+
+-include("mod_caps.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init(_Host, _Opts) ->
+    ok.
+
+caps_read(_LServer, Node) ->
+    case ejabberd_riak:get(caps_features, caps_features_schema(), Node) of
+       {ok, #caps_features{features = Features}} -> {ok, Features};
+       _ -> error
+    end.
+
+caps_write(_LServer, Node, Features) ->
+    ejabberd_riak:put(#caps_features{node_pair = Node,
+                                    features = Features},
+                     caps_features_schema()).
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+caps_features_schema() ->
+    {record_info(fields, caps_features), #caps_features{}}.
diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl
new file mode 100644 (file)
index 0000000..353b95b
--- /dev/null
@@ -0,0 +1,71 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2016, Evgeny Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+-module(mod_caps_sql).
+-behaviour(mod_caps).
+
+%% API
+-export([init/2, caps_read/2, caps_write/3, export/1]).
+
+-include("mod_caps.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init(_Host, _Opts) ->
+    ok.
+
+caps_read(LServer, {Node, SubNode}) ->
+    SNode = ejabberd_odbc:escape(Node),
+    SSubNode = ejabberd_odbc:escape(SubNode),
+    case ejabberd_odbc:sql_query(
+          LServer, [<<"select feature from caps_features where ">>,
+                    <<"node='">>, SNode, <<"' and subnode='">>,
+                    SSubNode, <<"';">>]) of
+       {selected, [<<"feature">>], [[H]|_] = Fs} ->
+           case catch jlib:binary_to_integer(H) of
+               Int when is_integer(Int), Int>=0 ->
+                   {ok, Int};
+               _ ->
+                   {ok, lists:flatten(Fs)}
+           end;
+       _ ->
+           error
+    end.
+
+caps_write(LServer, NodePair, Features) ->
+    ejabberd_odbc:sql_transaction(
+      LServer,
+      sql_write_features_t(NodePair, Features)).
+
+export(_Server) ->
+    [{caps_features,
+      fun(_Host, #caps_features{node_pair = NodePair,
+                                features = Features}) ->
+              sql_write_features_t(NodePair, Features);
+         (_Host, _R) ->
+              []
+      end}].
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+sql_write_features_t({Node, SubNode}, Features) ->
+    SNode = ejabberd_odbc:escape(Node),
+    SSubNode = ejabberd_odbc:escape(SubNode),
+    NewFeatures = if is_integer(Features) ->
+                          [jlib:integer_to_binary(Features)];
+                     true ->
+                          Features
+                  end,
+    [[<<"delete from caps_features where node='">>,
+      SNode, <<"' and subnode='">>, SSubNode, <<"';">>]|
+     [[<<"insert into caps_features(node, subnode, feature) ">>,
+       <<"values ('">>, SNode, <<"', '">>, SSubNode, <<"', '">>,
+       ejabberd_odbc:escape(F), <<"');">>] || F <- NewFeatures]].
+