From b75358e676899ef1ebb4e8eef3e1a116acb6c8bf Mon Sep 17 00:00:00 2001 From: douxu Date: Wed, 5 Nov 2025 18:20:54 +0800 Subject: [PATCH] optimize first create monitor config func of real time data query api --- constants/monitor.go | 15 ++++ database/create_component.go | 6 +- database/fill_identity_token_model.go | 92 ++++++++++++-------- database/query_component.go | 56 ++++++++++++ database/update_component.go | 6 +- handler/real_time_data_monitor.go | 67 ++++++++++++--- middleware/panic_recover.go | 47 +++++++++++ model/identity_token_model.go | 117 ++++++++++++++++++-------- network/response.go | 6 +- orm/circuit_diagram_component.go | 6 +- 10 files changed, 322 insertions(+), 96 deletions(-) create mode 100644 middleware/panic_recover.go diff --git a/constants/monitor.go b/constants/monitor.go index 981bb76..f2ed744 100644 --- a/constants/monitor.go +++ b/constants/monitor.go @@ -9,3 +9,18 @@ const ( // MonitorAppendAction define the real time monitor append action MonitorAppendAction string = "append" ) + +// 定义状态常量 +const ( + // SubSuccessCode define subscription success code + SubSuccessCode = "1001" + // SubSuccessCode define subscription failed code + SubFailedCode = "1002" +) + +const ( + // SubSuccessMsg define subscription success message + SubSuccessMsg = "subscription success" + // SubFailedMsg define subscription failed message + SubFailedMsg = "subscription failed" +) diff --git a/database/create_component.go b/database/create_component.go index c97730f..778ed4b 100644 --- a/database/create_component.go +++ b/database/create_component.go @@ -27,9 +27,9 @@ func CreateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo netwo component := orm.Component{ GlobalUUID: globalUUID, - GridID: strconv.FormatInt(componentInfo.GridID, 10), - ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10), - StationID: strconv.FormatInt(componentInfo.StationID, 10), + GridTag: strconv.FormatInt(componentInfo.GridID, 10), + ZoneTag: strconv.FormatInt(componentInfo.ZoneID, 10), + StationTag: strconv.FormatInt(componentInfo.StationID, 10), Tag: componentInfo.Tag, Name: componentInfo.Name, Context: componentInfo.Context, diff --git a/database/fill_identity_token_model.go b/database/fill_identity_token_model.go index 694dd89..d317960 100644 --- a/database/fill_identity_token_model.go +++ b/database/fill_identity_token_model.go @@ -3,64 +3,86 @@ package database import ( "context" + "fmt" "strings" + "modelRT/logger" "modelRT/model" + "modelRT/orm" "gorm.io/gorm" ) // FillingShortTokenModel define filling short token model info -func FillingShortTokenModel(ctx context.Context, tx *gorm.DB, attrItems []string, attrModel *model.ShortAttrInfo) error { - // TODO 重新创建tokenModel 及相关sql查询函数 - // component, err := QueryComponentByLongToken(ctx, tx, attrItems[0]) - // if err != nil { - // return err - // } - // attrModel.ComponentInfo = &component +func FillingShortTokenModel(ctx context.Context, tx *gorm.DB, identModel *model.ShortIdentityTokenModel) error { + filterComponent := &orm.Component{ + GridTag: identModel.GetGridTag(), + ZoneTag: identModel.GetZoneTag(), + StationTag: identModel.GetStationTag(), + } + + component, measurement, err := QueryLongIdentModelInfoByToken(ctx, tx, identModel.MeasurementTag, filterComponent) + if err != nil { + logger.Error(ctx, "query long identity token model info failed", "error", err) + return err + } + identModel.ComponentInfo = component + identModel.MeasurementInfo = measurement return nil } // FillingLongTokenModel define filling long token model info -func FillingLongTokenModel(ctx context.Context, tx *gorm.DB, attrItems []string, attrModel *model.LongAttrInfo) error { - // TODO 重新创建tokenModel 及相关sql查询函数 - // component, err := QueryComponentByShortToken(ctx, tx, attrItems[3]) - // if err != nil { - // return err - // } - // attrModel.ComponentInfo = &component +func FillingLongTokenModel(ctx context.Context, tx *gorm.DB, identModel *model.LongIdentityTokenModel) error { + filterComponent := &orm.Component{ + GridTag: identModel.GetGridTag(), + ZoneTag: identModel.GetZoneTag(), + StationTag: identModel.GetStationTag(), + Tag: identModel.GetComponentTag(), + } + component, measurement, err := QueryLongIdentModelInfoByToken(ctx, tx, identModel.MeasurementTag, filterComponent) + if err != nil { + logger.Error(ctx, "query long identity token model info failed", "error", err) + return err + } + identModel.ComponentInfo = component + identModel.MeasurementInfo = measurement return nil } // ParseDataIdentifierToken define function to parse data identifier token function -func ParseDataIdentifierToken(ctx context.Context, tx *gorm.DB, identToken string) (model.AttrModelInterface, error) { - // TODO 使用identityToken代替ShortAttrInfo等 - attrSlice := strings.Split(identToken, ".") - attrLen := len(attrSlice) - if attrLen == 4 { - short := &model.ShortAttrInfo{ - AttrGroupName: attrSlice[2], - AttrKey: attrSlice[3], +func ParseDataIdentifierToken(ctx context.Context, tx *gorm.DB, identToken string) (model.IndentityTokenModelInterface, error) { + identSlice := strings.Split(identToken, ".") + identSliceLen := len(identSlice) + if identSliceLen == 4 { + // token1.token2.token3.token4.token7 + shortIndentModel := &model.ShortIdentityTokenModel{ + GridTag: identSlice[0], + ZoneTag: identSlice[1], + StationTag: identSlice[2], + NamespacePath: identSlice[3], + MeasurementTag: identSlice[6], } - err := FillingShortTokenModel(ctx, tx, attrSlice, short) + err := FillingShortTokenModel(ctx, tx, shortIndentModel) if err != nil { return nil, err } - - // short.AttrValue = attrValue - return short, nil - } else if attrLen == 7 { - long := &model.LongAttrInfo{ - AttrGroupName: attrSlice[5], - AttrKey: attrSlice[6], + return shortIndentModel, nil + } else if identSliceLen == 7 { + // token1.token2.token3.token4.token5.token6.token7 + longIndentModel := &model.LongIdentityTokenModel{ + GridTag: identSlice[0], + ZoneTag: identSlice[1], + StationTag: identSlice[2], + NamespacePath: identSlice[3], + ComponentTag: identSlice[4], + AttributeGroup: identSlice[5], + MeasurementTag: identSlice[6], } - err := FillingLongTokenModel(ctx, tx, attrSlice, long) + err := FillingLongTokenModel(ctx, tx, longIndentModel) if err != nil { return nil, err } - - // long.AttrValue = attrValue - return long, nil + return longIndentModel, nil } - return nil, nil + return nil, fmt.Errorf("invalid identity token format: %s", identToken) } diff --git a/database/query_component.go b/database/query_component.go index 8565cbd..d43d3e0 100644 --- a/database/query_component.go +++ b/database/query_component.go @@ -3,6 +3,7 @@ package database import ( "context" + "fmt" "time" "modelRT/orm" @@ -81,3 +82,58 @@ func QueryComponentByNsPath(ctx context.Context, tx *gorm.DB, nsPath string) (or } return component, nil } + +// QueryLongIdentModelInfoByToken define func to query long identity model info by long token +func QueryLongIdentModelInfoByToken(ctx context.Context, tx *gorm.DB, measTag string, condition *orm.Component) (*orm.Component, *orm.Measurement, error) { + var resultComp orm.Component + var meauserment orm.Measurement + + // ctx timeout judgment + cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).First(&resultComp, &condition) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return nil, nil, fmt.Errorf("component record not found by %v:%w", condition, result.Error) + } + return nil, nil, result.Error + } + + filterMap := map[string]any{"COMPONENT_UUID": resultComp.GlobalUUID, "TAG": measTag} + result = tx.WithContext(cancelCtx).Where(filterMap).Clauses(clause.Locking{Strength: "UPDATE"}).First(&meauserment) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return nil, nil, fmt.Errorf("measurement record not found by %v:%w", filterMap, result.Error) + } + return nil, nil, result.Error + } + return &resultComp, &meauserment, nil +} + +// QueryShortIdentModelInfoByToken define func to query short identity model info by short token +func QueryShortIdentModelInfoByToken(ctx context.Context, tx *gorm.DB, measTag string, condition *orm.Component) (*orm.Component, *orm.Measurement, error) { + var resultComp orm.Component + var meauserment orm.Measurement + // ctx timeout judgment + cancelCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).First(&resultComp, &condition) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return nil, nil, fmt.Errorf("component record not found by %v:%w", condition, result.Error) + } + return nil, nil, result.Error + } + + filterMap := map[string]any{"COMPONENT_UUID": resultComp.GlobalUUID, "TAG": measTag} + result = tx.WithContext(cancelCtx).Where(filterMap).Clauses(clause.Locking{Strength: "UPDATE"}).First(&meauserment) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return nil, nil, fmt.Errorf("measurement record not found by %v:%w", filterMap, result.Error) + } + return nil, nil, result.Error + } + return &resultComp, &meauserment, nil +} diff --git a/database/update_component.go b/database/update_component.go index 3c7ed78..c2f9f1c 100644 --- a/database/update_component.go +++ b/database/update_component.go @@ -37,9 +37,9 @@ func UpdateComponentIntoDB(ctx context.Context, tx *gorm.DB, componentInfo netwo updateParams := orm.Component{ GlobalUUID: globalUUID, - GridID: strconv.FormatInt(componentInfo.GridID, 10), - ZoneID: strconv.FormatInt(componentInfo.ZoneID, 10), - StationID: strconv.FormatInt(componentInfo.StationID, 10), + GridTag: strconv.FormatInt(componentInfo.GridID, 10), + ZoneTag: strconv.FormatInt(componentInfo.ZoneID, 10), + StationTag: strconv.FormatInt(componentInfo.StationID, 10), Tag: componentInfo.Tag, Name: componentInfo.Name, Context: componentInfo.Context, diff --git a/handler/real_time_data_monitor.go b/handler/real_time_data_monitor.go index d228e25..2f02ca9 100644 --- a/handler/real_time_data_monitor.go +++ b/handler/real_time_data_monitor.go @@ -8,11 +8,13 @@ import ( "sync" "modelRT/constants" + "modelRT/database" "modelRT/logger" "modelRT/network" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" + "gorm.io/gorm" ) var globalMonitorState *SharedMonitorState @@ -62,9 +64,14 @@ func RealTimeMonitorHandler(c *gin.Context) { monitorID = request.MonitorID } + pgClient := database.GetPostgresDBClient() + // open transaction + tx := pgClient.Begin() + defer tx.Commit() + switch monitorAction { case constants.MonitorStartAction: - err := globalMonitorState.CreateConfig(monitorID, request.Components) + results, err := globalMonitorState.CreateConfig(c, tx, monitorID, request.Components) if err != nil { logger.Error(c, "create real time data monitor config failed", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ @@ -77,8 +84,8 @@ func RealTimeMonitorHandler(c *gin.Context) { c.JSON(http.StatusOK, network.SuccessResponse{ Code: http.StatusOK, Msg: "success", - PayLoad: map[string]interface{}{ - "monitor_id": monitorID, + PayLoad: network.RealTimeQueryPayload{ + TargetResults: results, }, }) return @@ -130,12 +137,12 @@ func NewSharedMonitorState() *SharedMonitorState { } // CreateConfig define function to create config in SharedMonitorState -func (s *SharedMonitorState) CreateConfig(monitorID string, components []network.RealTimeComponentItem) error { +func (s *SharedMonitorState) CreateConfig(ctx context.Context, tx *gorm.DB, monitorID string, components []network.RealTimeComponentItem) ([]network.TargetResult, error) { s.mutex.Lock() defer s.mutex.Unlock() if _, exist := s.monitorMap[monitorID]; exist { - return fmt.Errorf("monitorID %s already exists. Use AppendTargets to modify existing config", monitorID) + return nil, fmt.Errorf("monitorID %s already exists. Use AppendTargets to modify existing config", monitorID) } config := &RealTimeMonitorConfig{ @@ -143,17 +150,44 @@ func (s *SharedMonitorState) CreateConfig(monitorID string, components []network components: make(map[string]*RealTimeMonitorComponent), } - for _, compent := range components { - config.components[compent.Interval] = &RealTimeMonitorComponent{ - targets: compent.Targets, + targetProcessResults := make([]network.TargetResult, 0, processRealTimeRequestCount(components)) + for _, componentItem := range components { + interval := componentItem.Interval + for _, target := range componentItem.Targets { + targetModel, err := database.ParseDataIdentifierToken(ctx, tx, target) + + var targetResult network.TargetResult + targetResult.ID = target + + if err != nil { + logger.Error(ctx, "parse data indentity token failed", "error", err, "identity_token", target) + targetResult.Code = constants.SubFailedCode + targetResult.Msg = fmt.Sprintf("%s: %s", constants.SubFailedMsg, err.Error()) + targetProcessResults = append(targetProcessResults, targetResult) + continue + } + + targetResult.Code = constants.SubSuccessCode + targetResult.Msg = constants.SubSuccessMsg + if _, ok := config.components[componentItem.Interval]; !ok { + targets := make([]string, 0, len(componentItem.Targets)) + config.components[interval] = &RealTimeMonitorComponent{ + targets: append(targets, target), + } + } else { + component := config.components[interval] + component.targets = append(component.targets, target) + } + fmt.Println(targetModel.GetMeasurementInfo().Size) } } s.monitorMap[monitorID] = config - return nil + return targetProcessResults, nil } // AppendTargets define function to append targets in SharedMonitorState +// TODO 增加targetsResults的返回 func (s *SharedMonitorState) AppendTargets(monitorID string, components []network.RealTimeComponentItem) error { s.mutex.Lock() defer s.mutex.Unlock() @@ -168,12 +202,11 @@ func (s *SharedMonitorState) AppendTargets(monitorID string, components []networ comp, compExist := config.components[interval] if !compExist { comp = &RealTimeMonitorComponent{ - targets: comp.targets, + targets: compent.Targets, } config.components[interval] = comp - } else { - comp.targets = append(comp.targets, comp.targets...) + comp.targets = append(comp.targets, compent.Targets...) } } @@ -182,6 +215,7 @@ func (s *SharedMonitorState) AppendTargets(monitorID string, components []networ } // UpsertTargets define function to upsert targets in SharedMonitorState +// TODO 增加targetsResults的返回 func (s *SharedMonitorState) UpsertTargets(monitorID string, interval string, newTargets []string) (isNewMonitor bool, err error) { s.mutex.Lock() defer s.mutex.Unlock() @@ -229,6 +263,7 @@ func (s *SharedMonitorState) Get(monitorID, interval string) ([]string, bool) { } // RemoveTargets define function to remove targets in SharedMonitorState +// TODO 增加targetsResults的返回 func (s *SharedMonitorState) RemoveTargets(ctx context.Context, monitorID string, components []network.RealTimeComponentItem) error { s.mutex.Lock() defer s.mutex.Unlock() @@ -271,3 +306,11 @@ func (s *SharedMonitorState) RemoveTargets(ctx context.Context, monitorID string config.noticeChan <- struct{}{} return nil } + +func processRealTimeRequestCount(components []network.RealTimeComponentItem) int { + totalTargetsCount := 0 + for _, compItem := range components { + totalTargetsCount += len(compItem.Targets) + } + return totalTargetsCount +} diff --git a/middleware/panic_recover.go b/middleware/panic_recover.go new file mode 100644 index 0000000..e7aa3ac --- /dev/null +++ b/middleware/panic_recover.go @@ -0,0 +1,47 @@ +package middleware + +import ( + "net" + "net/http" + "net/http/httputil" + "os" + "runtime/debug" + "strings" + + "modelRT/logger" + + "github.com/gin-gonic/gin" +) + +// GinPanicRecovery define func of customizing gin recover output +func GinPanicRecovery() gin.HandlerFunc { + return func(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + // Check for a broken connection, as it is not really a + // condition that warrants a panic stack trace. + var brokenPipe bool + if ne, ok := err.(*net.OpError); ok { + if se, ok := ne.Err.(*os.SyscallError); ok { + if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { + brokenPipe = true + } + } + } + + httpRequest, _ := httputil.DumpRequest(c.Request, false) + if brokenPipe { + logger.Error(c, "http request broken pipe", "path", c.Request.URL.Path, "error", err, "request", string(httpRequest)) + // If the connection is dead, we can't write a status to it. + c.Error(err.(error)) + c.Abort() + return + } + + logger.Error(c, "http_request_panic", "path", c.Request.URL.Path, "error", err, "request", string(httpRequest), "stack", string(debug.Stack())) + c.AbortWithError(http.StatusInternalServerError, err.(error)) + } + }() + c.Next() + } +} diff --git a/model/identity_token_model.go b/model/identity_token_model.go index 0e57e57..088de78 100644 --- a/model/identity_token_model.go +++ b/model/identity_token_model.go @@ -5,34 +5,29 @@ import "modelRT/orm" // IndentityTokenModelInterface define basic identity token model type interface type IndentityTokenModelInterface interface { - GetGridInfo() *orm.Grid - GetZoneInfo() *orm.Zone - GetStationInfo() *orm.Station GetComponentInfo() *orm.Component + GetMeasurementInfo() *orm.Measurement + GetGridTag() string // token1 + GetZoneTag() string // token2 + GetStationTag() string // token3 + GetNamespacePath() string // token4(COMPONENT TABLE NSPATH) + GetComponentTag() string // token5(COMPONENT TABLE TAG) + GetAttributeGroup() string // token6(component attribute group information) + GetMeasurementTag() string // token7(measurement value or attribute field) IsLocal() bool } // LongIdentityTokenModel define struct to long identity token info type LongIdentityTokenModel struct { - GridInfo *orm.Grid - ZoneInfo *orm.Zone - StationInfo *orm.Station - ComponentInfo *orm.Component -} - -// GetGridInfo define return the grid information in the long identity token -func (l *LongIdentityTokenModel) GetGridInfo() *orm.Grid { - return l.GridInfo -} - -// GetZoneInfo define return the zone information in the long identity token -func (l *LongIdentityTokenModel) GetZoneInfo() *orm.Zone { - return l.ZoneInfo -} - -// GetStationInfo define return the station information in the long identity token -func (l *LongIdentityTokenModel) GetStationInfo() *orm.Station { - return l.StationInfo + ComponentInfo *orm.Component + MeasurementInfo *orm.Measurement + GridTag string + ZoneTag string + StationTag string + NamespacePath string + ComponentTag string + AttributeGroup string + MeasurementTag string } // GetComponentInfo define return the component information in the long identity token @@ -40,6 +35,34 @@ func (l *LongIdentityTokenModel) GetComponentInfo() *orm.Component { return l.ComponentInfo } +// GetMeasurementInfo define return the measurement information in the long identity token +func (l *LongIdentityTokenModel) GetMeasurementInfo() *orm.Measurement { + return l.MeasurementInfo +} + +// GetGridTag define function to return the grid tag information in the long identity token +func (l *LongIdentityTokenModel) GetGridTag() string { return l.GridTag } + +// GetZoneTag define function to return the zone tag information in the long identity token +func (l *LongIdentityTokenModel) GetZoneTag() string { return l.ZoneTag } + +// GetStationTag define function to return the station tag information in the long identity token +func (l *LongIdentityTokenModel) GetStationTag() string { return l.StationTag } + +// GetNamespacePath define function to return the namespace path information in the long identity token +func (l *LongIdentityTokenModel) GetNamespacePath() string { return l.NamespacePath } + +// GetComponentTag define function to return the component tag information in the long identity token +func (l *LongIdentityTokenModel) GetComponentTag() string { return l.ComponentTag } + +// GetAttributeGroup define function to return the attribute group information in the long identity token +func (l *LongIdentityTokenModel) GetAttributeGroup() string { return l.AttributeGroup } + +// GetMeasurementTag define function to return the measurement tag information in the long identity token +func (l *LongIdentityTokenModel) GetMeasurementTag() string { + return l.MeasurementTag +} + // IsLocal define return the is_local information in the long identity token func (l *LongIdentityTokenModel) IsLocal() bool { return false @@ -47,22 +70,14 @@ func (l *LongIdentityTokenModel) IsLocal() bool { // ShortIdentityTokenModel define struct to short identity token info type ShortIdentityTokenModel struct { - ComponentInfo *orm.Component -} + ComponentInfo *orm.Component + MeasurementInfo *orm.Measurement -// GetGridInfo define return the grid information in the short identity token -func (s *ShortIdentityTokenModel) GetGridInfo() *orm.Grid { - return nil -} - -// GetZoneInfo define return the zone information in the short identity token -func (s *ShortIdentityTokenModel) GetZoneInfo() *orm.Zone { - return nil -} - -// GetStationInfo define return the station information in the short identity token -func (s *ShortIdentityTokenModel) GetStationInfo() *orm.Station { - return nil + GridTag string // token1 + ZoneTag string // token2 + StationTag string // token3 + NamespacePath string // token4 + MeasurementTag string // token7 } // GetComponentInfo define return the component information in the short identity token @@ -70,6 +85,34 @@ func (s *ShortIdentityTokenModel) GetComponentInfo() *orm.Component { return s.ComponentInfo } +// GetMeasurementInfo define return the measurement information in the long identity token +func (s *ShortIdentityTokenModel) GetMeasurementInfo() *orm.Measurement { + return s.MeasurementInfo +} + +// GetGridTag define function to return the grid tag information in the short identity token +func (s *ShortIdentityTokenModel) GetGridTag() string { return "" } + +// GetZoneTag define function to return the zone tag information in the short identity token +func (s *ShortIdentityTokenModel) GetZoneTag() string { return "" } + +// GetStationTag define function to return the station tag information in the short identity token +func (s *ShortIdentityTokenModel) GetStationTag() string { return "" } + +// GetNamespacePath define function to return the namespace path information in the short identity token +func (s *ShortIdentityTokenModel) GetNamespacePath() string { return s.NamespacePath } + +// GetComponentTag define function to return the component tag information in the short identity token +func (s *ShortIdentityTokenModel) GetComponentTag() string { return "" } + +// GetAttributeGroup define function to return the attribute group information in the short identity token +func (s *ShortIdentityTokenModel) GetAttributeGroup() string { return "" } + +// GetMeasurementTag define function to return the measurement tag information in the short identity token +func (s *ShortIdentityTokenModel) GetMeasurementTag() string { + return "" +} + // IsLocal define return the is_local information in the short identity token func (s *ShortIdentityTokenModel) IsLocal() bool { return true diff --git a/network/response.go b/network/response.go index a36b519..7edd99f 100644 --- a/network/response.go +++ b/network/response.go @@ -22,8 +22,8 @@ type MeasurementRecommendPayload struct { RecommendedList []string `json:"recommended_list" example:"[\"I_A_rms\", \"I_B_rms\",\"I_C_rms\"]"` } -// Target define struct of target item in real time data query response payload -type Target struct { +// TargetResult define struct of target item in real time data query response payload +type TargetResult struct { ID string `json:"id" example:"grid1.zone1.station1.ns1.tag1.transformfeeder1_220.I_A_rms"` Code string `json:"code" example:"1001"` Msg string `json:"msg" example:"subscription success"` @@ -31,5 +31,5 @@ type Target struct { // RealTimeQueryPayload define struct of real time data query request type RealTimeQueryPayload struct { - Targets []Target `json:"targets"` + TargetResults []TargetResult `json:"targets"` } diff --git a/orm/circuit_diagram_component.go b/orm/circuit_diagram_component.go index 2d72322..1e95b6a 100644 --- a/orm/circuit_diagram_component.go +++ b/orm/circuit_diagram_component.go @@ -15,9 +15,9 @@ type Component struct { Name string `gorm:"column:NAME"` ModelName string `gorm:"column:MODEL_NAME"` Description string `gorm:"column:DESCRIPTION"` - GridID string `gorm:"column:GRID"` - ZoneID string `gorm:"column:ZONE"` - StationID string `gorm:"column:STATION"` + GridTag string `gorm:"column:GRID"` + ZoneTag string `gorm:"column:ZONE"` + StationTag string `gorm:"column:STATION"` Type int `gorm:"column:TYPE"` InService bool `gorm:"column:IN_SERVICE"` State int `gorm:"column:STATE"`