Files
akmon/complete_cleanup.sql
2026-01-20 08:04:15 +08:00

194 lines
7.1 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =====================================================
-- 完整清理脚本 - 解决所有冲突
-- 同时处理触发器、函数、策略冲突
-- =====================================================
-- 第一步:清理触发器
DO $$
BEGIN
RAISE NOTICE '🧹 第一步:清理触发器';
-- 删除用户角色相关触发器
DROP TRIGGER IF EXISTS trigger_update_user_roles_updated_at ON public.user_roles CASCADE;
DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users CASCADE;
-- 删除可能存在的旧版本触发器
DROP TRIGGER IF EXISTS update_user_roles_updated_at ON public.user_roles CASCADE;
DROP TRIGGER IF EXISTS handle_new_user_trigger ON auth.users CASCADE;
RAISE NOTICE '✅ 触发器清理完成';
END $$;
-- 第二步:清理函数(处理参数名称冲突)
DO $$
BEGIN
RAISE NOTICE '🧹 第二步:清理函数(解决参数冲突)';
-- 删除所有可能冲突的函数(按依赖顺序)
DROP FUNCTION IF EXISTS public.batch_update_user_roles(JSONB, UUID) CASCADE;
DROP FUNCTION IF EXISTS public.batch_update_user_roles(JSONB) CASCADE;
DROP FUNCTION IF EXISTS public.update_user_role(UUID, TEXT, UUID, JSONB) CASCADE;
DROP FUNCTION IF EXISTS public.update_user_role(UUID, TEXT, UUID) CASCADE;
DROP FUNCTION IF EXISTS public.update_user_role(UUID, TEXT) CASCADE;
DROP FUNCTION IF EXISTS public.get_user_role(UUID) CASCADE;
DROP FUNCTION IF EXISTS public.get_user_role() CASCADE;
DROP FUNCTION IF EXISTS public.sync_user_role_metadata(UUID) CASCADE;
DROP FUNCTION IF EXISTS public.user_has_permission(TEXT, UUID) CASCADE;
DROP FUNCTION IF EXISTS public.can_access_resource(TEXT, UUID, TEXT, UUID) CASCADE;
DROP FUNCTION IF EXISTS public.update_user_roles_updated_at() CASCADE;
DROP FUNCTION IF EXISTS public.handle_new_user() CASCADE;
DROP FUNCTION IF EXISTS public.test_message_permissions(UUID) CASCADE;
DROP FUNCTION IF EXISTS public.test_deployment() CASCADE;
RAISE NOTICE '✅ 函数清理完成(解决参数名称冲突)';
END $$;
-- 第三步:清理策略
DO $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE '🧹 第三步:清理策略';
-- 清理 user_roles 表的所有策略
FOR r IN
SELECT policyname
FROM pg_policies
WHERE schemaname = 'public'
AND tablename = 'user_roles'
LOOP
EXECUTE format('DROP POLICY IF EXISTS %I ON public.user_roles', r.policyname);
RAISE NOTICE ' 删除策略: %', r.policyname;
END LOOP;
-- 清理消息相关表的策略
FOR r IN
SELECT schemaname, tablename, policyname
FROM pg_policies
WHERE schemaname = 'public'
AND tablename IN ('ak_messages', 'ak_message_recipients', 'ak_message_groups',
'ak_message_group_members', 'ak_message_templates',
'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
LOOP
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
r.policyname, r.schemaname, r.tablename);
RAISE NOTICE ' 删除策略: %.%', r.tablename, r.policyname;
END LOOP;
RAISE NOTICE '✅ 策略清理完成';
END $$;
-- 第四步:清理视图(如果存在冲突)
DO $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE '🧹 第四步:清理视图和错误策略';
-- 删除可能错误创建在视图上的策略
FOR r IN
SELECT schemaname, tablename, policyname
FROM pg_policies
WHERE schemaname = 'public'
AND tablename IN (
SELECT table_name
FROM information_schema.views
WHERE table_schema = 'public'
)
LOOP
BEGIN
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
r.policyname, r.schemaname, r.tablename);
RAISE NOTICE ' 删除了视图上的错误策略: %.%', r.tablename, r.policyname;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE ' 无法删除策略: %.% (这是正常的)', r.tablename, r.policyname;
END;
END LOOP;
-- 重新创建视图
DROP VIEW IF EXISTS public.user_roles_with_email CASCADE;
DROP VIEW IF EXISTS public.user_roles_detailed CASCADE;
RAISE NOTICE '✅ 视图清理完成';
END $$;
-- 第五步:验证清理结果
DO $$
DECLARE
trigger_count INTEGER;
policy_count INTEGER;
function_count INTEGER;
BEGIN
RAISE NOTICE '🔍 第五步:验证清理结果';
-- 检查触发器
SELECT COUNT(*) INTO trigger_count
FROM information_schema.triggers
WHERE trigger_schema = 'public'
AND trigger_name IN ('trigger_update_user_roles_updated_at', 'on_auth_user_created');
-- 检查策略
SELECT COUNT(*) INTO policy_count
FROM pg_policies
WHERE schemaname = 'public'
AND tablename IN ('user_roles', 'ak_messages', 'ak_message_recipients');
-- 检查核心函数
SELECT COUNT(*) INTO function_count
FROM information_schema.routines
WHERE routine_schema = 'public'
AND routine_name IN ('get_user_role', 'user_has_permission', 'sync_user_role_metadata');
RAISE NOTICE '📊 清理统计:';
RAISE NOTICE ' - 剩余触发器: %', trigger_count;
RAISE NOTICE ' - 剩余策略: %', policy_count;
RAISE NOTICE ' - 核心函数: %', function_count;
IF trigger_count = 0 AND policy_count = 0 THEN
RAISE NOTICE '🎉 清理成功!可以安全地重新部署';
ELSE
RAISE NOTICE '⚠️ 部分组件仍存在,请检查是否需要进一步清理';
END IF;
END $$;
-- 第六步重置RLS状态确保表可以重新配置策略
DO $$
DECLARE
table_record RECORD;
BEGIN
RAISE NOTICE '🔄 第六步重置RLS状态';
-- 对所有相关表禁用然后重新启用RLS
FOR table_record IN
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN ('user_roles', 'ak_messages', 'ak_message_recipients', 'ak_message_groups',
'ak_message_group_members', 'ak_message_templates',
'ak_user_message_preferences', 'ak_message_stats', 'ak_message_types')
LOOP
EXECUTE format('ALTER TABLE public.%I DISABLE ROW LEVEL SECURITY', table_record.table_name);
EXECUTE format('ALTER TABLE public.%I ENABLE ROW LEVEL SECURITY', table_record.table_name);
RAISE NOTICE ' 重置RLS: %', table_record.table_name;
END LOOP;
RAISE NOTICE '✅ RLS状态重置完成';
END $$;
-- 完成消息
DO $$
BEGIN
RAISE NOTICE '🎉 完整清理完成!';
RAISE NOTICE '📋 下一步:';
RAISE NOTICE ' 1. 运行您的主要部署脚本';
RAISE NOTICE ' 2. 验证所有功能正常';
RAISE NOTICE ' 3. 测试权限和角色分配';
END $$;
-- 最终状态检查
SELECT
'🔧 清理完成' as status,
'系统已准备好重新部署' as message,
(SELECT COUNT(*) FROM pg_policies WHERE schemaname = 'public') as remaining_policies,
(SELECT COUNT(*) FROM information_schema.triggers WHERE trigger_schema = 'public') as remaining_triggers;