modelRT/handler/circuit_diagram_delete.go

232 lines
7.0 KiB
Go

// Package handler provides HTTP handlers for various endpoints.
package handler
import (
"context"
"fmt"
"net/http"
"time"
"modelRT/constant"
"modelRT/database"
"modelRT/diagram"
"modelRT/logger"
"modelRT/model"
"modelRT/network"
"modelRT/orm"
"github.com/gin-gonic/gin"
"github.com/gofrs/uuid"
"go.uber.org/zap"
"gorm.io/gorm/clause"
)
// CircuitDiagramDeleteHandler define circuit diagram delete process API
func CircuitDiagramDeleteHandler(c *gin.Context) {
logger := logger.GetLoggerInstance()
pgClient := database.GetPostgresDBClient()
var request network.CircuitDiagramDeleteRequest
if err := c.ShouldBindJSON(&request); err != nil {
logger.Error("unmarshal circuit diagram del info failed", zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
}
c.JSON(http.StatusOK, resp)
return
}
graph, err := diagram.GetGraphMap(request.PageID)
if err != nil {
logger.Error("get topologic data from set by pageID failed", zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"page_id": request.PageID,
},
}
c.JSON(http.StatusOK, resp)
return
}
var topologicDelInfos []network.TopologicUUIDDelInfo
for _, topologicLink := range request.TopologicLinks {
var delInfo network.TopologicUUIDDelInfo
UUIDFrom, err1 := uuid.FromString(topologicLink.UUIDFrom)
UUIDTo, err2 := uuid.FromString(topologicLink.UUIDTo)
if err1 != nil || err2 != nil {
var err error
if err1 != nil && err2 == nil {
err = fmt.Errorf("convert uuid from string failed:%w", err1)
} else if err1 == nil && err2 != nil {
err = fmt.Errorf("convert uuid from string failed:%w", err2)
} else {
err = fmt.Errorf("convert uuid from string failed:%w:%w", err1, err2)
}
logger.Error("format uuid from string failed", zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"topologic_info": topologicLink,
},
}
c.JSON(http.StatusOK, resp)
return
}
delInfo.UUIDFrom = UUIDFrom
delInfo.UUIDTo = UUIDTo
topologicDelInfos = append(topologicDelInfos, delInfo)
}
// open transaction
tx := pgClient.Begin()
for _, topologicDelInfo := range topologicDelInfos {
err = database.DeleteTopologicIntoDB(c, tx, request.PageID, topologicDelInfo)
if err != nil {
tx.Rollback()
logger.Error("delete topologic info into DB failed", zap.Any("topologic_info", topologicDelInfo), zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"topologic_info": topologicDelInfo,
},
}
c.JSON(http.StatusOK, resp)
return
}
err = graph.DelEdge(topologicDelInfo.UUIDFrom, topologicDelInfo.UUIDTo)
if err != nil {
tx.Rollback()
logger.Error("delete topologic info failed", zap.Any("topologic_info", topologicDelInfo), zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"topologic_info": topologicDelInfo,
},
}
c.JSON(http.StatusOK, resp)
return
}
}
if len(graph.VerticeLinks) == 0 && len(graph.FreeVertexs) == 0 {
diagram.DeleteGraphMap(request.PageID)
}
for _, componentInfo := range request.ComponentInfos {
cancelCtx, cancel := context.WithTimeout(c, 5*time.Second)
defer cancel()
globalUUID, err := uuid.FromString(componentInfo.UUID)
if err != nil {
tx.Rollback()
logger.Error("format uuid from string failed", zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"uuid": componentInfo.UUID,
},
}
c.JSON(http.StatusOK, resp)
return
}
var component orm.Component
result := tx.WithContext(cancelCtx).Clauses(clause.Locking{Strength: "UPDATE"}).Where("global_uuid = ?", globalUUID).Find(&component)
if result.Error != nil || result.RowsAffected == 0 {
tx.Rollback()
err := result.Error
if result.RowsAffected == 0 {
err = fmt.Errorf("%w:please check uuid conditions", constant.ErrDeleteRowZero)
}
logger.Error("query component info into postgresDB failed", zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"uuid": componentInfo.UUID,
},
}
c.JSON(http.StatusOK, resp)
return
}
result = tx.WithContext(cancelCtx).Delete(component)
if result.Error != nil || result.RowsAffected == 0 {
tx.Rollback()
err := result.Error
if result.RowsAffected == 0 {
err = fmt.Errorf("%w:please check uuid conditions", constant.ErrDeleteRowZero)
}
logger.Error("delete component info into postgresDB failed", zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"uuid": componentInfo.UUID,
},
}
c.JSON(http.StatusOK, resp)
return
}
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", constant.ErrDeleteRowZero)
}
msg := fmt.Sprintf("delete component info from table %s failed", modelStruct.ReturnTableName())
logger.Error(msg, zap.String("component_global_uuid", componentInfo.UUID), zap.Error(err))
header := network.FailResponseHeader{Status: http.StatusBadRequest, ErrMsg: err.Error()}
resp := network.FailureResponse{
FailResponseHeader: header,
PayLoad: map[string]interface{}{
"uuid": componentInfo.UUID,
},
}
c.JSON(http.StatusOK, resp)
return
}
diagram.DeleteComponentMap(componentInfo.UUID)
}
if len(request.FreeVertexs) > 0 {
for _, freeVertex := range request.FreeVertexs {
delete(graph.FreeVertexs, freeVertex)
}
}
// commit transsction
tx.Commit()
resp := network.SuccessResponse{
SuccessResponseHeader: network.SuccessResponseHeader{Status: http.StatusOK},
PayLoad: map[string]interface{}{
"page_id": request.PageID,
},
}
c.JSON(http.StatusOK, resp)
}