refactor(orm/circuit_diagram_component): fix compilation issues caused by structure field changes
http://server.baseware.net:9000/project/datart/task/47
This commit is contained in:
parent
f7a1ea2540
commit
f4ab4e4ea4
|
|
@ -16,11 +16,11 @@ var (
|
||||||
|
|
||||||
// Event define alert event struct
|
// Event define alert event struct
|
||||||
type Event struct {
|
type Event struct {
|
||||||
ComponentID int64
|
ComponentUUID string
|
||||||
AnchorName string
|
AnchorName string
|
||||||
Level constants.AlertLevel
|
Level constants.AlertLevel
|
||||||
Message string
|
Message string
|
||||||
StartTime int64
|
StartTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventManager define store and manager alert event struct
|
// EventManager define store and manager alert event struct
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ type AnchorParamListConfig struct {
|
||||||
|
|
||||||
// AnchorParamBaseConfig define anchor params base config struct
|
// AnchorParamBaseConfig define anchor params base config struct
|
||||||
type AnchorParamBaseConfig struct {
|
type AnchorParamBaseConfig struct {
|
||||||
ComponentID int64 // component表 ID
|
ComponentUUID string // componentUUID
|
||||||
AnchorName string // 锚定参量名称
|
AnchorName string // 锚定参量名称
|
||||||
CompareValUpperLimit float64 // 比较值上限
|
CompareValUpperLimit float64 // 比较值上限
|
||||||
CompareValLowerLimit float64 // 比较值下限
|
CompareValLowerLimit float64 // 比较值下限
|
||||||
|
|
|
||||||
|
|
@ -16,26 +16,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateComponentIntoDB define create component info of the circuit diagram into DB
|
// CreateComponentIntoDB define create component info of the circuit diagram into DB
|
||||||
func CreateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo network.ComponentCreateInfo) (int64, error) {
|
func CreateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo network.ComponentCreateInfo) (string, error) {
|
||||||
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, fmt.Errorf("format uuid from string type failed:%w", err)
|
return "", fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
component := orm.Component{
|
component := orm.Component{
|
||||||
GlobalUUID: globalUUID,
|
GlobalUUID: globalUUID,
|
||||||
GridID: strconv.FormatInt(componentInfo.GridID, 10),
|
GridID: strconv.FormatInt(componentInfo.GridID, 10),
|
||||||
ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10),
|
ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10),
|
||||||
StationID: strconv.FormatInt(componentInfo.StationID, 10),
|
StationID: strconv.FormatInt(componentInfo.StationID, 10),
|
||||||
Tag: componentInfo.Tag,
|
Tag: componentInfo.Tag,
|
||||||
ComponentType: componentInfo.ComponentType,
|
Name: componentInfo.Name,
|
||||||
Name: componentInfo.Name,
|
Context: componentInfo.Context,
|
||||||
Context: componentInfo.Context,
|
Op: componentInfo.Op,
|
||||||
Op: componentInfo.Op,
|
Ts: time.Now(),
|
||||||
Ts: time.Now(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result := tx.WithContext(cancelCtx).Create(&component)
|
result := tx.WithContext(cancelCtx).Create(&component)
|
||||||
|
|
@ -44,7 +43,7 @@ func CreateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo netwo
|
||||||
if result.RowsAffected == 0 {
|
if result.RowsAffected == 0 {
|
||||||
err = fmt.Errorf("%w:please check insert component slice", errcode.ErrInsertRowUnexpected)
|
err = fmt.Errorf("%w:please check insert component slice", errcode.ErrInsertRowUnexpected)
|
||||||
}
|
}
|
||||||
return -1, fmt.Errorf("insert component info failed:%w", err)
|
return "", fmt.Errorf("insert component info failed:%w", err)
|
||||||
}
|
}
|
||||||
return component.ID, nil
|
return component.GlobalUUID.String(), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,42 +5,37 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"modelRT/config"
|
|
||||||
"modelRT/logger"
|
|
||||||
"modelRT/orm"
|
"modelRT/orm"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"github.com/panjf2000/ants/v2"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueryCircuitDiagramComponentFromDB return the result of query circuit diagram component info order by page id from postgresDB
|
// QueryCircuitDiagramComponentFromDB return the result of query circuit diagram component info order by page id from postgresDB
|
||||||
func QueryCircuitDiagramComponentFromDB(ctx context.Context, tx *gorm.DB, pool *ants.PoolWithFunc) (map[uuid.UUID]int, error) {
|
// func QueryCircuitDiagramComponentFromDB(ctx context.Context, tx *gorm.DB, pool *ants.PoolWithFunc) (map[uuid.UUID]string, error) {
|
||||||
var components []orm.Component
|
// var components []orm.Component
|
||||||
// ctx超时判断
|
// // ctx超时判断
|
||||||
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
// cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
defer cancel()
|
// defer cancel()
|
||||||
|
|
||||||
result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Find(&components)
|
// result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Find(&components)
|
||||||
if result.Error != nil {
|
// if result.Error != nil {
|
||||||
logger.Error(ctx, "query circuit diagram component info failed", "error", result.Error)
|
// logger.Error(ctx, "query circuit diagram component info failed", "error", result.Error)
|
||||||
return nil, result.Error
|
// return nil, result.Error
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TODO 优化componentTypeMap输出
|
// componentTypeMap := make(map[uuid.UUID]string, len(components))
|
||||||
componentTypeMap := make(map[uuid.UUID]int, len(components))
|
// for _, component := range components {
|
||||||
|
// pool.Invoke(config.ModelParseConfig{
|
||||||
|
// ComponentInfo: component,
|
||||||
|
// Ctx: ctx,
|
||||||
|
// })
|
||||||
|
|
||||||
for _, component := range components {
|
// componentTypeMap[component.GlobalUUID] = component.GlobalUUID.String()
|
||||||
pool.Invoke(config.ModelParseConfig{
|
// }
|
||||||
ComponentInfo: component,
|
// return componentTypeMap, nil
|
||||||
Ctx: ctx,
|
// }
|
||||||
})
|
|
||||||
|
|
||||||
componentTypeMap[component.GlobalUUID] = component.ComponentType
|
|
||||||
}
|
|
||||||
return componentTypeMap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryComponentByUUID return the result of query circuit diagram component info by uuid from postgresDB
|
// QueryComponentByUUID return the result of query circuit diagram component info by uuid from postgresDB
|
||||||
func QueryComponentByUUID(ctx context.Context, tx *gorm.DB, uuid uuid.UUID) (orm.Component, error) {
|
func QueryComponentByUUID(ctx context.Context, tx *gorm.DB, uuid uuid.UUID) (orm.Component, error) {
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,14 @@ func QueryTopologic(ctx context.Context, tx *gorm.DB) ([]orm.Topologic, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryTopologicFromDB return the result of query topologic info from DB
|
// QueryTopologicFromDB return the result of query topologic info from DB
|
||||||
func QueryTopologicFromDB(ctx context.Context, tx *gorm.DB, componentTypeMap map[uuid.UUID]int) (*diagram.MultiBranchTreeNode, error) {
|
func QueryTopologicFromDB(ctx context.Context, tx *gorm.DB) (*diagram.MultiBranchTreeNode, error) {
|
||||||
topologicInfos, err := QueryTopologic(ctx, tx)
|
topologicInfos, err := QueryTopologic(ctx, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "query topologic info failed", "error", err)
|
logger.Error(ctx, "query topologic info failed", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tree, err := BuildMultiBranchTree(topologicInfos, componentTypeMap)
|
tree, err := BuildMultiBranchTree(topologicInfos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "init topologic failed", "error", err)
|
logger.Error(ctx, "init topologic failed", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -49,17 +49,11 @@ func QueryTopologicFromDB(ctx context.Context, tx *gorm.DB, componentTypeMap map
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitCircuitDiagramTopologic return circuit diagram topologic info from postgres
|
// InitCircuitDiagramTopologic return circuit diagram topologic info from postgres
|
||||||
func InitCircuitDiagramTopologic(topologicNodes []orm.Topologic, componentTypeMap map[uuid.UUID]int) error {
|
func InitCircuitDiagramTopologic(topologicNodes []orm.Topologic) error {
|
||||||
var rootVertex *diagram.MultiBranchTreeNode
|
var rootVertex *diagram.MultiBranchTreeNode
|
||||||
for _, node := range topologicNodes {
|
for _, node := range topologicNodes {
|
||||||
if node.UUIDFrom == constants.UUIDNil {
|
if node.UUIDFrom == constants.UUIDNil {
|
||||||
// rootVertex = node.UUIDTo
|
rootVertex = diagram.NewMultiBranchTree(node.UUIDFrom)
|
||||||
var componentType int
|
|
||||||
componentType, ok := componentTypeMap[node.UUIDFrom]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("can not get component type by uuid: %s", node.UUIDFrom)
|
|
||||||
}
|
|
||||||
rootVertex = diagram.NewMultiBranchTree(node.UUIDFrom, componentType)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,13 +64,7 @@ func InitCircuitDiagramTopologic(topologicNodes []orm.Topologic, componentTypeMa
|
||||||
|
|
||||||
for _, node := range topologicNodes {
|
for _, node := range topologicNodes {
|
||||||
if node.UUIDFrom == constants.UUIDNil {
|
if node.UUIDFrom == constants.UUIDNil {
|
||||||
var componentType int
|
nodeVertex := diagram.NewMultiBranchTree(node.UUIDTo)
|
||||||
componentType, ok := componentTypeMap[node.UUIDTo]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("can not get component type by uuid: %s", node.UUIDTo)
|
|
||||||
}
|
|
||||||
nodeVertex := diagram.NewMultiBranchTree(node.UUIDTo, componentType)
|
|
||||||
|
|
||||||
rootVertex.AddChild(nodeVertex)
|
rootVertex.AddChild(nodeVertex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,9 +79,7 @@ func InitCircuitDiagramTopologic(topologicNodes []orm.Topologic, componentTypeMa
|
||||||
|
|
||||||
// TODO 电流互感器不单独划分间隔,以母线、浇筑母线、变压器为间隔原件
|
// TODO 电流互感器不单独划分间隔,以母线、浇筑母线、变压器为间隔原件
|
||||||
func IntervalBoundaryDetermine(uuid uuid.UUID) bool {
|
func IntervalBoundaryDetermine(uuid uuid.UUID) bool {
|
||||||
fmt.Println(uuid)
|
diagram.GetComponentMap(uuid.String())
|
||||||
var componentID int64
|
|
||||||
diagram.GetComponentMap(componentID)
|
|
||||||
// TODO 判断 component 的类型是否为间隔
|
// TODO 判断 component 的类型是否为间隔
|
||||||
// TODO 0xA1B2C3D4,高四位表示可以成为间隔的compoent类型的值为FFFF,普通 component 类型的值为 0000。低四位中前二位表示component的一级类型,例如母线 PT、母联/母分、进线等,低四位中后二位表示一级类型中包含的具体类型,例如母线 PT中包含的电压互感器、隔离开关、接地开关、避雷器、带电显示器等。
|
// TODO 0xA1B2C3D4,高四位表示可以成为间隔的compoent类型的值为FFFF,普通 component 类型的值为 0000。低四位中前二位表示component的一级类型,例如母线 PT、母联/母分、进线等,低四位中后二位表示一级类型中包含的具体类型,例如母线 PT中包含的电压互感器、隔离开关、接地开关、避雷器、带电显示器等。
|
||||||
num := uint32(0xA1B2C3D4) // 八位16进制数
|
num := uint32(0xA1B2C3D4) // 八位16进制数
|
||||||
|
|
@ -104,23 +90,16 @@ func IntervalBoundaryDetermine(uuid uuid.UUID) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildMultiBranchTree return the multi branch tree by topologic info and component type map
|
// BuildMultiBranchTree return the multi branch tree by topologic info and component type map
|
||||||
func BuildMultiBranchTree(topologics []orm.Topologic, componentTypeMap map[uuid.UUID]int) (*diagram.MultiBranchTreeNode, error) {
|
func BuildMultiBranchTree(topologics []orm.Topologic) (*diagram.MultiBranchTreeNode, error) {
|
||||||
nodeMap := make(map[uuid.UUID]*diagram.MultiBranchTreeNode, len(topologics)*2)
|
nodeMap := make(map[uuid.UUID]*diagram.MultiBranchTreeNode, len(topologics)*2)
|
||||||
|
|
||||||
for _, topo := range topologics {
|
for _, topo := range topologics {
|
||||||
if _, exists := nodeMap[topo.UUIDFrom]; !exists {
|
if _, exists := nodeMap[topo.UUIDFrom]; !exists {
|
||||||
// skip special uuid
|
// skip special uuid
|
||||||
if topo.UUIDTo != constants.UUIDNil {
|
if topo.UUIDTo != constants.UUIDNil {
|
||||||
var ok bool
|
|
||||||
componentType, ok := componentTypeMap[topo.UUIDFrom]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("can not get component type by uuid: %s", topo.UUIDFrom)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeMap[topo.UUIDFrom] = &diagram.MultiBranchTreeNode{
|
nodeMap[topo.UUIDFrom] = &diagram.MultiBranchTreeNode{
|
||||||
ID: topo.UUIDFrom,
|
ID: topo.UUIDFrom,
|
||||||
NodeComponentType: componentType,
|
Children: make([]*diagram.MultiBranchTreeNode, 0),
|
||||||
Children: make([]*diagram.MultiBranchTreeNode, 0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -128,16 +107,9 @@ func BuildMultiBranchTree(topologics []orm.Topologic, componentTypeMap map[uuid.
|
||||||
if _, exists := nodeMap[topo.UUIDTo]; !exists {
|
if _, exists := nodeMap[topo.UUIDTo]; !exists {
|
||||||
// skip special uuid
|
// skip special uuid
|
||||||
if topo.UUIDTo != constants.UUIDNil {
|
if topo.UUIDTo != constants.UUIDNil {
|
||||||
var ok bool
|
|
||||||
componentType, ok := componentTypeMap[topo.UUIDTo]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("can not get component type by uuid: %s", topo.UUIDTo)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeMap[topo.UUIDTo] = &diagram.MultiBranchTreeNode{
|
nodeMap[topo.UUIDTo] = &diagram.MultiBranchTreeNode{
|
||||||
ID: topo.UUIDTo,
|
ID: topo.UUIDTo,
|
||||||
NodeComponentType: componentType,
|
Children: make([]*diagram.MultiBranchTreeNode, 0),
|
||||||
Children: make([]*diagram.MultiBranchTreeNode, 0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,10 +118,8 @@ func BuildMultiBranchTree(topologics []orm.Topologic, componentTypeMap map[uuid.
|
||||||
for _, topo := range topologics {
|
for _, topo := range topologics {
|
||||||
var parent *diagram.MultiBranchTreeNode
|
var parent *diagram.MultiBranchTreeNode
|
||||||
if topo.UUIDFrom == constants.UUIDNil {
|
if topo.UUIDFrom == constants.UUIDNil {
|
||||||
var componentType int
|
|
||||||
parent = &diagram.MultiBranchTreeNode{
|
parent = &diagram.MultiBranchTreeNode{
|
||||||
ID: constants.UUIDNil,
|
ID: constants.UUIDNil,
|
||||||
NodeComponentType: componentType,
|
|
||||||
}
|
}
|
||||||
nodeMap[constants.UUIDNil] = parent
|
nodeMap[constants.UUIDNil] = parent
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -158,10 +128,8 @@ func BuildMultiBranchTree(topologics []orm.Topologic, componentTypeMap map[uuid.
|
||||||
|
|
||||||
var child *diagram.MultiBranchTreeNode
|
var child *diagram.MultiBranchTreeNode
|
||||||
if topo.UUIDTo == constants.UUIDNil {
|
if topo.UUIDTo == constants.UUIDNil {
|
||||||
var componentType int
|
|
||||||
child = &diagram.MultiBranchTreeNode{
|
child = &diagram.MultiBranchTreeNode{
|
||||||
ID: topo.UUIDTo,
|
ID: topo.UUIDTo,
|
||||||
NodeComponentType: componentType,
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
child = nodeMap[topo.UUIDTo]
|
child = nodeMap[topo.UUIDTo]
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateComponentIntoDB define update component info of the circuit diagram into DB
|
// UpdateComponentIntoDB define update component info of the circuit diagram into DB
|
||||||
func UpdateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo network.ComponentUpdateInfo) (int64, error) {
|
func UpdateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo network.ComponentUpdateInfo) (string, error) {
|
||||||
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
globalUUID, err := uuid.FromString(componentInfo.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, fmt.Errorf("format uuid from string type failed:%w", err)
|
return "", fmt.Errorf("format uuid from string type failed:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var component orm.Component
|
var component orm.Component
|
||||||
|
|
@ -32,30 +32,29 @@ func UpdateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo netwo
|
||||||
if result.RowsAffected == 0 {
|
if result.RowsAffected == 0 {
|
||||||
err = fmt.Errorf("%w:please check update component conditions", errcode.ErrUpdateRowZero)
|
err = fmt.Errorf("%w:please check update component conditions", errcode.ErrUpdateRowZero)
|
||||||
}
|
}
|
||||||
return -1, fmt.Errorf("query component info failed:%w", err)
|
return "", fmt.Errorf("query component info failed:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateParams := orm.Component{
|
updateParams := orm.Component{
|
||||||
GlobalUUID: globalUUID,
|
GlobalUUID: globalUUID,
|
||||||
GridID: strconv.FormatInt(componentInfo.GridID, 10),
|
GridID: strconv.FormatInt(componentInfo.GridID, 10),
|
||||||
ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10),
|
ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10),
|
||||||
StationID: strconv.FormatInt(componentInfo.StationID, 10),
|
StationID: strconv.FormatInt(componentInfo.StationID, 10),
|
||||||
Tag: componentInfo.Tag,
|
Tag: componentInfo.Tag,
|
||||||
ComponentType: componentInfo.ComponentType,
|
Name: componentInfo.Name,
|
||||||
Name: componentInfo.Name,
|
Context: componentInfo.Context,
|
||||||
Context: componentInfo.Context,
|
Op: componentInfo.Op,
|
||||||
Op: componentInfo.Op,
|
Ts: time.Now(),
|
||||||
Ts: time.Now(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tx.Model(&orm.Component{}).WithContext(cancelCtx).Where("id = ?", component.ID).Updates(&updateParams)
|
result = tx.Model(&orm.Component{}).WithContext(cancelCtx).Where("GLOBAL_UUID = ?", component.GlobalUUID).Updates(&updateParams)
|
||||||
|
|
||||||
if result.Error != nil || result.RowsAffected == 0 {
|
if result.Error != nil || result.RowsAffected == 0 {
|
||||||
err := result.Error
|
err := result.Error
|
||||||
if result.RowsAffected == 0 {
|
if result.RowsAffected == 0 {
|
||||||
err = fmt.Errorf("%w:please check update component conditions", errcode.ErrUpdateRowZero)
|
err = fmt.Errorf("%w:please check update component conditions", errcode.ErrUpdateRowZero)
|
||||||
}
|
}
|
||||||
return -1, fmt.Errorf("update component info failed:%w", err)
|
return "", fmt.Errorf("update component info failed:%w", err)
|
||||||
}
|
}
|
||||||
return component.ID, nil
|
return component.GlobalUUID.String(), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import (
|
||||||
var anchorValueOverview sync.Map
|
var anchorValueOverview sync.Map
|
||||||
|
|
||||||
// GetAnchorValue define func of get circuit diagram data by componentID
|
// GetAnchorValue define func of get circuit diagram data by componentID
|
||||||
func GetAnchorValue(componentID int64) (string, error) {
|
func GetAnchorValue(componentUUID string) (string, error) {
|
||||||
value, ok := diagramsOverview.Load(componentID)
|
value, ok := diagramsOverview.Load(componentUUID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("can not find anchor value by componentID:%d", componentID)
|
return "", fmt.Errorf("can not find anchor value by componentUUID:%s", componentUUID)
|
||||||
}
|
}
|
||||||
anchorValue, ok := value.(string)
|
anchorValue, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -22,20 +22,20 @@ func GetAnchorValue(componentID int64) (string, error) {
|
||||||
return anchorValue, nil
|
return anchorValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAnchorValue define func of update anchor value by componentID and anchor name
|
// UpdateAnchorValue define func of update anchor value by componentUUID and anchor name
|
||||||
func UpdateAnchorValue(componentID int64, anchorValue string) bool {
|
func UpdateAnchorValue(componentUUID string, anchorValue string) bool {
|
||||||
_, result := anchorValueOverview.Swap(componentID, anchorValue)
|
_, result := anchorValueOverview.Swap(componentUUID, anchorValue)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreAnchorValue define func of store anchor value with componentID and anchor name
|
// StoreAnchorValue define func of store anchor value with componentUUID and anchor name
|
||||||
func StoreAnchorValue(componentID int64, anchorValue string) {
|
func StoreAnchorValue(componentUUID string, anchorValue string) {
|
||||||
anchorValueOverview.Store(componentID, anchorValue)
|
anchorValueOverview.Store(componentUUID, anchorValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAnchorValue define func of delete anchor value with componentID
|
// DeleteAnchorValue define func of delete anchor value with componentUUID
|
||||||
func DeleteAnchorValue(componentID int64) {
|
func DeleteAnchorValue(componentUUID string) {
|
||||||
anchorValueOverview.Delete(componentID)
|
anchorValueOverview.Delete(componentUUID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,38 +4,40 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"modelRT/orm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// diagramsOverview define struct of storage all circuit diagram data
|
// diagramsOverview define struct of storage all circuit diagram data
|
||||||
var diagramsOverview sync.Map
|
var diagramsOverview sync.Map
|
||||||
|
|
||||||
// GetComponentMap define func of get circuit diagram data by component id
|
// GetComponentMap define func of get circuit diagram data by component uuid
|
||||||
func GetComponentMap(componentID int64) (map[string]interface{}, error) {
|
func GetComponentMap(componentUUID string) (*orm.Component, error) {
|
||||||
value, ok := diagramsOverview.Load(componentID)
|
value, ok := diagramsOverview.Load(componentUUID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("can not find graph by global uuid:%d", componentID)
|
return nil, fmt.Errorf("can not find graph by global uuid:%s", componentUUID)
|
||||||
}
|
}
|
||||||
paramsMap, ok := value.(map[string]interface{})
|
componentInfo, ok := value.(*orm.Component)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("convert to component map struct failed")
|
return nil, errors.New("convert to component map struct failed")
|
||||||
}
|
}
|
||||||
return paramsMap, nil
|
return componentInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateComponentMap define func of update circuit diagram data by component id and component info
|
// UpdateComponentMap define func of update circuit diagram data by component uuid and component info
|
||||||
func UpdateComponentMap(componentID int64, componentInfo map[string]interface{}) bool {
|
func UpdateComponentMap(componentID int64, componentInfo *orm.Component) bool {
|
||||||
_, result := diagramsOverview.Swap(componentID, componentInfo)
|
_, result := diagramsOverview.Swap(componentID, componentInfo)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreComponentMap define func of store circuit diagram data with component id and component info
|
// StoreComponentMap define func of store circuit diagram data with component uuid and component info
|
||||||
func StoreComponentMap(componentID int64, componentInfo map[string]interface{}) {
|
func StoreComponentMap(componentUUID string, componentInfo *orm.Component) {
|
||||||
diagramsOverview.Store(componentID, componentInfo)
|
diagramsOverview.Store(componentUUID, componentInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteComponentMap define func of delete circuit diagram data with component id
|
// DeleteComponentMap define func of delete circuit diagram data with component uuid
|
||||||
func DeleteComponentMap(componentID int64) {
|
func DeleteComponentMap(componentUUID string) {
|
||||||
diagramsOverview.Delete(componentID)
|
diagramsOverview.Delete(componentUUID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,15 @@ var GlobalTree *MultiBranchTreeNode
|
||||||
|
|
||||||
// MultiBranchTreeNode represents a topological structure using an multi branch tree
|
// MultiBranchTreeNode represents a topological structure using an multi branch tree
|
||||||
type MultiBranchTreeNode struct {
|
type MultiBranchTreeNode struct {
|
||||||
ID uuid.UUID // 节点唯一标识
|
ID uuid.UUID // 节点唯一标识
|
||||||
NodeComponentType int // 节点组件类型
|
Parent *MultiBranchTreeNode // 指向父节点的指针
|
||||||
Parent *MultiBranchTreeNode // 指向父节点的指针
|
Children []*MultiBranchTreeNode // 指向所有子节点的指针切片
|
||||||
Children []*MultiBranchTreeNode // 指向所有子节点的指针切片
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMultiBranchTree(id uuid.UUID, componentType int) *MultiBranchTreeNode {
|
func NewMultiBranchTree(id uuid.UUID) *MultiBranchTreeNode {
|
||||||
return &MultiBranchTreeNode{
|
return &MultiBranchTreeNode{
|
||||||
ID: id,
|
ID: id,
|
||||||
NodeComponentType: componentType,
|
Children: make([]*MultiBranchTreeNode, 0),
|
||||||
Children: make([]*MultiBranchTreeNode, 0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +56,7 @@ func (n *MultiBranchTreeNode) PrintTree(level int) {
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("- ComponentType:%d,(ID: %s)\n", n.NodeComponentType, n.ID)
|
fmt.Printf("-ID: %s\n", n.ID)
|
||||||
|
|
||||||
for _, child := range n.Children {
|
for _, child := range n.Children {
|
||||||
child.PrintTree(level + 1)
|
child.PrintTree(level + 1)
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"modelRT/common/errcode"
|
"modelRT/common/errcode"
|
||||||
"modelRT/constants"
|
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
"modelRT/model"
|
|
||||||
"modelRT/network"
|
"modelRT/network"
|
||||||
"modelRT/orm"
|
"modelRT/orm"
|
||||||
|
|
||||||
|
|
@ -65,40 +63,7 @@ func ComponentAnchorReplaceHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
diagram.UpdateAnchorValue(componentInfo.GlobalUUID.String(), anchorName)
|
||||||
cancelCtx, cancel = context.WithTimeout(c, 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
unmarshalMap := make(map[string]interface{})
|
|
||||||
tableName := model.SelectModelNameByType(componentInfo.ComponentType)
|
|
||||||
result = pgClient.WithContext(cancelCtx).Table(tableName).Where("global_uuid = ?", uuid).Find(&unmarshalMap)
|
|
||||||
if result.Error != nil {
|
|
||||||
logger.Error(c, "query model detail info failed", "error", result.Error)
|
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
Msg: result.Error.Error(),
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if unmarshalMap == nil {
|
|
||||||
err := fmt.Errorf("query model detail info by uuid failed:%w", errcode.ErrQueryRowZero)
|
|
||||||
logger.Error(c, "query model detail info from table is empty", "table_name", tableName)
|
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
Msg: err.Error(),
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
componentType := unmarshalMap["component_type"].(int)
|
|
||||||
if componentType != constants.DemoType {
|
|
||||||
logger.Error(c, "can not process real time data of component type not equal DemoType", "component_id", componentInfo.ID)
|
|
||||||
}
|
|
||||||
diagram.UpdateAnchorValue(componentInfo.ID, anchorName)
|
|
||||||
|
|
||||||
resp := network.SuccessResponse{
|
resp := network.SuccessResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
"modelRT/network"
|
"modelRT/network"
|
||||||
|
"modelRT/orm"
|
||||||
|
|
||||||
"github.com/bitly/go-simplejson"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
)
|
)
|
||||||
|
|
@ -102,8 +102,8 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
graph.AddEdge(topologicCreateInfo.UUIDFrom, topologicCreateInfo.UUIDTo)
|
graph.AddEdge(topologicCreateInfo.UUIDFrom, topologicCreateInfo.UUIDTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, componentInfo := range request.ComponentInfos {
|
for index, info := range request.ComponentInfos {
|
||||||
componentID, err := database.CreateComponentIntoDB(c, tx, componentInfo)
|
componentUUID, err := database.CreateComponentIntoDB(c, tx, info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
|
||||||
|
|
@ -119,64 +119,48 @@ func CircuitDiagramCreateHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
request.ComponentInfos[index].ID = componentID
|
request.ComponentInfos[index].UUID = componentUUID
|
||||||
|
|
||||||
err = database.CreateModelIntoDB(c, tx, componentID, componentInfo.ComponentType, componentInfo.Params)
|
|
||||||
if err != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
logger.Error(c, "create component model into DB failed", "component_infos", request.ComponentInfos, "error", err)
|
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
Msg: err.Error(),
|
|
||||||
PayLoad: map[string]interface{}{
|
|
||||||
"uuid": request.PageID,
|
|
||||||
"component_infos": request.ComponentInfos,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, componentInfo := range request.ComponentInfos {
|
for _, info := range request.ComponentInfos {
|
||||||
paramsJSON, err := simplejson.NewJson([]byte(componentInfo.Params))
|
component := &orm.Component{
|
||||||
if err != nil {
|
GlobalUUID: uuid.FromStringOrNil(info.UUID),
|
||||||
tx.Rollback()
|
// NsPath
|
||||||
|
// Tag string `gorm:"column:TAG"`
|
||||||
logger.Error(c, "unmarshal component params info failed", "component_params", componentInfo.Params, "error", err)
|
Name: info.Name,
|
||||||
|
// ModelName string `gorm:"column:MODEL_NAME"`
|
||||||
resp := network.FailureResponse{
|
// Description: info.Description,
|
||||||
Code: http.StatusBadRequest,
|
// GridID: info.GridID,
|
||||||
Msg: err.Error(),
|
// ZoneID: info.ZoneID,
|
||||||
PayLoad: map[string]interface{}{
|
// StationID: info.StationID,
|
||||||
"uuid": componentInfo.UUID,
|
// Type int `gorm:"column:TYPE"`
|
||||||
"component_params": componentInfo.Params,
|
// InService bool `gorm:"column:IN_SERVICE"`
|
||||||
},
|
// State int `gorm:"column:STATE"`
|
||||||
}
|
// Status int `gorm:"column:STATUS"`
|
||||||
c.JSON(http.StatusOK, resp)
|
// Connection map[string]interface{} `gorm:"column:CONNECTION;type:jsonb;default:'{}'"`
|
||||||
return
|
// Label map[string]interface{} `gorm:"column:LABEL;type:jsonb;default:'{}'"`
|
||||||
|
// Context string `gorm:"column:CONTEXT"`
|
||||||
|
// Op: info.Op,
|
||||||
|
// Ts: info.Ts,
|
||||||
}
|
}
|
||||||
|
// paramsJSON, err := simplejson.NewJson([]byte(info.Params))
|
||||||
|
// if err != nil {
|
||||||
|
// tx.Rollback()
|
||||||
|
|
||||||
componentMap, err := paramsJSON.Map()
|
// logger.Error(c, "unmarshal component params info failed", "component_params", info.Params, "error", err)
|
||||||
if err != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
logger.Error(c, "format params json info to map failed", "error", err)
|
// resp := network.FailureResponse{
|
||||||
|
// Code: http.StatusBadRequest,
|
||||||
resp := network.FailureResponse{
|
// Msg: err.Error(),
|
||||||
Code: http.StatusBadRequest,
|
// PayLoad: map[string]interface{}{
|
||||||
Msg: err.Error(),
|
// "uuid": info.UUID,
|
||||||
PayLoad: map[string]interface{}{
|
// "component_params": info.Params,
|
||||||
"uuid": componentInfo.UUID,
|
// },
|
||||||
"component_params": componentInfo.Params,
|
// }
|
||||||
},
|
// c.JSON(http.StatusOK, resp)
|
||||||
}
|
// return
|
||||||
c.JSON(http.StatusOK, resp)
|
// }
|
||||||
return
|
diagram.StoreComponentMap(info.UUID, component)
|
||||||
}
|
|
||||||
diagram.StoreComponentMap(componentInfo.ID, componentMap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(request.FreeVertexs) > 0 {
|
if len(request.FreeVertexs) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
"modelRT/model"
|
|
||||||
"modelRT/network"
|
"modelRT/network"
|
||||||
"modelRT/orm"
|
"modelRT/orm"
|
||||||
|
|
||||||
|
|
@ -192,32 +191,7 @@ func CircuitDiagramDeleteHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
diagram.DeleteComponentMap(component.GlobalUUID.String())
|
||||||
modelStruct := model.SelectModelByType(component.ComponentType)
|
|
||||||
modelStruct.SetComponentID(component.ID)
|
|
||||||
result = tx.WithContext(cancelCtx).Where("component_id = ?", component.ID).Delete(modelStruct)
|
|
||||||
if result.Error != nil || result.RowsAffected == 0 {
|
|
||||||
tx.Rollback()
|
|
||||||
|
|
||||||
err := result.Error
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
err = fmt.Errorf("%w:please check uuid conditions", errcode.ErrDeleteRowZero)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := fmt.Sprintf("delete component info from table %s failed", modelStruct.ReturnTableName())
|
|
||||||
logger.Error(c, msg, "component_global_uuid", componentInfo.UUID, "error", err)
|
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
Msg: err.Error(),
|
|
||||||
PayLoad: map[string]interface{}{
|
|
||||||
"uuid": componentInfo.UUID,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
diagram.DeleteComponentMap(component.ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(request.FreeVertexs) > 0 {
|
if len(request.FreeVertexs) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
componentParams, err := diagram.GetComponentMap(component.ID)
|
componentParams, err := diagram.GetComponentMap(component.GlobalUUID.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(c, "get component data from set by uuid failed", "error", err)
|
logger.Error(c, "get component data from set by uuid failed", "error", err)
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ func CircuitDiagramLoadHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rootComponentParam, err := diagram.GetComponentMap(rootComponent.ID)
|
rootComponentParam, err := diagram.GetComponentMap(rootComponent.GlobalUUID.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(c, "get component data from set by uuid failed", "error", err)
|
logger.Error(c, "get component data from set by uuid failed", "error", err)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,10 @@ import (
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
"modelRT/network"
|
"modelRT/network"
|
||||||
|
"modelRT/orm"
|
||||||
|
|
||||||
"github.com/bitly/go-simplejson"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CircuitDiagramUpdateHandler define circuit diagram update process API
|
// CircuitDiagramUpdateHandler define circuit diagram update process API
|
||||||
|
|
@ -103,7 +104,7 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, componentInfo := range request.ComponentInfos {
|
for index, componentInfo := range request.ComponentInfos {
|
||||||
componentID, err := database.UpdateComponentIntoDB(c, tx, componentInfo)
|
componentUUID, err := database.UpdateComponentIntoDB(c, tx, componentInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(c, "udpate component info into DB failed", "error", err)
|
logger.Error(c, "udpate component info into DB failed", "error", err)
|
||||||
|
|
||||||
|
|
@ -118,59 +119,47 @@ func CircuitDiagramUpdateHandler(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
request.ComponentInfos[index].UUID = componentUUID
|
||||||
request.ComponentInfos[index].ID = componentID
|
|
||||||
|
|
||||||
err = database.UpdateModelIntoDB(c, tx, componentID, componentInfo.ComponentType, componentInfo.Params)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(c, "udpate component model info into DB failed", "error", err)
|
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
Msg: err.Error(),
|
|
||||||
PayLoad: map[string]interface{}{
|
|
||||||
"page_id": request.PageID,
|
|
||||||
"component_info": request.ComponentInfos,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, componentInfo := range request.ComponentInfos {
|
for _, info := range request.ComponentInfos {
|
||||||
paramsJSON, err := simplejson.NewJson([]byte(componentInfo.Params))
|
component := &orm.Component{
|
||||||
if err != nil {
|
GlobalUUID: uuid.FromStringOrNil(info.UUID),
|
||||||
logger.Error(c, "unmarshal component info by concurrent map failed", "component_params", componentInfo.Params, "error", err)
|
// NsPath
|
||||||
|
// Tag string `gorm:"column:TAG"`
|
||||||
resp := network.FailureResponse{
|
Name: info.Name,
|
||||||
Code: http.StatusBadRequest,
|
// ModelName string `gorm:"column:MODEL_NAME"`
|
||||||
Msg: err.Error(),
|
// Description: info.Description,
|
||||||
PayLoad: map[string]interface{}{
|
// GridID: info.GridID,
|
||||||
"uuid": componentInfo.UUID,
|
// ZoneID: info.ZoneID,
|
||||||
"component_params": componentInfo.Params,
|
// StationID: info.StationID,
|
||||||
},
|
// Type int `gorm:"column:TYPE"`
|
||||||
}
|
// InService bool `gorm:"column:IN_SERVICE"`
|
||||||
c.JSON(http.StatusOK, resp)
|
// State int `gorm:"column:STATE"`
|
||||||
return
|
// Status int `gorm:"column:STATUS"`
|
||||||
|
// Connection map[string]interface{} `gorm:"column:CONNECTION;type:jsonb;default:'{}'"`
|
||||||
|
// Label map[string]interface{} `gorm:"column:LABEL;type:jsonb;default:'{}'"`
|
||||||
|
// Context string `gorm:"column:CONTEXT"`
|
||||||
|
Op: info.Op,
|
||||||
|
// Ts: info.Ts,
|
||||||
}
|
}
|
||||||
|
|
||||||
componentMap, err := paramsJSON.Map()
|
// paramsJSON, err := simplejson.NewJson([]byte(info.Params))
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
logger.Error(c, "format params json info to map failed", "error", err)
|
// logger.Error(c, "unmarshal component info by concurrent map failed", "component_params", info.Params, "error", err)
|
||||||
|
|
||||||
resp := network.FailureResponse{
|
// resp := network.FailureResponse{
|
||||||
Code: http.StatusBadRequest,
|
// Code: http.StatusBadRequest,
|
||||||
Msg: err.Error(),
|
// Msg: err.Error(),
|
||||||
PayLoad: map[string]interface{}{
|
// PayLoad: map[string]interface{}{
|
||||||
"uuid": componentInfo.UUID,
|
// "uuid": info.UUID,
|
||||||
"component_params": componentInfo.Params,
|
// "component_params": info.Params,
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
c.JSON(http.StatusOK, resp)
|
// c.JSON(http.StatusOK, resp)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
diagram.UpdateComponentMap(componentInfo.ID, componentMap)
|
diagram.UpdateComponentMap(info.ID, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(request.FreeVertexs) > 0 {
|
if len(request.FreeVertexs) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ func RealTimeDataReceivehandler(c *gin.Context) {
|
||||||
realtimedata.RealTimeDataChan <- request
|
realtimedata.RealTimeDataChan <- request
|
||||||
|
|
||||||
payload := map[string]interface{}{
|
payload := map[string]interface{}{
|
||||||
"component_id": request.PayLoad.ComponentID,
|
"component_uuid": request.PayLoad.ComponentUUID,
|
||||||
"point": request.PayLoad.Point,
|
"point": request.PayLoad.Point,
|
||||||
}
|
}
|
||||||
respByte := processResponse(0, "success", payload)
|
respByte := processResponse(0, "success", payload)
|
||||||
if len(respByte) == 0 {
|
if len(respByte) == 0 {
|
||||||
|
|
|
||||||
12
main.go
12
main.go
|
|
@ -102,14 +102,14 @@ func main() {
|
||||||
|
|
||||||
postgresDBClient.Transaction(func(tx *gorm.DB) error {
|
postgresDBClient.Transaction(func(tx *gorm.DB) error {
|
||||||
// load circuit diagram from postgres
|
// load circuit diagram from postgres
|
||||||
componentTypeMap, err := database.QueryCircuitDiagramComponentFromDB(cancelCtx, tx, parsePool)
|
// componentTypeMap, err := database.QueryCircuitDiagramComponentFromDB(cancelCtx, tx, parsePool)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
logger.Error(ctx, "load circuit diagrams from postgres failed", "error", err)
|
// logger.Error(ctx, "load circuit diagrams from postgres failed", "error", err)
|
||||||
panic(err)
|
// panic(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TODO 暂时屏蔽完成 swagger 启动测试
|
// TODO 暂时屏蔽完成 swagger 启动测试
|
||||||
tree, err := database.QueryTopologicFromDB(ctx, tx, componentTypeMap)
|
tree, err := database.QueryTopologicFromDB(ctx, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "load topologic info from postgres failed", "error", err)
|
logger.Error(ctx, "load topologic info from postgres failed", "error", err)
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,16 @@ type TopologicUUIDCreateInfo struct {
|
||||||
|
|
||||||
// ComponentCreateInfo defines circuit diagram component create index info
|
// ComponentCreateInfo defines circuit diagram component create index info
|
||||||
type ComponentCreateInfo struct {
|
type ComponentCreateInfo struct {
|
||||||
ID int64 `json:"id"`
|
UUID string `json:"uuid"`
|
||||||
UUID string `json:"uuid"`
|
Name string `json:"name"`
|
||||||
Name string `json:"name"`
|
Context string `json:"context"`
|
||||||
Context string `json:"context"`
|
GridID int64 `json:"grid_id"`
|
||||||
GridID int64 `json:"grid_id"`
|
ZoneID int64 `json:"zone_id"`
|
||||||
ZoneID int64 `json:"zone_id"`
|
StationID int64 `json:"station_id"`
|
||||||
StationID int64 `json:"station_id"`
|
PageID int64 `json:"page_id"`
|
||||||
PageID int64 `json:"page_id"`
|
Tag string `json:"tag"`
|
||||||
Tag string `json:"tag"`
|
Params string `json:"params"`
|
||||||
ComponentType int `json:"component_type"`
|
Op int `json:"op"`
|
||||||
Params string `json:"params"`
|
|
||||||
Op int `json:"op"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CircuitDiagramCreateRequest defines request params of circuit diagram create api
|
// CircuitDiagramCreateRequest defines request params of circuit diagram create api
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,16 @@ type TopologicUUIDChangeInfos struct {
|
||||||
|
|
||||||
// ComponentUpdateInfo defines circuit diagram component params info
|
// ComponentUpdateInfo defines circuit diagram component params info
|
||||||
type ComponentUpdateInfo struct {
|
type ComponentUpdateInfo struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
UUID string `json:"uuid"`
|
UUID string `json:"uuid"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Context string `json:"context"`
|
Context string `json:"context"`
|
||||||
GridID int64 `json:"grid_id"`
|
GridID int64 `json:"grid_id"`
|
||||||
ZoneID int64 `json:"zone_id"`
|
ZoneID int64 `json:"zone_id"`
|
||||||
StationID int64 `json:"station_id"`
|
StationID int64 `json:"station_id"`
|
||||||
ComponentType int `json:"component_type"`
|
Params string `json:"params"`
|
||||||
Params string `json:"params"`
|
Op int `json:"op"`
|
||||||
Op int `json:"op"`
|
Tag string `json:"tag"`
|
||||||
Tag string `json:"tag"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CircuitDiagramUpdateRequest defines request params of circuit diagram update api
|
// CircuitDiagramUpdateRequest defines request params of circuit diagram update api
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ type RealTimeDataReceiveRequest struct {
|
||||||
|
|
||||||
// RealTimeDataReceivePayload defines request payload of real time data receive api
|
// RealTimeDataReceivePayload defines request payload of real time data receive api
|
||||||
type RealTimeDataReceivePayload struct {
|
type RealTimeDataReceivePayload struct {
|
||||||
ComponentID int64 `json:"component_id"`
|
ComponentUUID string `json:"component_uuid"`
|
||||||
Point string `json:"point"`
|
Point string `json:"point"`
|
||||||
Values []RealTimeDataReceiveParam `json:"values"`
|
Values []RealTimeDataReceiveParam `json:"values"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RealTimeDataReceiveParam defines request param of real time data receive api
|
// RealTimeDataReceiveParam defines request param of real time data receive api
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package orm define database data struct
|
||||||
package orm
|
package orm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@ type Component struct {
|
||||||
Context string `gorm:"column:CONTEXT"`
|
Context string `gorm:"column:CONTEXT"`
|
||||||
Op int `gorm:"column:OP"`
|
Op int `gorm:"column:OP"`
|
||||||
Ts time.Time `gorm:"column:TS"`
|
Ts time.Time `gorm:"column:TS"`
|
||||||
|
|
||||||
// TODO 解决删除ID、ComponentType 后的报错
|
|
||||||
ID int64 `gorm:"column:id;primaryKey"`
|
|
||||||
ComponentType int `gorm:"column:TYPE"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName func respresent return table name of Component
|
// TableName func respresent return table name of Component
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package pool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"modelRT/config"
|
"modelRT/config"
|
||||||
|
|
@ -13,7 +14,10 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var globalComponentChanSet *ComponentChanSet
|
var (
|
||||||
|
globalComponentChanMap sync.Map
|
||||||
|
globalComponentChanSet *ComponentChanSet
|
||||||
|
)
|
||||||
|
|
||||||
// ComponentChanSet defines component anchor real time data process channel set
|
// ComponentChanSet defines component anchor real time data process channel set
|
||||||
type ComponentChanSet struct {
|
type ComponentChanSet struct {
|
||||||
|
|
@ -21,36 +25,21 @@ type ComponentChanSet struct {
|
||||||
AnchorChans []chan config.AnchorParamConfig
|
AnchorChans []chan config.AnchorParamConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetComponentChan(ctx context.Context, componentID int64) chan config.AnchorParamConfig {
|
func GetAnchorParamChan(ctx context.Context, componentUUID string) (chan config.AnchorParamConfig, error) {
|
||||||
globalComponentChanSet.RLock()
|
paramChan, ok := globalComponentChanMap.Load(componentUUID)
|
||||||
componentChan := globalComponentChanSet.AnchorChans[componentID]
|
if !ok {
|
||||||
if componentChan == nil {
|
return CreateNewAnchorParamChan(ctx, componentUUID), nil
|
||||||
globalComponentChanSet.RUnlock()
|
|
||||||
globalComponentChanSet.Lock()
|
|
||||||
defer globalComponentChanSet.Unlock()
|
|
||||||
return CreateNewComponentChan(ctx, componentID)
|
|
||||||
}
|
}
|
||||||
globalComponentChanSet.RUnlock()
|
|
||||||
return componentChan
|
anchorParamChan, ok := paramChan.(chan config.AnchorParamConfig)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("conversion component anchor param chan type failed for componentUUID: %s", componentUUID)
|
||||||
|
}
|
||||||
|
return anchorParamChan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateNewComponentChan(ctx context.Context, componentID int64) chan config.AnchorParamConfig {
|
func CreateNewAnchorParamChan(ctx context.Context, componentUUID string) chan config.AnchorParamConfig {
|
||||||
componentChan := globalComponentChanSet.AnchorChans[componentID]
|
anchorParamChan := make(chan config.AnchorParamConfig, 100)
|
||||||
if componentChan == nil {
|
globalComponentChanMap.Store(componentUUID, anchorParamChan)
|
||||||
componentChan = make(chan config.AnchorParamConfig, 100)
|
return anchorParamChan
|
||||||
globalComponentChanSet.AnchorChans[componentID] = componentChan
|
|
||||||
|
|
||||||
readyChan := make(chan struct{})
|
|
||||||
chanConfig := config.AnchorChanConfig{
|
|
||||||
Ctx: ctx,
|
|
||||||
AnchorChan: componentChan,
|
|
||||||
ReadyChan: readyChan,
|
|
||||||
}
|
|
||||||
|
|
||||||
AnchorRealTimePool.Invoke(chanConfig)
|
|
||||||
|
|
||||||
<-readyChan
|
|
||||||
return componentChan
|
|
||||||
}
|
|
||||||
return componentChan
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,13 @@ var AnchorFunc = func(poolConfig interface{}) {
|
||||||
firstStart = false
|
firstStart = false
|
||||||
}
|
}
|
||||||
|
|
||||||
componentID := anchorParaConfig.ComponentID
|
componentUUID := anchorParaConfig.ComponentUUID
|
||||||
anchorRealTimeDatas := anchorParaConfig.AnchorRealTimeData
|
anchorRealTimeDatas := anchorParaConfig.AnchorRealTimeData
|
||||||
|
|
||||||
for _, value := range anchorRealTimeDatas {
|
for _, value := range anchorRealTimeDatas {
|
||||||
anchorName, err := diagram.GetAnchorValue(componentID)
|
anchorName, err := diagram.GetAnchorValue(componentUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(anchorChanConfig.Ctx, "can not get anchor value from map by uuid", "component_id", componentID, "error", err)
|
logger.Error(anchorChanConfig.Ctx, "can not get anchor value from map by uuid", "component_uuid", componentUUID, "error", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,11 +70,11 @@ var AnchorFunc = func(poolConfig interface{}) {
|
||||||
message := fmt.Sprintf("anchor param %s value out of range, value:%f, upper limit:%f, lower limit:%f", anchorName,
|
message := fmt.Sprintf("anchor param %s value out of range, value:%f, upper limit:%f, lower limit:%f", anchorName,
|
||||||
compareValue, upperLimitVal, lowerlimitVal)
|
compareValue, upperLimitVal, lowerlimitVal)
|
||||||
event := alert.Event{
|
event := alert.Event{
|
||||||
ComponentID: componentID,
|
ComponentUUID: componentUUID,
|
||||||
AnchorName: anchorName,
|
AnchorName: anchorName,
|
||||||
Level: constants.InfoAlertLevel,
|
Level: constants.InfoAlertLevel,
|
||||||
Message: message,
|
Message: message,
|
||||||
StartTime: time.Now().Unix(),
|
StartTime: time.Now().Unix(),
|
||||||
}
|
}
|
||||||
alertManager.AddEvent(event)
|
alertManager.AddEvent(event)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"modelRT/database"
|
"modelRT/database"
|
||||||
"modelRT/diagram"
|
"modelRT/diagram"
|
||||||
"modelRT/logger"
|
"modelRT/logger"
|
||||||
"modelRT/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseFunc defines func that parses the model data from postgres
|
// ParseFunc defines func that parses the model data from postgres
|
||||||
|
|
@ -23,42 +22,16 @@ var ParseFunc = func(parseConfig interface{}) {
|
||||||
cancelCtx, cancel := context.WithTimeout(modelParseConfig.Ctx, 5*time.Second)
|
cancelCtx, cancel := context.WithTimeout(modelParseConfig.Ctx, 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
pgClient := database.GetPostgresDBClient()
|
pgClient := database.GetPostgresDBClient()
|
||||||
|
component, err := database.QueryComponentByUUID(cancelCtx, pgClient, modelParseConfig.ComponentInfo.GlobalUUID)
|
||||||
unmarshalMap := make(map[string]interface{})
|
if err != nil {
|
||||||
tableName := model.SelectModelNameByType(modelParseConfig.ComponentInfo.ComponentType)
|
logger.Error(modelParseConfig.Ctx, "query component info failed", "error", err)
|
||||||
|
|
||||||
result := pgClient.WithContext(cancelCtx).Table(tableName).Where("component_id = ?", modelParseConfig.ComponentInfo.ID).Find(&unmarshalMap)
|
|
||||||
if result.Error != nil {
|
|
||||||
logger.Error(modelParseConfig.Ctx, "query component detail info failed", "error", result.Error)
|
|
||||||
return
|
|
||||||
} else if result.RowsAffected == 0 {
|
|
||||||
logger.Error(modelParseConfig.Ctx, "query component detail info from table is empty", "table_name", tableName)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var anchorName string
|
diagram.StoreAnchorValue(modelParseConfig.ComponentInfo.GlobalUUID.String(), "")
|
||||||
if anchoringV := unmarshalMap["anchor_v"].(bool); anchoringV {
|
|
||||||
anchorName = "voltage"
|
|
||||||
} else {
|
|
||||||
anchorName = "current"
|
|
||||||
}
|
|
||||||
diagram.StoreAnchorValue(modelParseConfig.ComponentInfo.ID, anchorName)
|
|
||||||
|
|
||||||
GetComponentChan(modelParseConfig.Ctx, modelParseConfig.ComponentInfo.ID)
|
GetAnchorParamChan(modelParseConfig.Ctx, modelParseConfig.ComponentInfo.GlobalUUID.String())
|
||||||
|
|
||||||
uuid := modelParseConfig.ComponentInfo.GlobalUUID.String()
|
diagram.StoreComponentMap(modelParseConfig.ComponentInfo.GlobalUUID.String(), &component)
|
||||||
unmarshalMap["id"] = modelParseConfig.ComponentInfo.ID
|
|
||||||
unmarshalMap["uuid"] = uuid
|
|
||||||
unmarshalMap["uuid"] = modelParseConfig.ComponentInfo.Tag
|
|
||||||
unmarshalMap["grid_id"] = modelParseConfig.ComponentInfo.GridID
|
|
||||||
unmarshalMap["zone_id"] = modelParseConfig.ComponentInfo.ZoneID
|
|
||||||
unmarshalMap["station_id"] = modelParseConfig.ComponentInfo.StationID
|
|
||||||
unmarshalMap["component_type"] = modelParseConfig.ComponentInfo.ComponentType
|
|
||||||
unmarshalMap["name"] = modelParseConfig.ComponentInfo.Name
|
|
||||||
unmarshalMap["context"] = modelParseConfig.ComponentInfo.Context
|
|
||||||
unmarshalMap["op"] = modelParseConfig.ComponentInfo.Op
|
|
||||||
unmarshalMap["ts"] = modelParseConfig.ComponentInfo.Ts
|
|
||||||
|
|
||||||
diagram.StoreComponentMap(modelParseConfig.ComponentInfo.ID, unmarshalMap)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,16 @@ func ReceiveChan(ctx context.Context) {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case realTimeData := <-RealTimeDataChan:
|
case realTimeData := <-RealTimeDataChan:
|
||||||
// TODO 根据 componentID 缓存到来的实时数据
|
componentUUID := realTimeData.PayLoad.ComponentUUID
|
||||||
componentID := realTimeData.PayLoad.ComponentID
|
component, err := diagram.GetComponentMap(componentUUID)
|
||||||
component, err := diagram.GetComponentMap(componentID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(ctx, "query component info from diagram map by componet id failed", "component_id", componentID, "error", err)
|
logger.Error(ctx, "query component info from diagram map by componet id failed", "component_uuid", componentUUID, "error", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
componentType := component["component_type"].(int)
|
componentType := component.Type
|
||||||
if componentType != constants.DemoType {
|
if componentType != constants.DemoType {
|
||||||
logger.Error(ctx, "can not process real time data of component type not equal DemoType", "component_id", componentID)
|
logger.Error(ctx, "can not process real time data of component type not equal DemoType", "component_uuid", componentUUID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,21 +43,8 @@ func ReceiveChan(ctx context.Context) {
|
||||||
var compareValUpperLimit, compareValLowerLimit float64
|
var compareValUpperLimit, compareValLowerLimit float64
|
||||||
var anchorRealTimeData []float64
|
var anchorRealTimeData []float64
|
||||||
var calculateFunc func(archorValue float64, args ...float64) float64
|
var calculateFunc func(archorValue float64, args ...float64) float64
|
||||||
if anchoringV := component["anchor_v"].(bool); anchoringV {
|
|
||||||
anchorName = "voltage"
|
|
||||||
compareValUpperLimit = component["uv_alarm"].(float64)
|
|
||||||
compareValLowerLimit = component["ov_alarm"].(float64)
|
|
||||||
} else {
|
|
||||||
anchorName = "current"
|
|
||||||
compareValUpperLimit = component["ui_alarm"].(float64)
|
|
||||||
compareValLowerLimit = component["oi_alarm"].(float64)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentData := map[string]interface{}{
|
// calculateFunc, params := config.SelectAnchorCalculateFuncAndParams(componentType, anchorName, componentData)
|
||||||
"resistance": component["resistance"].(float64),
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateFunc, params := config.SelectAnchorCalculateFuncAndParams(componentType, anchorName, componentData)
|
|
||||||
|
|
||||||
for _, param := range realTimeData.PayLoad.Values {
|
for _, param := range realTimeData.PayLoad.Values {
|
||||||
anchorRealTimeData = append(anchorRealTimeData, param.Value)
|
anchorRealTimeData = append(anchorRealTimeData, param.Value)
|
||||||
|
|
@ -66,16 +52,21 @@ func ReceiveChan(ctx context.Context) {
|
||||||
|
|
||||||
anchorConfig := config.AnchorParamConfig{
|
anchorConfig := config.AnchorParamConfig{
|
||||||
AnchorParamBaseConfig: config.AnchorParamBaseConfig{
|
AnchorParamBaseConfig: config.AnchorParamBaseConfig{
|
||||||
ComponentID: componentID,
|
ComponentUUID: componentUUID,
|
||||||
AnchorName: anchorName,
|
AnchorName: anchorName,
|
||||||
CompareValUpperLimit: compareValUpperLimit,
|
CompareValUpperLimit: compareValUpperLimit,
|
||||||
CompareValLowerLimit: compareValLowerLimit,
|
CompareValLowerLimit: compareValLowerLimit,
|
||||||
AnchorRealTimeData: anchorRealTimeData,
|
AnchorRealTimeData: anchorRealTimeData,
|
||||||
},
|
},
|
||||||
CalculateFunc: calculateFunc,
|
CalculateFunc: calculateFunc,
|
||||||
CalculateParams: params,
|
CalculateParams: []float64{},
|
||||||
}
|
}
|
||||||
pool.GetComponentChan(ctx, componentID) <- anchorConfig
|
anchorChan, err := pool.GetAnchorParamChan(ctx, componentUUID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, "get anchor param chan failed", "component_uuid", componentUUID, "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
anchorChan <- anchorConfig
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ func WriteComponentInShareMemory(key uintptr, componentInfo *orm.Component) erro
|
||||||
|
|
||||||
obj := (*orm.Component)(unsafe.Pointer(shmAddr + unsafe.Sizeof(structSize)))
|
obj := (*orm.Component)(unsafe.Pointer(shmAddr + unsafe.Sizeof(structSize)))
|
||||||
fmt.Println(obj)
|
fmt.Println(obj)
|
||||||
obj.ComponentType = componentInfo.ComponentType
|
|
||||||
|
|
||||||
// id integer NOT NULL DEFAULT nextval('component_id_seq'::regclass),
|
// id integer NOT NULL DEFAULT nextval('component_id_seq'::regclass),
|
||||||
// global_uuid uuid NOT NULL DEFAULT gen_random_uuid(),
|
// global_uuid uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
package handler_test
|
||||||
|
|
||||||
|
// TODO 使用 mock测试 handler
|
||||||
|
|
||||||
|
// 一、安装 GoMock
|
||||||
|
// 首先需要安装 GoMock 和 mockgen 工具:
|
||||||
|
|
||||||
|
// bash
|
||||||
|
// 复制
|
||||||
|
// # 安装 GoMock 包
|
||||||
|
// go get github.com/golang/mock/gomock
|
||||||
|
|
||||||
|
// # 安装 mockgen 工具
|
||||||
|
// go install github.com/golang/mock/mockgen@latest
|
||||||
|
// 二、基本使用步骤
|
||||||
|
// 1. 定义接口
|
||||||
|
// 假设我们有一个简单的接口:
|
||||||
|
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // greeter.go
|
||||||
|
// package main
|
||||||
|
|
||||||
|
// type Greeter interface {
|
||||||
|
// Greet(name string) string
|
||||||
|
// }
|
||||||
|
// 2. 生成 mock 代码
|
||||||
|
// 使用 mockgen 为接口生成 mock 实现:
|
||||||
|
|
||||||
|
// bash
|
||||||
|
// 复制
|
||||||
|
// mockgen -source=greeter.go -destination=mock_greeter.go -package=main
|
||||||
|
// 这会生成一个 mock_greeter.go 文件,包含 MockGreeter 结构体。
|
||||||
|
|
||||||
|
// 3. 编写测试代码
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // greeter_test.go
|
||||||
|
// package main
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "testing"
|
||||||
|
|
||||||
|
// "github.com/golang/mock/gomock"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func TestGreet(t *testing.T) {
|
||||||
|
// // 创建控制器
|
||||||
|
// ctrl := gomock.NewController(t)
|
||||||
|
// defer ctrl.Finish() // 断言所有期望都被满足
|
||||||
|
|
||||||
|
// // 创建 mock 对象
|
||||||
|
// mockGreeter := NewMockGreeter(ctrl)
|
||||||
|
|
||||||
|
// // 设置期望
|
||||||
|
// mockGreeter.EXPECT().
|
||||||
|
// Greet("Alice").
|
||||||
|
// Return("Hello, Alice!").
|
||||||
|
// Times(1)
|
||||||
|
|
||||||
|
// // 使用 mock 对象
|
||||||
|
// result := mockGreeter.Greet("Alice")
|
||||||
|
|
||||||
|
// // 验证结果
|
||||||
|
// if result != "Hello, Alice!" {
|
||||||
|
// t.Errorf("Expected 'Hello, Alice!', got '%s'", result)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 三、高级功能
|
||||||
|
// 1. 参数匹配
|
||||||
|
// GoMock 提供了多种参数匹配方式:
|
||||||
|
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // 精确匹配
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice")
|
||||||
|
|
||||||
|
// // 任意值匹配
|
||||||
|
// mockGreeter.EXPECT().Greet(gomock.Any())
|
||||||
|
|
||||||
|
// // 自定义匹配
|
||||||
|
// mockGreeter.EXPECT().Greet(gomock.AssignableToTypeOf("")).DoAndReturn(
|
||||||
|
// func(name string) string {
|
||||||
|
// return "Hello, " + name + "!"
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// 2. 调用次数控制
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // 精确调用次数
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").Times(3)
|
||||||
|
|
||||||
|
// // 至少调用一次
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").MinTimes(1)
|
||||||
|
|
||||||
|
// // 最多调用一次
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").MaxTimes(1)
|
||||||
|
|
||||||
|
// // 任意次数(0或多次)
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").AnyTimes()
|
||||||
|
// 3. 调用顺序控制
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// gomock.InOrder(
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice"),
|
||||||
|
// mockGreeter.EXPECT().Greet("Bob"),
|
||||||
|
// )
|
||||||
|
// 4. 模拟副作用
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // 使用 Do
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").Do(func(name string) {
|
||||||
|
// t.Logf("Greet was called with %s", name)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// // 使用 DoAndReturn
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").DoAndReturn(
|
||||||
|
// func(name string) string {
|
||||||
|
// return "Hi, " + name + "!"
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// 四、实际应用示例
|
||||||
|
// 假设我们有一个服务依赖 Greeter 接口:
|
||||||
|
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // greeter_service.go
|
||||||
|
// package main
|
||||||
|
|
||||||
|
// type GreeterService struct {
|
||||||
|
// greeter Greeter
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *GreeterService) WelcomePeople(names []string) []string {
|
||||||
|
// var greetings []string
|
||||||
|
// for _, name := range names {
|
||||||
|
// greetings = append(greetings, s.greeter.Greet(name))
|
||||||
|
// }
|
||||||
|
// return greetings
|
||||||
|
// }
|
||||||
|
// 对应的测试:
|
||||||
|
|
||||||
|
// go
|
||||||
|
// 复制
|
||||||
|
// // greeter_service_test.go
|
||||||
|
// package main
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "testing"
|
||||||
|
|
||||||
|
// "github.com/golang/mock/gomock"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func TestWelcomePeople(t *testing.T) {
|
||||||
|
// ctrl := gomock.NewController(t)
|
||||||
|
// defer ctrl.Finish()
|
||||||
|
|
||||||
|
// mockGreeter := NewMockGreeter(ctrl)
|
||||||
|
// service := &GreeterService{greeter: mockGreeter}
|
||||||
|
|
||||||
|
// // 设置期望
|
||||||
|
// mockGreeter.EXPECT().Greet("Alice").Return("Hello, Alice!")
|
||||||
|
// mockGreeter.EXPECT().Greet("Bob").Return("Hello, Bob!")
|
||||||
|
|
||||||
|
// // 测试
|
||||||
|
// result := service.WelcomePeople([]string{"Alice", "Bob"})
|
||||||
|
|
||||||
|
// // 验证
|
||||||
|
// expected := []string{"Hello, Alice!", "Hello, Bob!"}
|
||||||
|
// if len(result) != len(expected) {
|
||||||
|
// t.Fatalf("Expected %d greetings, got %d", len(expected), len(result))
|
||||||
|
// }
|
||||||
|
// for i := range expected {
|
||||||
|
// if result[i] != expected[i] {
|
||||||
|
// t.Errorf("At index %d: expected %q, got %q", i, expected[i], result[i])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
Loading…
Reference in New Issue