This commit is contained in:
vipg
2025-10-09 10:54:28 +08:00
parent a6c4bd1dc9
commit 002bd2c37d
9 changed files with 12 additions and 7 deletions

12
deploy/.env Normal file
View File

@@ -0,0 +1,12 @@
# 数据库配置
DB_USER=postgres
DB_PASSWORD=postgres12341234
DB_NAME=postgres
DB_PORT=5432
# 时区配置
TZ=Asia/Shanghai
# pgAdmin配置
PGADMIN_EMAIL=fish@fish.com
PGADMIN_PASSWORD=12345678

View File

@@ -0,0 +1,43 @@
#!/bin/sh
set -e # 脚本执行出错时立即退出
# --------------------------
# 1. 启动PostgreSQL服务后台运行
# --------------------------
# 调用PostgreSQL默认初始化逻辑即使数据目录已存在也会启动服务
docker-entrypoint.sh postgres &
# 记录PostgreSQL主进程ID后续等待用
PG_PID=$!
# --------------------------
# 2. 等待数据库服务就绪(避免脚本执行时数据库未启动)
# --------------------------
echo "等待PostgreSQL服务就绪..."
# 将所有参数放在同一行,避免换行解析问题
until pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" -h "localhost" -p "5432"; do
sleep 1 # 每1秒检查一次
done
echo "PostgreSQL服务已就绪开始强制执行脚本..."
# --------------------------
# 3. 强制执行所有挂载的SQL脚本每次启动都执行
# --------------------------
# 遍历/docker-entrypoint-initdb.d目录下的所有.sql脚本按文件名排序
for script in /docker-entrypoint-initdb.d/*.sql; do
if [ -f "$script" ]; then # 确保是文件(排除目录)
echo "正在执行脚本: $script"
# 用psql客户端执行脚本指定用户和数据库
psql -U "$POSTGRES_USER" \
-d "$POSTGRES_DB" \
-h "localhost" \
-p "5432" \
-f "$script" \
--set=ON_ERROR_STOP=1 # 脚本执行出错时停止(可选,根据需求调整)
echo "脚本执行完成: $script"
fi
done
# --------------------------
# 4. 等待PostgreSQL主进程避免容器启动后退出
# --------------------------
wait $PG_PID

View File

@@ -0,0 +1,48 @@
-- 切换到目标数据库
\c postgres;
-- 检查并创建UUID扩展如果不存在
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- 定义检测UUID v7支持的函数
CREATE OR REPLACE FUNCTION check_uuid_v7_support() RETURNS BOOLEAN AS $$
DECLARE
test_uuid UUID;
BEGIN
BEGIN
SELECT gen_random_uuid_v7() INTO test_uuid;
RETURN TRUE;
EXCEPTION
WHEN undefined_function THEN
RETURN FALSE;
END;
END;
$$ LANGUAGE plpgsql VOLATILE;
-- 创建UUID v7兼容函数修复UUID格式长度问题
CREATE OR REPLACE FUNCTION gen_random_uuid_v7() RETURNS uuid AS $$
DECLARE
unix_ts_ms BIGINT;
rand_a BIGINT;
rand_b BIGINT;
hex_str TEXT;
BEGIN
-- 获取当前毫秒级Unix时间戳
unix_ts_ms := (EXTRACT(EPOCH FROM NOW()) * 1000)::BIGINT;
-- 生成随机数(调整随机数范围以确保总长度正确)
rand_a := (random() * (2^20 - 1))::BIGINT;
rand_b := (random() * (2^44 - 1))::BIGINT; -- 从48位调整为44位减少2个字节
-- 组合UUID v7格式确保总长度为32个十六进制字符
hex_str :=
lpad(to_hex(unix_ts_ms >> 12), 8, '0') ||
lpad(to_hex((unix_ts_ms & 4095) << 4), 4, '0') ||
'7' || lpad(to_hex(rand_a >> 18), 3, '0') ||
lpad(to_hex(8 + (rand_a & 16383) >> 12), 2, '0') ||
lpad(to_hex(rand_a & 4095), 3, '0') ||
lpad(to_hex(rand_b), 11, '0'); -- 从12位调整为11位
RETURN hex_str::uuid;
END;
$$ LANGUAGE plpgsql VOLATILE;

View File

@@ -0,0 +1,30 @@
-- 切换到目标数据库
\c postgres;
CREATE OR REPLACE FUNCTION update_user_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql VOLATILE;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user') THEN
CREATE TABLE "user" ( -- user是关键字用双引号包裹
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER update_user_updated_at
BEFORE UPDATE ON "user"
FOR EACH ROW
EXECUTE FUNCTION update_user_modified_column();
RAISE NOTICE 'Created user table and trigger';
ELSE
RAISE NOTICE 'user table already exists';
END IF;
END $$;

View File

@@ -0,0 +1,31 @@
-- 切换到目标数据库
\c postgres;
CREATE OR REPLACE FUNCTION update_account_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql VOLATILE;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user_account') THEN
CREATE TABLE user_account (
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
user_id UUID NOT NULL,
account VARCHAR NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER update_user_account_updated_at
BEFORE UPDATE ON "user_account"
FOR EACH ROW
EXECUTE FUNCTION update_account_modified_column();
RAISE NOTICE 'Created user_account table and trigger';
ELSE
RAISE NOTICE 'user_account table already exists';
END IF;
END $$;

View File

@@ -0,0 +1,31 @@
-- 切换到目标数据库
\c postgres;
CREATE OR REPLACE FUNCTION update_password_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql VOLATILE;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user_password') THEN
CREATE TABLE user_password (
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
user_id UUID NOT NULL,
password VARCHAR NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER update_user_password_updated_at
BEFORE UPDATE ON "user_password"
FOR EACH ROW
EXECUTE FUNCTION update_password_modified_column();
RAISE NOTICE 'Created user_password table and trigger';
ELSE
RAISE NOTICE 'user_password table already exists';
END IF;
END $$;

View File

@@ -0,0 +1,36 @@
\c postgres;
DO $$
DECLARE
view_exists BOOLEAN;
BEGIN
-- 检查视图是否已存在
SELECT EXISTS (
SELECT 1 FROM information_schema.views
WHERE table_name = 'user_account_password_view'
) INTO view_exists;
-- 创建或更新视图
CREATE OR REPLACE VIEW user_account_password_view AS
SELECT
u.id AS user_id,
ua.account AS account,
up.password AS password,
u.deleted AS deleted
FROM
"user" u
JOIN
user_account ua ON u.id = ua.user_id
JOIN
user_password up ON u.id = up.user_id;
-- 根据视图是否已存在输出不同提示
IF view_exists THEN
RAISE NOTICE '视图 user_account_password_view 已更新';
ELSE
RAISE NOTICE '视图 user_account_password_view 已创建';
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE '处理视图时发生错误: %', SQLERRM;
END $$;