"""utf8mb4 charset and collation Revision ID: 56e2ce8e2ffa Revises: ef39fcd6e1cd Create Date: 2021-05-17 14:23:00.008479 """ from alembic import op import aurweb.config # revision identifiers, used by Alembic. revision = '56e2ce8e2ffa' down_revision = 'ef39fcd6e1cd' branch_labels = None depends_on = None # Tables affected by charset/collate change tables = [ ('AccountTypes', 'utf8mb4', 'utf8mb4_general_ci'), ('ApiRateLimit', 'utf8mb4', 'utf8mb4_general_ci'), ('Bans', 'utf8mb4', 'utf8mb4_general_ci'), ('DependencyTypes', 'utf8mb4', 'utf8mb4_general_ci'), ('Groups', 'utf8mb4', 'utf8mb4_general_ci'), ('Licenses', 'utf8mb4', 'utf8mb4_general_ci'), ('OfficialProviders', 'utf8mb4', 'utf8mb4_bin'), ('PackageBases', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageBlacklist', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageComments', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageDepends', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageKeywords', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageRelations', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageRequests', 'utf8mb4', 'utf8mb4_general_ci'), ('PackageSources', 'utf8mb4', 'utf8mb4_general_ci'), ('Packages', 'utf8mb4', 'utf8mb4_general_ci'), ('RelationTypes', 'utf8mb4', 'utf8mb4_general_ci'), ('RequestTypes', 'utf8mb4', 'utf8mb4_general_ci'), ('SSHPubKeys', 'utf8mb4', 'utf8mb4_bin'), ('Sessions', 'utf8mb4', 'utf8mb4_bin'), ('TU_VoteInfo', 'utf8mb4', 'utf8mb4_general_ci'), ('Terms', 'utf8mb4', 'utf8mb4_general_ci'), ('Users', 'utf8mb4', 'utf8mb4_general_ci') ] # Indexes affected by charset/collate change # Map of Unique Indexes key = index_name, value = [table_name, column1, column2] indexes = {'ProviderNameProvides': ['OfficialProviders', 'Name', 'Provides']} # Source charset/collation, before this migration is run. src_charset = "utf8" src_collate = "utf8_general_ci" db_backend = aurweb.config.get("database", "backend") def rebuild_unique_indexes_with_str_cols(): for idx_name in indexes: sql = f""" DROP INDEX IF EXISTS {idx_name} ON {indexes.get(idx_name)[0]} """ op.execute(sql) sql = f""" CREATE UNIQUE INDEX {idx_name} ON {indexes.get(idx_name)[0]} ({indexes.get(idx_name)[1]}, {indexes.get(idx_name)[2]}) """ op.execute(sql) def do_all(iterable, fn): for element in iterable: fn(element) def upgrade(): def op_execute(table_meta): table, charset, collate = table_meta sql = f""" ALTER TABLE {table} CONVERT TO CHARACTER SET {charset} COLLATE {collate} """ op.execute(sql) do_all(tables, op_execute) rebuild_unique_indexes_with_str_cols() def downgrade(): if db_backend == "sqlite": return None def op_execute(table_meta): table, charset, collate = table_meta sql = f""" ALTER TABLE {table} CONVERT TO CHARACTER SET {src_charset} COLLATE {src_collate} """ op.execute(sql) do_all(tables, op_execute) rebuild_unique_indexes_with_str_cols()