func fieldAssignmentTypeToModel(model *RelationalModelDefinition, ut *design.UserTypeDefinition, utype, mtype string) string { // Get a sortable slice of field names var keys []string for k := range model.RelationalFields { keys = append(keys, k) } sort.Strings(keys) var fieldAssignments []string for _, fname := range keys { field := model.RelationalFields[fname] var mpointer, upointer bool mpointer = field.Nullable obj := ut.ToObject() definition := ut.Definition() if field.Datatype == "" { continue } for key := range obj { gfield := obj[key] if field.Underscore() == key || field.DatabaseFieldName == key { // this is our field if gfield.Type.IsObject() || definition.IsPrimitivePointer(key) { upointer = true } else { // set it explicitly because we're reusing the same bool upointer = false } var prefix string if upointer != mpointer { prefix = "*" } fa := fmt.Sprintf("\t%s.%s = %s%s.%s", mtype, fname, prefix, utype, codegen.Goify(key, true)) fieldAssignments = append(fieldAssignments, fa) } } } return strings.Join(fieldAssignments, "\n") }
// GoTypeTransform produces Go code that initializes the data structure defined by target from an // instance of the data structure described by source. The algorithm matches object fields by name // or using the value of the "transform:key" attribute metadata when present. // The function returns an error if target is not compatible with source (different type, fields of // different type etc). It ignores fields in target that don't have a match in source. func GoTypeTransform(source, target *design.UserTypeDefinition, targetPkg, funcName string) (string, error) { var impl string var err error switch { case source.IsObject(): if !target.IsObject() { return "", fmt.Errorf("source is an object but target type is %s", target.Type.Name()) } impl, err = transformObject(source.ToObject(), target.ToObject(), targetPkg, target.TypeName, "source", "target", 1) case source.IsArray(): if !target.IsArray() { return "", fmt.Errorf("source is an array but target type is %s", target.Type.Name()) } impl, err = transformArray(source.ToArray(), target.ToArray(), targetPkg, "source", "target", 1) case source.IsHash(): if !target.IsHash() { return "", fmt.Errorf("source is a hash but target type is %s", target.Type.Name()) } impl, err = transformHash(source.ToHash(), target.ToHash(), targetPkg, "source", "target", 1) default: panic("cannot transform primitive types") // bug } if err != nil { return "", err } t := GoTypeRef(target, nil, 0) if strings.HasPrefix(t, "*") && len(targetPkg) > 0 { t = fmt.Sprintf("*%s.%s", targetPkg, t[1:]) } data := map[string]interface{}{ "Name": funcName, "Source": source, "Target": target, "TargetRef": t, "TargetPkg": targetPkg, "Impl": impl, } return RunTemplate(transformT, data), nil }