Skip to content

Commit

Permalink
Use prepared queries for mod_last
Browse files Browse the repository at this point in the history
  • Loading branch information
arcusfelis committed Feb 5, 2021
1 parent 7fd536c commit abc5a1a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 62 deletions.
82 changes: 48 additions & 34 deletions src/mod_last_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,66 @@
remove_user/2]).

-spec init(jid:server(), list()) -> ok.
init(_Host, _Opts) ->
init(Host, _Opts) ->
prepare_queries(Host),
ok.

%% Prepared query functions
prepare_queries(Host) ->
mongoose_rdbms:prepare(last_select, last, [username],
<<"SELECT seconds, state FROM last WHERE username=?">>),
mongoose_rdbms:prepare(last_count_active, last, [seconds],
<<"SELECT COUNT(*) FROM last WHERE seconds > ?">>),
mongoose_rdbms:prepare(last_delete, last, [username],
<<"delete from last where username=?">>),
rdbms_queries:prepare_upsert(Host, last_upsert, last,
[<<"username">>, <<"seconds">>, <<"state">>],
[<<"seconds">>, <<"state">>],
[<<"username">>]).

execute_get_last(LServer, LUser) ->
mongoose_rdbms:execute_successfully(LServer, last_select, [LUser]).

execute_count_active_users(LServer, Seconds) ->
mongoose_rdbms:execute_successfully(LServer, last_count_active, [Seconds]).

execute_remove_user(LServer, LUser) ->
mongoose_rdbms:execute_successfully(LServer, last_delete, [LUser]).

execute_upsert_last(Host, LUser, Seconds, State) ->
InsertParams = [LUser, Seconds, State],
UpdateParams = [Seconds, State],
UniqueKeyValues = [LUser],
rdbms_queries:execute_upsert(Host, last_upsert, InsertParams, UpdateParams, UniqueKeyValues).

%% API functions
-spec get_last(jid:luser(), jid:lserver()) ->
{ok, non_neg_integer(), binary()} | {error, term()} | not_found.
{ok, non_neg_integer(), binary()} | not_found.
get_last(LUser, LServer) ->
Username = mongoose_rdbms:escape_string(LUser),
case catch rdbms_queries:get_last(LServer, Username) of
{selected, []} ->
not_found;
{selected, [{STimeStamp, Status}]} ->
case catch mongoose_rdbms:result_to_integer(STimeStamp) of
TimeStamp when is_integer(TimeStamp) ->
{ok, TimeStamp, Status};
Reason ->
{error, {invalid_timestamp, Reason}}
end;
Reason -> {error, {invalid_result, Reason}}
end.
Result = execute_get_last(LServer, LUser),
decode_last_result(Result).

-spec count_active_users(jid:lserver(), non_neg_integer()) -> non_neg_integer().
count_active_users(LServer, TimeStamp) ->
TimeStampBin = integer_to_binary(TimeStamp),
WhereClause = <<"where seconds > ", TimeStampBin/binary >>,
case rdbms_queries:count_records_where(LServer, <<"last">>, WhereClause) of
{selected, [{Count}]} ->
mongoose_rdbms:result_to_integer(Count);
_ ->
0
end.
count_active_users(LServer, Seconds) ->
Result = execute_count_active_users(LServer, Seconds),
mongoose_rdbms:selected_to_integer(Result).

-spec set_last_info(jid:luser(), jid:lserver(),
non_neg_integer(), binary()) ->
ok | {error, term()}.
set_last_info(LUser, LServer, TimeStamp, Status) ->
Username = mongoose_rdbms:escape_string(LUser),
Seconds = mongoose_rdbms:escape_integer(TimeStamp),
State = mongoose_rdbms:escape_string(Status),
wrap_rdbms_result(rdbms_queries:set_last_t(LServer, Username, Seconds, State)).
non_neg_integer(), binary()) -> ok | {error, term()}.
set_last_info(LUser, LServer, Seconds, State) ->
wrap_rdbms_result(execute_upsert_last(LServer, LUser, Seconds, State)).

-spec remove_user(jid:luser(), jid:lserver()) -> ok | {error, term()}.
remove_user(LUser, LServer) ->
Username = mongoose_rdbms:escape_string(LUser),
wrap_rdbms_result(rdbms_queries:del_last(LServer, Username)).
wrap_rdbms_result(execute_remove_user(LServer, LUser)).

%% Helper functions
decode_last_result({selected, []}) ->
not_found;
decode_last_result({selected, [{DbSeconds, State}]}) ->
Seconds = mongoose_rdbms:result_to_integer(DbSeconds),
{ok, Seconds, State}.

-spec wrap_rdbms_result({error, term()} | any()) -> ok | {error, term()}.
wrap_rdbms_result({error, _} = Error) -> Error;
wrap_rdbms_result(_) -> ok.

28 changes: 0 additions & 28 deletions src/rdbms/rdbms_queries.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@
limit_offset_sql/0,
limit_offset_args/2,
sql_transaction/2,
get_last/2,
select_last/3,
set_last_t/4,
del_last/2,
get_password/2,
set_password_t/3,
add_user/3,
Expand Down Expand Up @@ -247,30 +243,6 @@ begin_trans(mssql) ->
begin_trans(_) ->
[<<"BEGIN;">>].


get_last(LServer, Username) ->
mongoose_rdbms:sql_query(
LServer,
[<<"select seconds, state from last "
"where username=">>, mongoose_rdbms:use_escaped_string(Username)]).

select_last(LServer, TStamp, Comparator) ->
mongoose_rdbms:sql_query(
LServer,
[<<"select username, seconds, state from last "
"where seconds ">>, Comparator, " ",
mongoose_rdbms:use_escaped_integer(mongoose_rdbms:escape_integer(TStamp)), ";"]).

set_last_t(LServer, Username, Seconds, State) ->
update(LServer, "last", ["username", "seconds", "state"],
[Username, Seconds, State],
[<<"username=">>, mongoose_rdbms:use_escaped_string(Username)]).

del_last(LServer, Username) ->
mongoose_rdbms:sql_query(
LServer,
[<<"delete from last where username=">>, mongoose_rdbms:use_escaped_string(Username)]).

get_password(LServer, Username) ->
mongoose_rdbms:sql_query(
LServer,
Expand Down

0 comments on commit abc5a1a

Please sign in to comment.