// params — слияние, фильтрация, анализ параметров и ForceNew. package main import ( "sort" "strings" ) func mergeParams(sets ...[]Param) []Param { seen := map[string]Param{} for _, s := range sets { for _, p := range s { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if _, ok := seen[key]; !ok { seen[key] = p } } } out := make([]Param, 0, len(seen)) for _, p := range seen { out = append(out, p) } sort.Slice(out, func(i, j int) bool { return out[i].Code < out[j].Code }) return out } func alignParamTypes(params []Param, schema []Param) []Param { if len(params) == 0 || len(schema) == 0 { return params } codeType := make(map[string]string, len(schema)) for _, p := range schema { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if strings.TrimSpace(p.Type) != "" { codeType[key] = p.Type } } if len(codeType) == 0 { return params } for i, p := range params { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if t, ok := codeType[key]; ok && strings.TrimSpace(t) != "" { params[i].Type = t } } return params } func computeCreateOnly(createParams []Param, modifyParams []Param) map[string]struct{} { modifyCodes := make(map[string]struct{}, len(modifyParams)) for _, p := range modifyParams { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } modifyCodes[key] = struct{}{} } createOnly := make(map[string]struct{}) for _, p := range createParams { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if _, ok := modifyCodes[key]; !ok { createOnly[key] = struct{}{} } } return createOnly } func markCreateOnly(schema []Param, createOnly map[string]struct{}) []Param { if len(schema) == 0 || len(createOnly) == 0 { return schema } for i, p := range schema { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if _, ok := createOnly[key]; ok { schema[i].CreateOnly = true } } return schema } func filterCreateOnly(schema []Param) []Param { if len(schema) == 0 { return []Param{} } result := make([]Param, 0, len(schema)) for _, p := range schema { if p.CreateOnly { result = append(result, p) } } return result } func filterCreateOnlyRequired(schema []Param) []Param { if len(schema) == 0 { return []Param{} } result := make([]Param, 0, len(schema)) for _, p := range schema { if p.CreateOnly && p.Required { result = append(result, p) } } return result } func analyzeParams(usesBool *bool, usesInt64 *bool, usesString *bool, hasDefaults *bool, needsBoolDefault *bool, needsInt64Default *bool, needsStringDefault *bool, params []Param) { for _, p := range params { switch strings.ToLower(p.Type) { case "bool": *usesBool = true if p.Default != "" { *needsBoolDefault = true *hasDefaults = true } case "int", "int64", "number": *usesInt64 = true if p.Default != "" { *needsInt64Default = true *hasDefaults = true } default: *usesString = true if p.Default != "" { *needsStringDefault = true *hasDefaults = true } } } } func buildSubresourceForceNewCodes(sr *GenSubresource, createOnly map[string]struct{}) map[string]struct{} { forceNew := map[string]struct{}{} if sr.ModifyOpName == "" { for _, p := range sr.SchemaParams { key := strings.ToLower(strings.TrimSpace(p.Code)) if key != "" { forceNew[key] = struct{}{} } } return forceNew } for key := range createOnly { forceNew[key] = struct{}{} } for _, p := range sr.DeleteParams { key := strings.ToLower(strings.TrimSpace(p.Code)) if key != "" { forceNew[key] = struct{}{} } } return forceNew } func markForceNew(params []Param, forceNew map[string]struct{}) []Param { if len(params) == 0 || len(forceNew) == 0 { return params } for i, p := range params { key := strings.ToLower(strings.TrimSpace(p.Code)) if key == "" { continue } if _, ok := forceNew[key]; ok { params[i].ForceNew = true } } return params } func filterForceNew(params []Param) []Param { result := []Param{} for _, p := range params { if p.ForceNew { result = append(result, p) } } return result } // analyzeJsonPlanMod возвращает true, если хотя бы один параметр является JSON-строкой. // Используется для условного добавления импорта planmodifier в сгенерированные файлы. func analyzeJsonPlanMod(params []Param) bool { for _, p := range params { if p.IsJson { return true } } return false } // hasRestoreCasingParams возвращает true, если есть ref_svc params с RefSvcId > 0 && != 12 // (restore-casing блок в Create/Read/Update использует strings.EqualFold для них). func hasRestoreCasingParams(params []Param) bool { for _, p := range params { if p.RefSvcId > 0 && p.RefSvcId != 12 && strings.EqualFold(strings.TrimSpace(p.Type), "string") { return true } } return false } // analyzeNeedsStrings возвращает true, если среди params есть хотя бы один строковый параметр. // Используется для условного добавления импорта "strings" (EqualFold в Update). func analyzeNeedsStrings(params []Param) bool { for _, p := range params { t := strings.ToLower(strings.TrimSpace(p.Type)) if t != "bool" && t != "int" && t != "int64" && t != "number" { return true } } return false } func analyzePlanModifiers(needsBool *bool, needsInt64 *bool, needsString *bool, params []Param) { for _, p := range params { if !p.ForceNew { continue } switch strings.ToLower(strings.TrimSpace(p.Type)) { case "bool": *needsBool = true case "int", "int64", "number": *needsInt64 = true default: *needsString = true } } }