diff --git a/modules/base/base.go b/modules/base/base.go index 509eeedf1..b0722b526 100644 --- a/modules/base/base.go +++ b/modules/base/base.go @@ -3,6 +3,7 @@ package base import ( _ "blazing/modules/base/packed" "context" + "fmt" "blazing/cool" @@ -13,6 +14,7 @@ import ( "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/util/gconv" ) func init() { @@ -31,38 +33,109 @@ func init() { cool.FillInitData(ctx, "base", &model.BaseSysRoleDepartment{}) cool.FillInitData(ctx, "base", &model.BaseSysParam{}) cool.FillInitData(ctx, "base", &model.BaseSysConf{}) - g.DB("default").Exec(context.Background(), `CREATE OR REPLACE FUNCTION reset_all_sequences() -RETURNS void AS $$ -DECLARE - seq_record record; -BEGIN - FOR seq_record IN - SELECT - 'SELECT SETVAL(' || - quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) || - ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' || - quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';' AS sql - FROM - pg_class AS S, - pg_depend AS D, - pg_class AS T, - pg_attribute AS C, - pg_tables AS PGT - WHERE - S.relkind = 'S' - AND S.oid = D.objid - AND D.refobjid = T.oid - AND D.refobjid = C.attrelid - AND D.refobjsubid = C.attnum - AND T.relname = PGT.tablename - LOOP - EXECUTE seq_record.sql; - END LOOP; -END; -$$ LANGUAGE plpgsql; + ResetAllSequences(ctx) + // g.DB("default").Exec(context.Background(), `CREATE OR REPLACE FUNCTION reset_all_sequences() + // RETURNS void AS $$ + // DECLARE + // seq_record record; + // BEGIN + // FOR seq_record IN + // SELECT + // 'SELECT SETVAL(' || + // quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) || + // ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' || + // quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';' AS sql + // FROM + // pg_class AS S, + // pg_depend AS D, + // pg_class AS T, + // pg_attribute AS C, + // pg_tables AS PGT + // WHERE + // S.relkind = 'S' + // AND S.oid = D.objid + // AND D.refobjid = T.oid + // AND D.refobjid = C.attrelid + // AND D.refobjsubid = C.attnum + // AND T.relname = PGT.tablename + // LOOP + // EXECUTE seq_record.sql; + // END LOOP; + // END; + // $$ LANGUAGE plpgsql; --- 执行函数 -SELECT reset_all_sequences();`, nil) //重置所有序列 + // -- 执行函数 + // SELECT reset_all_sequences();`, nil) //重置所有序列 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 +}