Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepared queries for chatmarkers and smart_markers #3066

Merged
merged 3 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions src/mod_smart_markers_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ init(Host, _) ->
QueryName = smart_markers_upsert,
rdbms_queries:prepare_upsert(Host, QueryName, smart_markers,
InsertFields, UpdateFields, KeyFields),
mongoose_rdbms:prepare(smart_markers_select, smart_markers,
[to_jid, thread, timestamp],
<<"select from_jid, to_jid, thread, type, msg_id, timestamp from smart_markers "
leszke marked this conversation as resolved.
Show resolved Hide resolved
"WHERE to_jid = ? AND thread = ? AND timestamp >= ? ;">>),
leszke marked this conversation as resolved.
Show resolved Hide resolved
ok.

%%% @doc
Expand All @@ -47,6 +51,15 @@ get_chat_markers(Host, To, Thread, TS) ->
%%--------------------------------------------------------------------
%% local functions
%%--------------------------------------------------------------------
-spec execute_select_chat_markers(Host :: jid:lserver(),
To :: binary(),
Thread :: binary(),
Timestamp :: integer()) ->
mongoose_rdbms:query_result().
execute_select_chat_markers(Host, To, Thread, Timestamp) ->
mongoose_rdbms:execute_successfully(Host, smart_markers_select,
[To, Thread, Timestamp]).

