-
Notifications
You must be signed in to change notification settings - Fork 428
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
Pubsub index rdbms #2160
Pubsub index rdbms #2160
Changes from all commits
3b173b4
db5a847
1f88dea
368e66d
ea1272a
93c217d
1aad023
718c0f0
68bfc7c
704999b
4f3cdee
5b8d908
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,7 +54,8 @@ | |
|
||
% Nodes | ||
|
||
-export([upsert_pubsub_node/6, | ||
-export([insert_pubsub_node/5, | ||
update_pubsub_node/4, | ||
select_node_by_key_and_name/2, | ||
select_node_by_id/1, | ||
select_nodes_by_key/1, | ||
|
@@ -517,82 +518,60 @@ delete_all_items(Nidx) -> | |
["DELETE FROM pubsub_items" | ||
" WHERE nidx = ", esc_int(Nidx)]. | ||
|
||
|
||
-spec upsert_pubsub_node(Nidx :: mod_pubsub:nodeIdx(), Key :: binary(), | ||
Name :: mod_pubsub:nodeId(), Type :: binary(), | ||
Owners :: binary(), Options :: binary()) -> iolist(). | ||
upsert_pubsub_node(Nidx, Key, Name, Type, Owners, Options) -> | ||
EscNidx = esc_int(Nidx), | ||
insert_pubsub_node(Key, Name, Type, Owners, Options) -> | ||
RDBMSType = {mongoose_rdbms:db_engine(global), mongoose_rdbms_type:get()}, | ||
EscKey = esc_string(Key), | ||
EscName = esc_string(Name), | ||
EscType = esc_string(Type), | ||
EscOwners = esc_string(Owners), | ||
EscOptions = esc_string(Options), | ||
case {mongoose_rdbms:db_engine(global), mongoose_rdbms_type:get()} of | ||
{mysql, _} -> | ||
upsert_node_mysql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions); | ||
{pgsql, _} -> | ||
upsert_node_pgsql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions); | ||
{odbc, mssql} -> | ||
upsert_node_mssql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions); | ||
NotSupported -> erlang:error({rdbms_not_supported, NotSupported}) | ||
end. | ||
|
||
upsert_node_pgsql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions) -> | ||
Insert = mysql_and_pgsql_node_insert(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions), | ||
OnConflict = pgsql_node_conflict(EscType, EscOwners, EscOptions), | ||
[Insert, OnConflict]. | ||
|
||
upsert_node_mysql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions) -> | ||
Insert = mysql_and_pgsql_node_insert(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions), | ||
OnConflict = mysql_node_conflict(EscType, EscOwners, EscOptions), | ||
[Insert, OnConflict]. | ||
|
||
mysql_and_pgsql_node_insert(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions) -> | ||
["INSERT INTO pubsub_nodes (nidx, p_key, name, type, owners, options) VALUES (", | ||
EscNidx, ", ", | ||
EscKey, ", ", | ||
EscName, ", ", | ||
EscType, ", ", | ||
EscOwners, ", ", | ||
EscOptions, | ||
")"]. | ||
sql_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions, RDBMSType). | ||
|
||
pgsql_node_conflict(EscType, EscOwners, EscOptions) -> | ||
[" ON CONFLICT (nidx, p_key, name) DO", | ||
" UPDATE SET type = ", EscType, ", " | ||
" owners = ", EscOwners, ", " | ||
" options = ", EscOptions]. | ||
|
||
mysql_node_conflict(EscType, EscOwners, EscOptions) -> | ||
[" ON DUPLICATE KEY", | ||
" UPDATE type = ", EscType, ", " | ||
" owners = ", EscOwners, ", " | ||
" options = ", EscOptions]. | ||
|
||
upsert_node_mssql(EscNidx, EscKey, EscName, EscType, EscOwners, EscOptions) -> | ||
["MERGE INTO pubsub_nodes WITH (SERIALIZABLE) as target" | ||
" USING (SELECT ", EscNidx, " AS nidx, ", | ||
EscKey, " AS p_key, ", | ||
EscName, " AS name)" | ||
" AS source (nidx, p_key, name)" | ||
" ON (target.nidx = source.nidx" | ||
" AND target.p_key = source.p_key" | ||
" AND target.name = source.name)" | ||
" WHEN MATCHED THEN UPDATE" | ||
" SET type = ", EscType, ", " | ||
"owners = ", EscOwners, ", " | ||
"options = ", EscOptions, | ||
" WHEN NOT MATCHED THEN INSERT" | ||
" (nidx, p_key, name, type, owners, options)" | ||
" VALUES (", | ||
EscNidx, ", ", | ||
EscKey, ", ", | ||
EscName, ", ", | ||
EscType, ", ", | ||
EscOwners, ", ", | ||
EscOptions, | ||
");"]. | ||
update_pubsub_node(Nidx, Type, Owners, Options) -> | ||
EscNidx = esc_int(Nidx), | ||
EscType = esc_string(Type), | ||
EscOwners = esc_string(Owners), | ||
EscOptions = esc_string(Options), | ||
sql_node_update(EscNidx, EscType, EscOwners, EscOptions). | ||
|
||
sql_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions, {odbc, mssql}) -> | ||
Query = ["INSERT INTO pubsub_nodes (p_key, name, type, owners, options) " | ||
"OUTPUT inserted.nidx " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
"VALUES (", | ||
EscKey, ", ", | ||
EscName, ", ", | ||
EscType, ", ", | ||
EscOwners, ", ", | ||
EscOptions, ");"], | ||
Res = mongoose_rdbms:sql_query(global, Query), | ||
convert_sql_nidx(Res); | ||
sql_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions, {pgsql, _}) -> | ||
Query = [common_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions), | ||
[" RETURNING nidx;"]], | ||
Res = mongoose_rdbms:sql_query(global, Query), | ||
convert_sql_nidx(Res); | ||
sql_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions, {mysql, _}) -> | ||
Queries = [common_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions), | ||
["; SELECT last_insert_id();"]], | ||
%% When a list of qeries is passed, the firs encountered error will be returned. | ||
%% Otherwise last statement result is returned. | ||
Res = mongoose_rdbms:sql_query(global, Queries), | ||
convert_sql_nidx(Res). | ||
|
||
common_node_insert(EscKey, EscName, EscType, EscOwners, EscOptions) -> | ||
["INSERT INTO pubsub_nodes (p_key, name, type, owners, options) VALUES (", | ||
EscKey, ", ", | ||
EscName, ", ", | ||
EscType, ", ", | ||
EscOwners, ", ", | ||
EscOptions, ")"]. | ||
|
||
sql_node_update(EscNidx, EscType, EscOwners, EscOptions) -> | ||
Query = [" UPDATE pubsub_nodes SET type = ", EscType, ", " | ||
" owners = ", EscOwners, ", " | ||
" options = ", EscOptions, | ||
" WHERE nidx = ", EscNidx, ";"], | ||
{updated, _} = mongoose_rdbms:sql_query(global, Query). | ||
|
||
set_parents(Node, Parents) -> | ||
EscNode = esc_string(Node), | ||
|
@@ -690,3 +669,11 @@ esc_string(String) -> | |
esc_int(Int) -> | ||
mongoose_rdbms:use_escaped_integer(mongoose_rdbms:escape_integer(Int)). | ||
|
||
%% MSSQL and MYSQL | ||
convert_sql_nidx({selected, [{Nidx}]}) -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just realized that it may be helpful for someone new to this part of the code if there is a comment somewhere in the code which DB returns what. So that it's easier to understand the code. You and me understand it (at least today). I'm not sure how easy would it be to understand for anyone who didn't work on this change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've marked which clause applies to which DB. I think that's enough to understand :) |
||
{ok, mongoose_rdbms:result_to_integer(Nidx)}; | ||
%% PGSQL | ||
convert_sql_nidx({updated, _, [{Nidx}]}) -> | ||
{ok, mongoose_rdbms:result_to_integer(Nidx)}; | ||
convert_sql_nidx(Res) -> | ||
{error, {bad_rdbms_response, Res}}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the data is still maintained in Mnesia, so there is a certain risk of it becoming inconsistent?
Please note the schema used by this backend is still prone to changes as it has not reached a stable status?
If
mod_pubsub
is configured to use RDBMS, management of nodes indexes is done by the database, so thepubsub_index
table is not needed.