refactor(base): 重构并优化序列重置功能

- 移除 init 函数中的硬编码 SQL
- 新增 ResetAllSequences 函数用于重置所有序列
- 优化序列重置逻辑,提高可读性和可维护性
- 添加错误处理和日志记录,提升代码健壮性
This commit is contained in:
2025-07-11 15:23:41 +08:00
parent d71b1dd169
commit 79a31c5b55

View File

@@ -3,6 +3,7 @@ package base
import ( import (
_ "blazing/modules/base/packed" _ "blazing/modules/base/packed"
"context" "context"
"fmt"
"blazing/cool" "blazing/cool"
@@ -13,6 +14,7 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gconv"
) )
func init() { func init() {
@@ -31,38 +33,109 @@ func init() {
cool.FillInitData(ctx, "base", &model.BaseSysRoleDepartment{}) cool.FillInitData(ctx, "base", &model.BaseSysRoleDepartment{})
cool.FillInitData(ctx, "base", &model.BaseSysParam{}) cool.FillInitData(ctx, "base", &model.BaseSysParam{})
cool.FillInitData(ctx, "base", &model.BaseSysConf{}) cool.FillInitData(ctx, "base", &model.BaseSysConf{})
g.DB("default").Exec(context.Background(), `CREATE OR REPLACE FUNCTION reset_all_sequences() ResetAllSequences(ctx)
RETURNS void AS $$ // g.DB("default").Exec(context.Background(), `CREATE OR REPLACE FUNCTION reset_all_sequences()
DECLARE // RETURNS void AS $$
seq_record record; // DECLARE
BEGIN // seq_record record;
FOR seq_record IN // BEGIN
SELECT // FOR seq_record IN
'SELECT SETVAL(' || // SELECT
quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) || // 'SELECT SETVAL(' ||
', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' || // quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';' AS sql // ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
FROM // quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';' AS sql
pg_class AS S, // FROM
pg_depend AS D, // pg_class AS S,
pg_class AS T, // pg_depend AS D,
pg_attribute AS C, // pg_class AS T,
pg_tables AS PGT // pg_attribute AS C,
WHERE // pg_tables AS PGT
S.relkind = 'S' // WHERE
AND S.oid = D.objid // S.relkind = 'S'
AND D.refobjid = T.oid // AND S.oid = D.objid
AND D.refobjid = C.attrelid // AND D.refobjid = T.oid
AND D.refobjsubid = C.attnum // AND D.refobjid = C.attrelid
AND T.relname = PGT.tablename // AND D.refobjsubid = C.attnum
LOOP // AND T.relname = PGT.tablename
EXECUTE seq_record.sql; // LOOP
END LOOP; // EXECUTE seq_record.sql;
END; // END LOOP;
$$ LANGUAGE plpgsql; // END;
// $$ LANGUAGE plpgsql;
-- 执行函数 // -- 执行函数
SELECT reset_all_sequences();`, nil) //重置所有序列 // SELECT reset_all_sequences();`, nil) //重置所有序列
g.Log().Debug(ctx, "module base init finished ...") g.Log().Debug(ctx, "module base init finished ...")
} }
func ResetAllSequences(ctx context.Context) error {
// 查询所有序列及其关联的表和字段信息
query := `
SELECT
n.nspname AS schema_name,
s.relname AS sequence_name,
t.relname AS table_name,
a.attname AS column_name
FROM
pg_class s
JOIN pg_depend d ON s.oid = d.objid
JOIN pg_class t ON d.refobjid = t.oid
JOIN pg_attribute a ON d.refobjid = a.attrelid AND d.refobjsubid = a.attnum
JOIN pg_namespace n ON s.relnamespace = n.oid
WHERE
s.relkind = 'S'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
`
// 执行查询获取序列信息
records, err := g.DB("default").Query(ctx, query)
if err != nil {
return fmt.Errorf("查询序列信息失败: %w", err)
}
// 遍历每个序列并重置
for _, record := range records {
schemaName := record.Map()["schema_name"]
sequenceName := record.Map()["sequence_name"]
tableName := record.Map()["table_name"]
columnName := record.Map()["column_name"]
// 获取表中对应列的最大值
maxValueQuery := fmt.Sprintf(`SELECT MAX("%s") FROM "%s"."%s"`,
columnName, schemaName, tableName)
maxValueRecord, err := g.DB("default").Query(ctx, maxValueQuery)
if err != nil {
g.Log().Warning(ctx, fmt.Sprintf("获取表 %s.%s 的最大值失败: %v",
schemaName, tableName, err))
continue
}
// 处理最大值结果
var maxValue int64 = 1
if len(maxValueRecord) > 0 && !maxValueRecord[0].IsEmpty() {
maxValue = gconv.Int64(maxValueRecord[0].Map()["max"])
if maxValue < 1 {
maxValue = 1
}
}
// 重置序列值
resetQuery := fmt.Sprintf(`SELECT SETVAL('%s.%s', %d)`,
schemaName, sequenceName, maxValue)
_, err = g.DB("default").Exec(ctx, resetQuery)
if err != nil {
g.Log().Warning(ctx, fmt.Sprintf("重置序列 %s.%s 失败: %v",
schemaName, sequenceName, err))
continue
}
g.Log().Info(ctx, fmt.Sprintf("序列 %s.%s 已重置为 %d",
schemaName, sequenceName, maxValue))
}
return nil
}