// 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) } }