modelRT/model/attribute_group_recommend_m...

159 lines
5.0 KiB
Go

// Package model define model struct of model runtime service
package model
import (
"context"
"errors"
"fmt"
"modelRT/constants"
"modelRT/diagram"
"modelRT/logger"
"modelRT/orm"
"github.com/RediSearch/redisearch-go/v2/redisearch"
"gorm.io/gorm"
)
type columnParam struct {
AttributeType string
AttributeGroup map[string]any
}
// TraverseAttributeGroupTables define func to traverse component attribute group tables
func TraverseAttributeGroupTables(ctx context.Context, db *gorm.DB, compTagToFullPath map[string]string, compAttrSet map[string]orm.AttributeSet) error {
var tableNames []string
excludedTables := []string{"component", ""}
result := db.Model(&orm.ProjectManager{}).
Where("name NOT IN ?", excludedTables).
Pluck("name", &tableNames)
if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
logger.Error(ctx, "query name column data from postgres table failed", "err", result.Error)
return result.Error
}
if len(tableNames) == 0 {
logger.Info(ctx, "query from postgres successed, but no records found")
return nil
}
for _, tableName := range tableNames {
var records []map[string]any
err := db.Table(tableName).Find(&records).Error
if err != nil && err != gorm.ErrRecordNotFound {
logger.Error(ctx, fmt.Sprintf("query table '%s' data failed", tableName), "table_name", tableName, "err", err)
return err
}
migrator := db.Migrator()
if exists := migrator.HasTable(tableName); !exists {
err := errors.New("can not find special table into database")
logger.Error(ctx, "table does not exist in the database", "table _name", tableName, "error", err)
return err
}
columnTypes, err := migrator.ColumnTypes(tableName)
if err != nil {
logger.Error(ctx, "retrieving column structure for table failed", "table _name", tableName, "error", err)
return err
}
for _, record := range records {
attributeGroup := make(map[string]any)
var componentUUIDStr string
var attrSet orm.AttributeSet
var attributeType string
for _, col := range columnTypes {
colName := col.Name()
value, exists := record[colName]
if !exists {
err := errors.New("can not find value from record by column name")
logger.Error(ctx, "query value by column name failed", "column_name", colName, "error", err)
return err
}
switch colName {
case "id":
case "global_uuid":
componentUUIDStr = value.(string)
attrSet, exists = compAttrSet[componentUUIDStr]
if !exists {
err := errors.New("can not find component tag from record by global uuid")
logger.Error(ctx, "check component info by global uuid failed", "global_uuid", componentUUIDStr, "error", err)
return err
}
case "attribute_group":
attributeType = value.(string)
default:
attributeGroup[colName] = value
}
}
fullPath := compTagToFullPath[attrSet.CompTag]
if fullPath == "" {
err := errors.New("can not find full parent path from mapping by component tag")
logger.Error(ctx, "find full parent path by from mapping by component tag failed", "component_tag", attrSet.CompTag, "error", err)
return err
}
columnParam := columnParam{
AttributeType: attributeType,
AttributeGroup: attributeGroup,
}
go storeAttributeGroup(ctx, attrSet, fullPath, columnParam)
}
}
return nil
}
func storeAttributeGroup(ctx context.Context, attributeSet orm.AttributeSet, fullPath string, colParams columnParam) {
rdb := diagram.GetRedisClientInstance()
pipe := rdb.Pipeline()
// add token6 hierarchy content
pipe.SAdd(ctx, constants.RedisAllConfigSetKey, colParams.AttributeType)
// add token5-token7 hierarchy collaboration content
specCompMeasKey := fmt.Sprintf(constants.RedisSpecCompTagMeasSetKey, attributeSet.CompTag)
attrNameMembers := make([]string, 0, len(colParams.AttributeGroup))
attrbutesGroups := make([]any, 0, len(colParams.AttributeGroup)*2)
attributeGroupKey := fmt.Sprintf("%s_%s", attributeSet.CompTag, colParams.AttributeType)
sug := make([]redisearch.Suggestion, 0, len(colParams.AttributeGroup))
for attrName, attrValue := range colParams.AttributeGroup {
attrbutesGroups = append(attrbutesGroups, attrName, attrValue)
attrNameMembers = append(attrNameMembers, attrName)
configTerm := fmt.Sprintf("%s.%s", fullPath, colParams.AttributeType)
sug = append(sug, redisearch.Suggestion{
Term: configTerm,
Score: constants.DefaultScore,
})
measTerm := fmt.Sprintf("%s.%s.%s", fullPath, colParams.AttributeType, attrName)
sug = append(sug, redisearch.Suggestion{
Term: measTerm,
Score: constants.DefaultScore,
})
}
if len(attrbutesGroups) > 0 {
pipe.HSet(ctx, attributeGroupKey, attrbutesGroups...)
}
if len(attrNameMembers) > 0 {
pipe.SAdd(ctx, constants.RedisAllMeasTagSetKey, attrNameMembers)
pipe.SAdd(ctx, specCompMeasKey, attrNameMembers)
}
if len(sug) > 0 {
ac.AddTerms(sug...)
}
_, err := pipe.Exec(ctx)
if err != nil {
logger.Error(ctx, "init component attribute group recommend content failed", "error", err)
}
}