157 lines
5.9 KiB
SQL
157 lines
5.9 KiB
SQL
-- 本文件是人工执行的 MySQL 前向补丁,未自动执行。
|
|
-- 执行前备份数据库,并在维护窗口使用独立连接运行标准 mysql batch。
|
|
-- 旧状态和目标状态均可通过写前校验,因此本补丁可幂等重跑。
|
|
-- 标准 mysql batch 遇错后必须退出并关闭连接,使未提交事务回滚;禁止使用 mysql --force。
|
|
|
|
-- 在事务外准备六个固定菜单的稳定身份及完整旧/新层级状态。
|
|
drop temporary table if exists promote_business_menus_expected;
|
|
create temporary table promote_business_menus_expected (
|
|
menu_id bigint not null,
|
|
menu_name varchar(50) not null,
|
|
path varchar(200),
|
|
component varchar(255),
|
|
query varchar(255),
|
|
route_name varchar(50),
|
|
is_frame int,
|
|
is_cache int,
|
|
menu_type char(1),
|
|
visible char(1),
|
|
status char(1),
|
|
perms varchar(100),
|
|
icon varchar(100),
|
|
old_parent_id bigint not null,
|
|
old_order_num int not null,
|
|
new_parent_id bigint not null,
|
|
new_order_num int not null,
|
|
primary key (menu_id)
|
|
) engine=innodb;
|
|
|
|
insert into promote_business_menus_expected (
|
|
menu_id, menu_name, path, component, query, route_name,
|
|
is_frame, is_cache, menu_type, visible, status, perms, icon,
|
|
old_parent_id, old_order_num, new_parent_id, new_order_num
|
|
) values
|
|
(1, '系统管理', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 0, 1, 0, 4),
|
|
(2, '系统监控', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 0, 2, 0, 5),
|
|
(3, '系统工具', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 0, 3, 0, 6),
|
|
(121, '基础资料维护', 'businessMaster', null, '', '', 1, 0, 'M', '0', '0', '', '#', 1, 10, 0, 1),
|
|
(122, '业务管理', 'businessOperation', null, '', '', 1, 0, 'M', '0', '0', '', '#', 1, 11, 0, 2),
|
|
(123, '报表查询', 'businessReport', null, '', '', 1, 0, 'M', '0', '0', '', '#', 1, 12, 0, 3);
|
|
|
|
drop temporary table if exists promote_business_menus_guard;
|
|
create temporary table promote_business_menus_guard (
|
|
guard_token varchar(64) not null,
|
|
primary key (guard_token)
|
|
) engine=innodb;
|
|
|
|
start transaction;
|
|
|
|
-- 锁定六个固定 ID,防止身份预检与永久更新之间被并发修改。
|
|
select menu_id
|
|
from sys_menu
|
|
where menu_id in (1, 2, 3, 121, 122, 123)
|
|
order by menu_id
|
|
for update;
|
|
|
|
-- 写前只接受六行全部处于旧状态或全部处于目标状态。
|
|
-- 缺行、稳定身份漂移或新旧状态混合时,重复主键 token 会中止 batch。
|
|
insert into promote_business_menus_guard (guard_token)
|
|
select guard_token
|
|
from (
|
|
select 'promote-business-menus-precondition-conflict' as guard_token
|
|
union all
|
|
select if(
|
|
count(actual.menu_id) = 6
|
|
and sum(
|
|
(binary actual.menu_name <=> binary expected.menu_name)
|
|
and (binary actual.path <=> binary expected.path)
|
|
and (binary actual.component <=> binary expected.component)
|
|
and (binary actual.query <=> binary expected.query)
|
|
and (binary actual.route_name <=> binary expected.route_name)
|
|
and (actual.is_frame <=> expected.is_frame)
|
|
and (actual.is_cache <=> expected.is_cache)
|
|
and (binary actual.menu_type <=> binary expected.menu_type)
|
|
and (binary actual.visible <=> binary expected.visible)
|
|
and (binary actual.status <=> binary expected.status)
|
|
and (binary actual.perms <=> binary expected.perms)
|
|
and (binary actual.icon <=> binary expected.icon)
|
|
) = 6
|
|
and (
|
|
sum(
|
|
(actual.parent_id <=> expected.old_parent_id)
|
|
and (actual.order_num <=> expected.old_order_num)
|
|
) = 6
|
|
or sum(
|
|
(actual.parent_id <=> expected.new_parent_id)
|
|
and (actual.order_num <=> expected.new_order_num)
|
|
) = 6
|
|
),
|
|
'promote-business-menus-precondition-verified',
|
|
'promote-business-menus-precondition-conflict'
|
|
) as guard_token
|
|
from promote_business_menus_expected as expected
|
|
left join sys_menu as actual
|
|
on actual.menu_id = expected.menu_id
|
|
) as precondition_guard_rows;
|
|
|
|
-- 唯一永久 DML:只更新六个固定菜单的父级和显示顺序。
|
|
update sys_menu
|
|
set parent_id = case
|
|
when menu_id in (121, 122, 123) then 0
|
|
else parent_id
|
|
end,
|
|
order_num = case menu_id
|
|
when 121 then 1
|
|
when 122 then 2
|
|
when 123 then 3
|
|
when 1 then 4
|
|
when 2 then 5
|
|
when 3 then 6
|
|
else order_num
|
|
end
|
|
where menu_id in (1, 2, 3, 121, 122, 123);
|
|
|
|
-- 提交前再次核对六行稳定身份及完整目标状态。
|
|
insert into promote_business_menus_guard (guard_token)
|
|
select guard_token
|
|
from (
|
|
select 'promote-business-menus-postcondition-conflict' as guard_token
|
|
union all
|
|
select if(
|
|
count(actual.menu_id) = 6
|
|
and sum(
|
|
(binary actual.menu_name <=> binary expected.menu_name)
|
|
and (binary actual.path <=> binary expected.path)
|
|
and (binary actual.component <=> binary expected.component)
|
|
and (binary actual.query <=> binary expected.query)
|
|
and (binary actual.route_name <=> binary expected.route_name)
|
|
and (actual.is_frame <=> expected.is_frame)
|
|
and (actual.is_cache <=> expected.is_cache)
|
|
and (binary actual.menu_type <=> binary expected.menu_type)
|
|
and (binary actual.visible <=> binary expected.visible)
|
|
and (binary actual.status <=> binary expected.status)
|
|
and (binary actual.perms <=> binary expected.perms)
|
|
and (binary actual.icon <=> binary expected.icon)
|
|
) = 6
|
|
and sum(
|
|
(actual.parent_id <=> expected.new_parent_id)
|
|
and (actual.order_num <=> expected.new_order_num)
|
|
) = 6,
|
|
'promote-business-menus-postcondition-verified',
|
|
'promote-business-menus-postcondition-conflict'
|
|
) as guard_token
|
|
from promote_business_menus_expected as expected
|
|
left join sys_menu as actual
|
|
on actual.menu_id = expected.menu_id
|
|
) as postcondition_guard_rows;
|
|
|
|
commit;
|
|
|
|
drop temporary table promote_business_menus_guard;
|
|
drop temporary table promote_business_menus_expected;
|
|
|
|
select menu_id, menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms
|
|
from sys_menu
|
|
where menu_id in (1, 2, 3, 121, 122, 123)
|
|
order by order_num, menu_id;
|