// Package database define database operation functions package database import ( "context" "time" "modelRT/diagram" "modelRT/orm" "github.com/gofrs/uuid" "go.uber.org/zap" "gorm.io/gorm/clause" ) var recursiveSQL = `WITH RECURSIVE recursive_tree as ( SELECT uuid_from,uuid_to,page_id,flag FROM "Topologic" WHERE uuid_from is null and page_id = ? UNION ALL SELECT t.uuid_from,t.uuid_to,t.page_id,t.flag FROM "Topologic" t JOIN recursive_tree rt ON t.uuid_from = rt.uuid_to ) SELECT * FROM recursive_tree;` // QueryTopologicByPageID return the topologic info of the circuit diagram query by pageID func QueryTopologicByPageID(ctx context.Context, logger *zap.Logger, pageID int64) ([]orm.Topologic, error) { var topologics []orm.Topologic // ctx超时判断 cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() result := _globalPostgresClient.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Raw(recursiveSQL, pageID).Scan(&topologics) if result.Error != nil { logger.Error("query circuit diagram topologic info by pageID failed", zap.Int64("pageID", pageID), zap.Error(result.Error)) return nil, result.Error } return topologics, nil } // InitCircuitDiagramTopologic return circuit diagram topologic info from postgres func InitCircuitDiagramTopologic(pageID int64, topologicNodes []orm.Topologic) error { var rootVertex uuid.UUID for _, node := range topologicNodes { if node.UUIDFrom.IsNil() { rootVertex = node.UUIDTo break } } topologicSet := diagram.NewGraph(rootVertex) for _, node := range topologicNodes { if node.UUIDFrom.IsNil() { continue } topologicSet.AddEdge(node.UUIDFrom, node.UUIDTo) } diagram.DiagramsOverview.Store(pageID, topologicSet) return nil } // QueryTopologicFromDB return the result of query topologic info from postgresDB func QueryTopologicFromDB(ctx context.Context, logger *zap.Logger, gridID, zoneID, stationID int64) error { allPages, err := QueryAllPages(ctx, logger, gridID, zoneID, stationID) if err != nil { logger.Error("query all pages info failed", zap.Int64("gridID", gridID), zap.Int64("zoneID", zoneID), zap.Int64("stationID", stationID), zap.Error(err)) return err } for _, page := range allPages { topologicInfos, err := QueryTopologicByPageID(ctx, logger, page.ID) if err != nil { logger.Error("query topologic info by pageID failed", zap.Int64("pageID", page.ID), zap.Error(err)) return err } err = InitCircuitDiagramTopologic(page.ID, topologicInfos) if err != nil { logger.Error("init topologic failed", zap.Error(err)) return err } } return nil }