From f7f0d3b1fba30eedf7033bb1339f4a97acb6248d Mon Sep 17 00:00:00 2001 From: Stu Tomlinson Date: Thu, 19 Jan 2023 15:44:44 +0000 Subject: [PATCH] Enable MySQL support for new schema migration --- sql/mysql.new.sql | 2 +- src/mod_admin_update_sql.erl | 112 +++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/sql/mysql.new.sql b/sql/mysql.new.sql index cbd9414aa..959fbff84 100644 --- a/sql/mysql.new.sql +++ b/sql/mysql.new.sql @@ -85,7 +85,7 @@ CREATE TABLE sr_user ( PRIMARY KEY (server_host(191), jid, grp) ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -CREATE UNIQUE INDEX i_sr_user_sh_jid_group ON sr_user(server_host(191), jid, grp); +CREATE UNIQUE INDEX i_sr_user_sh_jid_grp ON sr_user(server_host(191), jid, grp); CREATE INDEX i_sr_user_sh_grp ON sr_user(server_host(191), grp); CREATE TABLE spool ( diff --git a/src/mod_admin_update_sql.erl b/src/mod_admin_update_sql.erl index e9f248f5c..ec86cece7 100644 --- a/src/mod_admin_update_sql.erl +++ b/src/mod_admin_update_sql.erl @@ -63,7 +63,7 @@ depends(_Host, _Opts) -> get_commands_spec() -> [#ejabberd_commands{name = update_sql, tags = [sql], - desc = "Convert PostgreSQL DB to the new format", + desc = "Convert MySQL or PostgreSQL DB to the new format", module = ?MODULE, function = update_sql, args = [], args_example = [], @@ -93,6 +93,7 @@ update_sql(Host) -> DBType = ejabberd_option:sql_type(LHost), IsSupported = case DBType of + mysql -> true; pgsql -> true; _ -> false end, @@ -125,15 +126,15 @@ update_tables(State) -> drop_sh_default(State, "last"), add_sh_column(State, "rosterusers"), - drop_index(State, "i_rosteru_user_jid"), - drop_index(State, "i_rosteru_username"), - drop_index(State, "i_rosteru_jid"), + drop_index(State, "rosterusers", "i_rosteru_user_jid"), + drop_index(State, "rosterusers", "i_rosteru_username"), + drop_index(State, "rosterusers", "i_rosteru_jid"), create_unique_index(State, "rosterusers", "i_rosteru_sh_user_jid", ["server_host", "username", "jid"]), create_index(State, "rosterusers", "i_rosteru_sh_jid", ["server_host", "jid"]), drop_sh_default(State, "rosterusers"), add_sh_column(State, "rostergroups"), - drop_index(State, "pk_rosterg_user_jid"), + drop_index(State, "rostergroups", "pk_rosterg_user_jid"), create_index(State, "rostergroups", "i_rosterg_sh_user_jid", ["server_host", "username", "jid"]), drop_sh_default(State, "rostergroups"), @@ -143,27 +144,27 @@ update_tables(State) -> drop_sh_default(State, "sr_group"), add_sh_column(State, "sr_user"), - drop_index(State, "i_sr_user_jid_grp"), - drop_index(State, "i_sr_user_jid"), - drop_index(State, "i_sr_user_grp"), + drop_index(State, "sr_user", "i_sr_user_jid_grp"), + drop_index(State, "sr_user", "i_sr_user_jid"), + drop_index(State, "sr_user", "i_sr_user_grp"), add_pkey(State, "sr_user", ["server_host", "jid", "grp"]), create_unique_index(State, "sr_user", "i_sr_user_sh_jid_grp", ["server_host", "jid", "grp"]), create_index(State, "sr_user", "i_sr_user_sh_grp", ["server_host", "grp"]), drop_sh_default(State, "sr_user"), add_sh_column(State, "spool"), - drop_index(State, "i_despool"), + drop_index(State, "spool", "i_despool"), create_index(State, "spool", "i_spool_sh_username", ["server_host", "username"]), drop_sh_default(State, "spool"), add_sh_column(State, "archive"), - drop_index(State, "i_username"), - drop_index(State, "i_username_timestamp"), - drop_index(State, "i_timestamp"), - drop_index(State, "i_peer"), - drop_index(State, "i_bare_peer"), - drop_index(State, "i_username_peer"), - drop_index(State, "i_username_bare_peer"), + drop_index(State, "archive", "i_username"), + drop_index(State, "archive", "i_username_timestamp"), + drop_index(State, "archive", "i_timestamp"), + drop_index(State, "archive", "i_peer"), + drop_index(State, "archive", "i_bare_peer"), + drop_index(State, "archive", "i_username_peer"), + drop_index(State, "archive", "i_username_bare_peer"), create_index(State, "archive", "i_archive_sh_username_timestamp", ["server_host", "username", "timestamp"]), create_index(State, "archive", "i_archive_sh_timestamp", ["server_host", "timestamp"]), create_index(State, "archive", "i_archive_sh_username_peer", ["server_host", "username", "peer"]), @@ -182,17 +183,17 @@ update_tables(State) -> add_sh_column(State, "vcard_search"), drop_pkey(State, "vcard_search"), - drop_index(State, "i_vcard_search_lfn"), - drop_index(State, "i_vcard_search_lfamily"), - drop_index(State, "i_vcard_search_lgiven"), - drop_index(State, "i_vcard_search_lmiddle"), - drop_index(State, "i_vcard_search_lnickname"), - drop_index(State, "i_vcard_search_lbday"), - drop_index(State, "i_vcard_search_lctry"), - drop_index(State, "i_vcard_search_llocality"), - drop_index(State, "i_vcard_search_lemail"), - drop_index(State, "i_vcard_search_lorgname"), - drop_index(State, "i_vcard_search_lorgunit"), + drop_index(State, "vcard_search", "i_vcard_search_lfn"), + drop_index(State, "vcard_search", "i_vcard_search_lfamily"), + drop_index(State, "vcard_search", "i_vcard_search_lgiven"), + drop_index(State, "vcard_search", "i_vcard_search_lmiddle"), + drop_index(State, "vcard_search", "i_vcard_search_lnickname"), + drop_index(State, "vcard_search", "i_vcard_search_lbday"), + drop_index(State, "vcard_search", "i_vcard_search_lctry"), + drop_index(State, "vcard_search", "i_vcard_search_llocality"), + drop_index(State, "vcard_search", "i_vcard_search_lemail"), + drop_index(State, "vcard_search", "i_vcard_search_lorgname"), + drop_index(State, "vcard_search", "i_vcard_search_lorgunit"), add_pkey(State, "vcard_search", ["server_host", "username"]), create_index(State, "vcard_search", "i_vcard_search_sh_lfn", ["server_host", "lfn"]), create_index(State, "vcard_search", "i_vcard_search_sh_lfamily", ["server_host", "lfamily"]), @@ -213,14 +214,14 @@ update_tables(State) -> drop_sh_default(State, "privacy_default_list"), add_sh_column(State, "privacy_list"), - drop_index(State, "i_privacy_list_username"), - drop_index(State, "i_privacy_list_username_name"), + drop_index(State, "privacy_list", "i_privacy_list_username"), + drop_index(State, "privacy_list", "i_privacy_list_username_name"), create_unique_index(State, "privacy_list", "i_privacy_list_sh_username_name", ["server_host", "username", "name"]), drop_sh_default(State, "privacy_list"), add_sh_column(State, "private_storage"), - drop_index(State, "i_private_storage_username"), - drop_index(State, "i_private_storage_username_namespace"), + drop_index(State, "private_storage", "i_private_storage_username"), + drop_index(State, "private_storage", "i_private_storage_username_namespace"), add_pkey(State, "private_storage", ["server_host", "username", "namespace"]), drop_sh_default(State, "private_storage"), @@ -247,27 +248,28 @@ update_tables(State) -> drop_sh_default(State, "motd"), add_sh_column(State, "sm"), - drop_index(State, "i_sm_sid"), - drop_index(State, "i_sm_username"), + drop_index(State, "sm", "i_sm_sid"), + drop_index(State, "sm", "i_sm_username"), add_pkey(State, "sm", ["usec", "pid"]), create_index(State, "sm", "i_sm_sh_username", ["server_host", "username"]), drop_sh_default(State, "sm"), add_sh_column(State, "push_session"), - drop_index(State, "i_push_usn"), - drop_index(State, "i_push_ut"), + drop_index(State, "push_session", "i_push_usn"), + drop_index(State, "push_session", "i_push_ut"), add_pkey(State, "push_session", ["server_host", "username", "timestamp"]), create_unique_index(State, "push_session", "i_push_session_susn", ["server_host", "username", "service", "node"]), drop_sh_default(State, "push_session"), add_sh_column(State, "mix_pam"), - drop_index(State, "i_mix_pam"), - drop_index(State, "i_mix_pam_us"), + drop_index(State, "mix_pam", "i_mix_pam"), + drop_index(State, "mix_pam", "i_mix_pam_u"), + drop_index(State, "mix_pam", "i_mix_pam_us"), create_unique_index(State, "mix_pam", "i_mix_pam", ["username", "server_host", "channel", "service"]), drop_sh_default(State, "mix_pam"), add_sh_column(State, "mqtt_pub"), - drop_index(State, "i_mqtt_topic"), + drop_index(State, "mqtt_pub", "i_mqtt_topic"), create_unique_index(State, "mqtt_pub", "i_mqtt_topic_server", ["topic", "server_host"]), drop_sh_default(State, "mqtt_pub"), @@ -282,7 +284,7 @@ add_sh_column(#state{dbtype = pgsql} = State, Table) -> add_sh_column(#state{dbtype = mysql} = State, Table) -> sql_query( State#state.host, - ["ALTER TABLE ", Table, " ADD COLUMN server_host text NOT NULL DEFAULT '", + ["ALTER TABLE ", Table, " ADD COLUMN server_host varchar(191) NOT NULL DEFAULT '", (State#state.escape)(State#state.host), "';"]). @@ -301,7 +303,8 @@ add_pkey(#state{dbtype = pgsql} = State, Table, Cols) -> State#state.host, ["ALTER TABLE ", Table, " ADD PRIMARY KEY (", SCols, ");"]); add_pkey(#state{dbtype = mysql} = State, Table, Cols) -> - SCols = string:join(Cols, ", "), + Cols2 = [C ++ mysql_keylen(Table, C) || C <- Cols], + SCols = string:join(Cols2, ", "), sql_query( State#state.host, ["ALTER TABLE ", Table, " ADD PRIMARY KEY (", SCols, ");"]). @@ -315,14 +318,14 @@ drop_sh_default(#state{dbtype = mysql} = State, Table) -> State#state.host, ["ALTER TABLE ", Table, " ALTER COLUMN server_host DROP DEFAULT;"]). -drop_index(#state{dbtype = pgsql} = State, Index) -> +drop_index(#state{dbtype = pgsql} = State, _Table, Index) -> sql_query( State#state.host, ["DROP INDEX ", Index, ";"]); -drop_index(#state{dbtype = mysql} = State, Index) -> +drop_index(#state{dbtype = mysql} = State, Table, Index) -> sql_query( State#state.host, - ["DROP INDEX ", Index, ";"]). + ["ALTER TABLE ", Table, " DROP INDEX ", Index, ";"]). create_unique_index(#state{dbtype = pgsql} = State, Table, Index, Cols) -> SCols = string:join(Cols, ", "), @@ -331,7 +334,7 @@ create_unique_index(#state{dbtype = pgsql} = State, Table, Index, Cols) -> ["CREATE UNIQUE INDEX ", Index, " ON ", Table, " USING btree (", SCols, ");"]); create_unique_index(#state{dbtype = mysql} = State, Table, Index, Cols) -> - Cols2 = [C ++ "(75)" || C <- Cols], + Cols2 = [C ++ mysql_keylen(Index, C) || C <- Cols], SCols = string:join(Cols2, ", "), sql_query( State#state.host, @@ -345,13 +348,30 @@ create_index(#state{dbtype = pgsql} = State, Table, Index, Cols) -> ["CREATE INDEX ", Index, " ON ", Table, " USING btree (", SCols, ");"]); create_index(#state{dbtype = mysql} = State, Table, Index, Cols) -> - Cols2 = [C ++ "(75)" || C <- Cols], + Cols2 = [C ++ mysql_keylen(Index, C) || C <- Cols], SCols = string:join(Cols2, ", "), sql_query( State#state.host, ["CREATE INDEX ", Index, " ON ", Table, "(", SCols, ");"]). +mysql_keylen(_, "bare_peer") -> "(191)"; +mysql_keylen(_, "channel") -> "(191)"; +mysql_keylen(_, "domain") -> "(75)"; +mysql_keylen(_, "jid") -> "(75)"; +mysql_keylen(_, "name") -> "(75)"; +mysql_keylen(_, "node") -> "(75)"; +mysql_keylen(_, "peer") -> "(191)"; +mysql_keylen(_, "pid") -> "(75)"; +mysql_keylen(_, "server_host") -> "(191)"; +mysql_keylen(_, "service") -> "(191)"; +mysql_keylen(_, "topic") -> "(191)"; +mysql_keylen("i_privacy_list_sh_username_name", "username") -> "(75)"; +mysql_keylen("i_rosterg_sh_user_jid", "username") -> "(75)"; +mysql_keylen("i_rosteru_sh_user_jid", "username") -> "(75)"; +mysql_keylen(_, "username") -> "(191)"; +mysql_keylen(_, _) -> "". + sql_query(Host, Query) -> io:format("executing \"~ts\" on ~ts~n", [Query, Host]), case ejabberd_sql:sql_query(Host, Query) of @@ -369,5 +389,5 @@ mod_doc() -> ?T("This module can be used to update existing SQL database " "from the default to the new schema. Check the section " "http://../database/#default-and-new-schemas[Default and New Schemas] for details. " - "Please note that only PostgreSQL is supported. " + "Please note that only MySQL and PostgreSQL are supported. " "When the module is loaded use _`update_sql`_ API.")}.