-- 在当前商户业务库增加消息加密字段。 -- 可重复执行,覆盖单聊、消息修订、群聊主表及全部现有群消息月分片。 DELIMITER $$ DROP PROCEDURE IF EXISTS add_message_crypto_column$$ CREATE PROCEDURE add_message_crypto_column( IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_definition TEXT ) BEGIN IF EXISTS ( SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table ) AND NOT EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND COLUMN_NAME = p_column ) THEN SET @ddl = CONCAT('ALTER TABLE `', REPLACE(p_table, '`', '``'), '` ADD COLUMN `', REPLACE(p_column, '`', '``'), '` ', p_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ DROP PROCEDURE IF EXISTS drop_message_crypto_column$$ CREATE PROCEDURE drop_message_crypto_column(IN p_table VARCHAR(64), IN p_column VARCHAR(64)) BEGIN IF EXISTS ( SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND COLUMN_NAME = p_column ) THEN SET @ddl = CONCAT('ALTER TABLE `', REPLACE(p_table, '`', '``'), '` DROP COLUMN `', REPLACE(p_column, '`', '``'), '`'); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ DROP PROCEDURE IF EXISTS migrate_message_crypto_table$$ CREATE PROCEDURE migrate_message_crypto_table(IN p_table VARCHAR(64)) BEGIN CALL add_message_crypto_column(p_table, 'content_nonce', 'VARBINARY(12) NULL COMMENT ''每条消息独立随机Nonce'' AFTER `content`'); CALL add_message_crypto_column(p_table, 'key_version', 'INT NOT NULL DEFAULT 0 COMMENT ''商户消息DEK版本'' AFTER `content_nonce`'); CALL drop_message_crypto_column(p_table, 'content_ciphertext'); CALL drop_message_crypto_column(p_table, 'encryption_alg'); CALL drop_message_crypto_column(p_table, 'encrypted'); END$$ DROP PROCEDURE IF EXISTS migrate_message_crypto_schema$$ CREATE PROCEDURE migrate_message_crypto_schema() BEGIN DECLARE done INT DEFAULT 0; DECLARE table_name_value VARCHAR(64); DECLARE shard_cursor CURSOR FOR SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME REGEXP '^im_group_messages_[0-9]{6}$'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; CALL migrate_message_crypto_table('im_messages'); CALL migrate_message_crypto_table('im_message_revisions'); CALL migrate_message_crypto_table('im_group_messages'); OPEN shard_cursor; shard_loop: LOOP FETCH shard_cursor INTO table_name_value; IF done = 1 THEN LEAVE shard_loop; END IF; CALL migrate_message_crypto_table(table_name_value); END LOOP; CLOSE shard_cursor; END$$ CALL migrate_message_crypto_schema()$$ DROP PROCEDURE migrate_message_crypto_schema$$ DROP PROCEDURE migrate_message_crypto_table$$ DROP PROCEDURE drop_message_crypto_column$$ DROP PROCEDURE add_message_crypto_column$$ DELIMITER ;