286 lines
11 KiB
SQL
286 lines
11 KiB
SQL
-- ===================================================================
|
|
-- 安全的全局配置表初始化脚本
|
|
-- 适配现有表结构,避免字段冲突
|
|
-- ===================================================================
|
|
|
|
-- 首先检查现有的 ak_languages 表结构
|
|
DO $$
|
|
DECLARE
|
|
rec RECORD;
|
|
BEGIN
|
|
RAISE NOTICE '========================================';
|
|
RAISE NOTICE '检查现有 ak_languages 表结构:';
|
|
RAISE NOTICE '========================================';
|
|
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ak_languages') THEN
|
|
FOR rec IN
|
|
SELECT column_name, data_type, is_nullable, column_default
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages'
|
|
ORDER BY ordinal_position
|
|
LOOP
|
|
RAISE NOTICE '列: % - 类型: % - 可空: % - 默认值: %',
|
|
rec.column_name, rec.data_type, rec.is_nullable, rec.column_default;
|
|
END LOOP;
|
|
ELSE
|
|
RAISE NOTICE 'ak_languages 表不存在';
|
|
END IF;
|
|
|
|
RAISE NOTICE '========================================';
|
|
END $$;
|
|
|
|
-- 检查并创建必要的扩展
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- 1. 检查并创建/修改主配置表
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.tables
|
|
WHERE table_schema = 'public' AND table_name = 'ak_global_config'
|
|
) THEN
|
|
-- 如果主配置表不存在,创建新的主表+翻译表结构
|
|
CREATE TABLE public.ak_global_config (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
config_key VARCHAR(100) NOT NULL UNIQUE,
|
|
config_type VARCHAR(50) DEFAULT 'string',
|
|
config_category VARCHAR(50) DEFAULT 'general',
|
|
default_value TEXT,
|
|
is_translatable BOOLEAN DEFAULT false,
|
|
is_active BOOLEAN DEFAULT true,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
RAISE NOTICE '已创建新的 ak_global_config 主表';
|
|
ELSE
|
|
RAISE NOTICE 'ak_global_config 表已存在,检查是否需要添加字段';
|
|
|
|
-- 检查并添加缺失的字段
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_global_config'
|
|
AND column_name = 'config_category'
|
|
) THEN
|
|
ALTER TABLE public.ak_global_config ADD COLUMN config_category VARCHAR(50) DEFAULT 'general';
|
|
RAISE NOTICE '已添加 config_category 字段';
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_global_config'
|
|
AND column_name = 'is_translatable'
|
|
) THEN
|
|
ALTER TABLE public.ak_global_config ADD COLUMN is_translatable BOOLEAN DEFAULT false;
|
|
RAISE NOTICE '已添加 is_translatable 字段';
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_global_config'
|
|
AND column_name = 'sort_order'
|
|
) THEN
|
|
ALTER TABLE public.ak_global_config ADD COLUMN sort_order INTEGER DEFAULT 0;
|
|
RAISE NOTICE '已添加 sort_order 字段';
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_global_config'
|
|
AND column_name = 'default_value'
|
|
) THEN
|
|
ALTER TABLE public.ak_global_config ADD COLUMN default_value TEXT;
|
|
RAISE NOTICE '已添加 default_value 字段';
|
|
END IF;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- 2. 创建翻译表
|
|
CREATE TABLE IF NOT EXISTS public.ak_global_config_translations (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
config_id UUID NOT NULL REFERENCES public.ak_global_config(id) ON DELETE CASCADE,
|
|
language_code VARCHAR(10) NOT NULL,
|
|
translated_value TEXT NOT NULL,
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
UNIQUE(config_id, language_code)
|
|
);
|
|
|
|
-- 3. 适配现有的 ak_languages 表
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ak_languages') THEN
|
|
RAISE NOTICE '使用现有的 ak_languages 表';
|
|
|
|
-- 检查并添加可能缺失的字段
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages'
|
|
AND column_name = 'sort_order'
|
|
) THEN
|
|
ALTER TABLE public.ak_languages ADD COLUMN sort_order INTEGER DEFAULT 0;
|
|
RAISE NOTICE '已为 ak_languages 表添加 sort_order 字段';
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages'
|
|
AND column_name = 'is_default'
|
|
) THEN
|
|
ALTER TABLE public.ak_languages ADD COLUMN is_default BOOLEAN DEFAULT false;
|
|
RAISE NOTICE '已为 ak_languages 表添加 is_default 字段';
|
|
END IF;
|
|
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages'
|
|
AND column_name = 'native_name'
|
|
) THEN
|
|
ALTER TABLE public.ak_languages ADD COLUMN native_name VARCHAR(100);
|
|
RAISE NOTICE '已为 ak_languages 表添加 native_name 字段';
|
|
END IF;
|
|
ELSE
|
|
-- 创建新的语言表
|
|
CREATE TABLE public.ak_languages (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
code VARCHAR(10) NOT NULL UNIQUE,
|
|
name VARCHAR(100) NOT NULL,
|
|
native_name VARCHAR(100) NOT NULL,
|
|
is_active BOOLEAN DEFAULT true,
|
|
is_default BOOLEAN DEFAULT false,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
RAISE NOTICE '已创建新的 ak_languages 表';
|
|
END IF;
|
|
END $$;
|
|
|
|
-- 4. 创建索引
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_key ON public.ak_global_config(config_key);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_active ON public.ak_global_config(is_active);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_category ON public.ak_global_config(config_category);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_translatable ON public.ak_global_config(is_translatable);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_config ON public.ak_global_config_translations(config_id);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_lang ON public.ak_global_config_translations(language_code);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_active ON public.ak_global_config_translations(is_active);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_ak_languages_code ON public.ak_languages(code);
|
|
CREATE INDEX IF NOT EXISTS idx_ak_languages_active ON public.ak_languages(is_active);
|
|
|
|
-- 5. 安全地插入语言数据(动态构建 INSERT 语句)
|
|
DO $$
|
|
DECLARE
|
|
has_sort_order BOOLEAN;
|
|
has_is_default BOOLEAN;
|
|
has_native_name BOOLEAN;
|
|
insert_sql TEXT;
|
|
BEGIN
|
|
-- 检查字段是否存在
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'sort_order'
|
|
) INTO has_sort_order;
|
|
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'is_default'
|
|
) INTO has_is_default;
|
|
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'native_name'
|
|
) INTO has_native_name;
|
|
|
|
-- 构建动态 INSERT 语句
|
|
insert_sql := 'INSERT INTO public.ak_languages (code, name';
|
|
|
|
IF has_native_name THEN
|
|
insert_sql := insert_sql || ', native_name';
|
|
END IF;
|
|
|
|
IF has_is_default THEN
|
|
insert_sql := insert_sql || ', is_default';
|
|
END IF;
|
|
|
|
IF has_sort_order THEN
|
|
insert_sql := insert_sql || ', sort_order';
|
|
END IF;
|
|
|
|
insert_sql := insert_sql || ') VALUES ';
|
|
insert_sql := insert_sql || '(''zh'', ''Chinese Simplified''';
|
|
|
|
IF has_native_name THEN
|
|
insert_sql := insert_sql || ', ''简体中文''';
|
|
END IF;
|
|
|
|
IF has_is_default THEN
|
|
insert_sql := insert_sql || ', true';
|
|
END IF;
|
|
|
|
IF has_sort_order THEN
|
|
insert_sql := insert_sql || ', 1';
|
|
END IF;
|
|
|
|
insert_sql := insert_sql || '), (''en'', ''English''';
|
|
|
|
IF has_native_name THEN
|
|
insert_sql := insert_sql || ', ''English''';
|
|
END IF;
|
|
|
|
IF has_is_default THEN
|
|
insert_sql := insert_sql || ', false';
|
|
END IF;
|
|
|
|
IF has_sort_order THEN
|
|
insert_sql := insert_sql || ', 2';
|
|
END IF;
|
|
|
|
insert_sql := insert_sql || ') ON CONFLICT (code) DO UPDATE SET name = EXCLUDED.name';
|
|
|
|
IF has_native_name THEN
|
|
insert_sql := insert_sql || ', native_name = EXCLUDED.native_name';
|
|
END IF;
|
|
|
|
IF has_is_default THEN
|
|
insert_sql := insert_sql || ', is_default = EXCLUDED.is_default';
|
|
END IF;
|
|
|
|
IF has_sort_order THEN
|
|
insert_sql := insert_sql || ', sort_order = EXCLUDED.sort_order';
|
|
END IF;
|
|
|
|
-- 执行动态 SQL
|
|
EXECUTE insert_sql;
|
|
|
|
RAISE NOTICE '已安全插入语言数据';
|
|
RAISE NOTICE '执行的 SQL: %', insert_sql;
|
|
END $$;
|
|
|
|
-- 6. 显示最终的表结构确认
|
|
DO $$
|
|
DECLARE
|
|
rec RECORD;
|
|
BEGIN
|
|
RAISE NOTICE '========================================';
|
|
RAISE NOTICE '最终的 ak_languages 表结构:';
|
|
FOR rec IN
|
|
SELECT column_name, data_type, is_nullable
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = 'ak_languages'
|
|
ORDER BY ordinal_position
|
|
LOOP
|
|
RAISE NOTICE ' - % (%)', rec.column_name, rec.data_type;
|
|
END LOOP;
|
|
|
|
RAISE NOTICE '========================================';
|
|
RAISE NOTICE '语言数据:';
|
|
FOR rec IN
|
|
SELECT code, name FROM public.ak_languages ORDER BY code
|
|
LOOP
|
|
RAISE NOTICE ' - %: %', rec.code, rec.name;
|
|
END LOOP;
|
|
RAISE NOTICE '========================================';
|
|
END $$;
|