• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

processone / ejabberd / 1296

19 Jan 2026 11:25AM UTC coverage: 33.562% (+0.09%) from 33.468%
1296

push

github

badlop
mod_conversejs: Cosmetic change: sort paths alphabetically

0 of 4 new or added lines in 1 file covered. (0.0%)

11245 existing lines in 174 files now uncovered.

15580 of 46421 relevant lines covered (33.56%)

1074.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/src/ejabberd_sm_sql.erl
1
%%%-------------------------------------------------------------------
2
%%% File    : ejabberd_sm_sql.erl
3
%%% Author  : Evgeny Khramtsov <ekhramtsov@process-one.net>
4
%%% Created :  9 Mar 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
5
%%%
6
%%%
7
%%% ejabberd, Copyright (C) 2002-2026   ProcessOne
8
%%%
9
%%% This program is free software; you can redistribute it and/or
10
%%% modify it under the terms of the GNU General Public License as
11
%%% published by the Free Software Foundation; either version 2 of the
12
%%% License, or (at your option) any later version.
13
%%%
14
%%% This program is distributed in the hope that it will be useful,
15
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
16
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
%%% General Public License for more details.
18
%%%
19
%%% You should have received a copy of the GNU General Public License along
20
%%% with this program; if not, write to the Free Software Foundation, Inc.,
21
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
%%%
23
%%%----------------------------------------------------------------------
24

25
-module(ejabberd_sm_sql).
26

27

28
-behaviour(ejabberd_sm).
29

30
%% API
31
-export([init/0,
32
         set_session/1,
33
         delete_session/1,
34
         get_sessions/0,
35
         get_sessions/1,
36
         get_sessions/2]).
37
-export([sql_schemas/0]).
38

39
-include("ejabberd_sm.hrl").
40
-include("logger.hrl").
41
-include("ejabberd_sql_pt.hrl").
42

43
%%%===================================================================
44
%%% API
45
%%%===================================================================
46
-spec init() -> ok | {error, any()}.
47
init() ->
UNCOV
48
    Node = erlang:atom_to_binary(node(), latin1),
6✔
UNCOV
49
    ?DEBUG("Cleaning SQL SM table...", []),
6✔
UNCOV
50
    lists:foldl(
6✔
51
      fun(Host, ok) ->
UNCOV
52
              ejabberd_sql_schema:update_schema(Host, ?MODULE, sql_schemas()),
6✔
UNCOV
53
              case ejabberd_sql:sql_query(
6✔
UNCOV
54
                     Host, ?SQL("delete from sm where node=%(Node)s")) of
12✔
55
                  {updated, _} ->
UNCOV
56
                      ok;
6✔
57
                  Err ->
58
                      ?ERROR_MSG("Failed to clean 'sm' table: ~p", [Err]),
×
59
                      {error, db_failure}
×
60
              end;
61
         (_, Err) ->
62
              Err
×
63
      end, ok, ejabberd_sm:get_vh_by_backend(?MODULE)).
64

65
sql_schemas() ->
UNCOV
66
    [#sql_schema{
6✔
67
        version = 1,
68
        tables =
69
            [#sql_table{
70
                name = <<"sm">>,
71
                columns =
72
                    [#sql_column{name = <<"usec">>, type = bigint},
73
                     #sql_column{name = <<"pid">>, type = text},
74
                     #sql_column{name = <<"node">>, type = text},
75
                     #sql_column{name = <<"username">>, type = text},
76
                     #sql_column{name = <<"server_host">>, type = text},
77
                     #sql_column{name = <<"resource">>, type = text},
78
                     #sql_column{name = <<"priority">>, type = text},
79
                     #sql_column{name = <<"info">>, type = text}],
80
                indices = [#sql_index{
81
                              columns = [<<"usec">>, <<"pid">>],
82
                              unique = true},
83
                           #sql_index{
84
                              columns = [<<"node">>]},
85
                           #sql_index{
86
                              columns = [<<"server_host">>, <<"username">>]}]}]}].
87

88
set_session(#session{sid = {Now, Pid}, usr = {U, LServer, R},
89
                     priority = Priority, info = Info}) ->
UNCOV
90
    InfoS = misc:term_to_expr(Info),
1,548✔
UNCOV
91
    PrioS = enc_priority(Priority),
1,548✔
UNCOV
92
    TS = now_to_timestamp(Now),
1,548✔
UNCOV
93
    PidS = misc:encode_pid(Pid),
1,548✔
UNCOV
94
    Node = erlang:atom_to_binary(node(Pid), latin1),