do_update_chat_marker(Host, #{from := From, to := To, thread := Thread,
type := Type, timestamp := TS, id := Id}) ->
FromEncoded = encode_jid(From),
Expand All @@ -61,14 +74,10 @@ do_update_chat_marker(Host, #{from := From, to := To, thread := Thread,
ok = check_upsert_result(Res).

do_get_chat_markers(Host, To, Thread, TS) ->
ToEscaped = escape(encode_jid(To)),
ThreadEscaped = escape(encode_thread(Thread)),
TSEscaped = escape(TS),
SelectQuery = [
"select from_jid, to_jid, thread, type, msg_id, timestamp from smart_markers"
" WHERE to_jid = ", ToEscaped, " AND thread = ", ThreadEscaped,
" AND timestamp >= ", TSEscaped, " ;"],
{selected, ChatMarkers} = mongoose_rdbms:sql_query(Host, SelectQuery),
{selected, ChatMarkers} = execute_select_chat_markers(Host,
encode_jid(To),
encode_thread(Thread),
TS),
decode(ChatMarkers).

encode_jid(JID) -> jid:to_binary(jid:to_lus(JID)).
Expand All @@ -80,15 +89,6 @@ encode_type(received) -> <<"R">>;
encode_type(displayed) -> <<"D">>;
encode_type(acknowledged) -> <<"A">>.

escape(String) when is_binary(String) -> escape_string(String);
escape(Int) when is_integer(Int) -> escape_int(Int).

escape_string(String) ->
mongoose_rdbms:use_escaped_string(mongoose_rdbms:escape_string(String)).

escape_int(Int) ->
mongoose_rdbms:use_escaped_integer(mongoose_rdbms:escape_integer(Int)).

%% MySQL returns 1 when an upsert is an insert
%% and 2, when an upsert acts as update
check_upsert_result({updated, 1}) -> ok;
Expand Down
64 changes: 33 additions & 31 deletions src/offline/mod_offline_chatmarkers_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,43 @@
-include("jlib.hrl").

-spec init(Host :: jid:lserver(), Opts :: list()) -> ok.
init(_Host, _Opts) ->
init(Host, _Opts) ->
mongoose_rdbms:prepare(offline_chatmarkers_select, offline_markers, [jid],
<<"SELECT thread, room, timestamp FROM offline_markers WHERE jid = ?;">>),
mongoose_rdbms:prepare(offline_chatmarkers_delete, offline_markers, [jid],
<<"DELETE FROM offline_markers WHERE jid = ?;">>),
rdbms_queries:prepare_upsert(Host, offline_chatmarkers_upsert, offline_markers,
[<<"jid">>, <<"thread">>, <<"room">>, <<"timestamp">>],
[],
[<<"jid">>, <<"thread">>, <<"room">>]),
ok.

-spec get(Jid :: jid:jid()) -> {ok, [{Thread :: undefined | binary(),
Room :: undefined | jid:jid(),
Timestamp :: integer()}]}.
get(#jid{lserver = Host} = Jid) ->
JidEscaped = escape(encode_jid(Jid)),
SelectQuery = ["SELECT thread, room, timestamp FROM offline_markers",
" WHERE jid = ", JidEscaped, ";"],
{selected, Rows} = mongoose_rdbms:sql_query(Host, SelectQuery),
{selected, Rows} = execute_select(Host, encode_jid(Jid)),
decode(Rows).

-spec execute_select(Host :: jid:lserver(), Jid :: binary()) -> mongoose_rdbms:query_result().
execute_select(Host, Jid) ->
mongoose_rdbms:execute_successfully(Host, offline_chatmarkers_select, [Jid]).

-spec execute_delete_user(Host :: jid:lserver(), Jid :: binary()) -> mongoose_rdbms:query_result().
execute_delete_user(Host, Jid) ->
mongoose_rdbms:execute_successfully(Host, offline_chatmarkers_delete, [Jid]).

-spec execute_maybe_store(Host :: jid:lserver(),
Jid :: binary(),
Thread :: binary(),
Room :: binary(),
Timestamp :: integer()) ->
mongoose_rdbms:query_result().
execute_maybe_store(Host, Jid, Thread, Room, Timestamp) ->
rdbms_queries:execute_upsert(Host, offline_chatmarkers_upsert,
[Jid, Thread, Room, Timestamp],
[],
[Jid, Thread, Room]).
%%% @doc
%%% Jid, Thread, and Room parameters serve as a composite database key. If
%%% key is not available in the database, then it must be added with the
Expand All @@ -39,20 +63,13 @@ get(#jid{lserver = Host} = Jid) ->
-spec maybe_store(Jid :: jid:jid(), Thread :: undefined | binary(),
Room :: undefined | jid:jid(), Timestamp :: integer()) -> ok.
maybe_store(#jid{lserver = Host} = Jid, Thread, Room, Timestamp) ->
JidEscaped = escape(encode_jid(Jid)),
ThreadEscaped = escape(encode_thread(Thread)),
RoomEscaped = escape(encode_jid(Room)),
TSEscaped = escape(Timestamp),
InsertQuery = ["INSERT INTO offline_markers (jid, thread, room, timestamp) VALUES (",
JidEscaped, ",", ThreadEscaped, ",", RoomEscaped, ",", TSEscaped, ");"],
Res = mongoose_rdbms:sql_query(Host, InsertQuery),
ok = check_insert_result(Res).
{updated, _} = execute_maybe_store(Host, encode_jid(Jid), encode_thread(Thread),
leszke marked this conversation as resolved.
Show resolved Hide resolved
encode_jid(Room), Timestamp),
ok.

-spec remove_user(Jid :: jid:jid()) -> ok.
remove_user(#jid{lserver = Host} = Jid) ->
JidEscaped = escape(encode_jid(Jid)),
DelQuery = ["DELETE FROM offline_markers WHERE jid = ", JidEscaped, ";"],
{updated, _} = mongoose_rdbms:sql_query(Host, DelQuery),
{updated, _} = execute_delete_user(Host, encode_jid(Jid)),
leszke marked this conversation as resolved.
Show resolved Hide resolved
ok.

encode_jid(undefined) -> <<"">>;
Expand All @@ -61,21 +78,6 @@ encode_jid(JID) -> jid:to_binary(jid:to_lus(JID)).
encode_thread(undefined) -> <<"">>;
encode_thread(Thread) -> Thread.

escape(String) when is_binary(String) -> escape_string(String);
escape(Int) when is_integer(Int) -> escape_int(Int).

escape_string(String) ->
mongoose_rdbms:use_escaped_string(mongoose_rdbms:escape_string(String)).

escape_int(Int) ->
mongoose_rdbms:use_escaped_integer(mongoose_rdbms:escape_integer(Int)).

%% add new record if key is not available, otherwise no changes to the table
check_insert_result({error,duplicate_key}) -> ok;
check_insert_result({updated, 1}) -> ok;
check_insert_result(Result) ->
{error, {bad_result, Result}}.

decode(Rows) ->
{ok, [decode_row(R) || R <- Rows]}.

Expand Down