1,548✔
UNCOV
95
    case ?SQL_UPSERT(LServer, "sm",
1,548✔
96
                     ["!usec=%(TS)d",
97
                      "!pid=%(PidS)s",
98
                      "node=%(Node)s",
99
                      "username=%(U)s",
100
                      "server_host=%(LServer)s",
101
                      "resource=%(R)s",
102
                      "priority=%(PrioS)s",
103
                      "info=%(InfoS)s"]) of
104
        ok ->
UNCOV
105
            ok;
1,548✔
106
        _Err ->
107
            {error, db_failure}
×
108
    end.
109

110
delete_session(#session{usr = {_, LServer, _}, sid = {Now, Pid}}) ->
UNCOV
111
    TS = now_to_timestamp(Now),
1,338✔
UNCOV
112
    PidS = misc:encode_pid(Pid),
1,338✔
UNCOV
113
    case ejabberd_sql:sql_query(
1,338✔
114
           LServer,
UNCOV
115
           ?SQL("delete from sm where usec=%(TS)d and pid=%(PidS)s")) of
1,788✔
116
        {updated, _} ->
UNCOV
117
            ok;
1,338✔
118
        _Err ->
119
            {error, db_failure}
×
120
    end.
121

122
get_sessions() ->
UNCOV
123
    lists:flatmap(
×
124
      fun(LServer) ->
UNCOV
125
              get_sessions(LServer)
×
126
      end, ejabberd_sm:get_vh_by_backend(?MODULE)).
127

128
get_sessions(LServer) ->
UNCOV
129
    case ejabberd_sql:sql_query(
12✔
130
           LServer,
UNCOV
131
           ?SQL("select @(usec)d, @(pid)s, @(node)s, @(username)s,"
12✔
132
                " @(resource)s, @(priority)s, @(info)s from sm"
133
                " where %(LServer)H")) of
134
        {selected, Rows} ->
UNCOV
135
            lists:flatmap(
12✔
136
              fun(Row) ->
UNCOV
137
                      try [row_to_session(LServer, Row)]
12✔
138
                      catch _:{bad_node, _} -> []
×
139
                      end
140
              end, Rows);
141
        _Err ->
142
            []
×
143
    end.
144

145
get_sessions(LUser, LServer) ->
UNCOV
146
    case ejabberd_sql:sql_query(
3,410✔
147
           LServer,
UNCOV
148
           ?SQL("select @(usec)d, @(pid)s, @(node)s, @(username)s,"
3,410✔
149
                " @(resource)s, @(priority)s, @(info)s from sm"
150
                " where username=%(LUser)s and %(LServer)H")) of
151
        {selected, Rows} ->
UNCOV
152
            {ok, lists:flatmap(
3,410✔
153
                   fun(Row) ->
UNCOV
154
                           try [row_to_session(LServer, Row)]
1,970✔
155
                           catch _:{bad_node, _} -> []
×
156
                           end
157
                   end, Rows)};
158
        _Err ->
159
            {error, db_failure}
×
160
    end.
161

162
%%%===================================================================
163
%%% Internal functions
164
%%%===================================================================
165
now_to_timestamp({MSec, Sec, USec}) ->
UNCOV
166
    (MSec * 1000000 + Sec) * 1000000 + USec.
2,886✔
167

168
timestamp_to_now(I) ->
UNCOV
169
    Head = I div 1000000,
1,982✔
UNCOV
170
    USec = I rem 1000000,
1,982✔
UNCOV
171
    MSec = Head div 1000000,
1,982✔
UNCOV
172
    Sec = Head rem 1000000,
1,982✔
UNCOV
173
    {MSec, Sec, USec}.
1,982✔
174

175
dec_priority(Prio) ->
UNCOV
176
    case catch binary_to_integer(Prio) of
1,982✔
177
        {'EXIT', _} ->
UNCOV
178
            undefined;
1,789✔
179
        Int ->
UNCOV
180
            Int
193✔
181
    end.
182

183
enc_priority(undefined) ->
UNCOV
184
    <<"">>;
1,368✔
185
enc_priority(Int) when is_integer(Int) ->
UNCOV
186
    integer_to_binary(Int).
180✔
187

188
row_to_session(LServer, {USec, PidS, NodeS, User, Resource, PrioS, InfoS}) ->
UNCOV
189
    Now = timestamp_to_now(USec),
1,982✔
UNCOV
190
    Pid = misc:decode_pid(PidS, NodeS),
1,982✔
UNCOV
191
    Priority = dec_priority(PrioS),
1,982✔
UNCOV
192
    Info = ejabberd_sql:decode_term(InfoS),
1,982✔
UNCOV
193
    #session{sid = {Now, Pid}, us = {User, LServer},
1,982✔
194
             usr = {User, LServer, Resource},
195
             priority = Priority,
196
             info = Info}.
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc