github.com/duskeagle/pop@v4.10.1-0.20190417200916-92f2b794aab5+incompatible/soda/cmd/generate/attribute.go (about) 1 package generate 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "github.com/gobuffalo/flect" 9 ) 10 11 var attrNamePattern = regexp.MustCompile(`^\p{L}[\p{L}\d_]*$`) 12 13 type attribute struct { 14 Name flect.Ident 15 OriginalType string 16 GoType string 17 Nullable bool 18 Primary bool 19 PreventValidation bool 20 StructTag string 21 } 22 23 func (a attribute) String() string { 24 if len(a.StructTag) == 0 { 25 a.StructTag = "json" 26 } 27 return fmt.Sprintf("\t%s %s `%s:\"%s\" db:\"%s\"`", a.Name.Pascalize(), a.GoType, a.StructTag, a.Name.Underscore(), a.Name.Underscore()) 28 } 29 30 func (a attribute) IsValidable() bool { 31 return !a.PreventValidation && (a.GoType == "string" || a.GoType == "time.Time" || a.GoType == "int") 32 } 33 34 func newAttribute(base string, model *model) (attribute, error) { 35 col := strings.Split(base, ":") 36 if len(col) == 1 { 37 col = append(col, "string") 38 } 39 40 if !attrNamePattern.MatchString(col[0]) { 41 return attribute{}, fmt.Errorf("%s is not a valid attribute name", col[0]) 42 } 43 44 nullable := strings.HasPrefix(col[1], "nulls.") 45 if !model.HasNulls && nullable { 46 model.HasNulls = true 47 model.Imports = append(model.Imports, "github.com/gobuffalo/nulls") 48 } else if !model.HasSlices && strings.HasPrefix(col[1], "slices.") { 49 model.HasSlices = true 50 model.Imports = append(model.Imports, "github.com/gobuffalo/pop/slices") 51 } else if !model.HasUUID && col[1] == "uuid" { 52 model.HasUUID = true 53 model.Imports = append(model.Imports, "github.com/gofrs/uuid") 54 } 55 56 got := colType(col[1]) 57 if len(col) > 2 { 58 got = col[2] 59 } 60 name := flect.New(col[0]) 61 primary := false 62 if name.String() == "id" { 63 primary = true 64 } 65 a := attribute{ 66 Name: name, 67 OriginalType: col[1], 68 GoType: got, 69 Nullable: nullable, 70 StructTag: model.StructTag, 71 Primary: primary, 72 } 73 74 return a, nil 75 } 76 77 func colType(s string) string { 78 switch strings.ToLower(s) { 79 case "text": 80 return "string" 81 case "time", "timestamp", "datetime": 82 return "time.Time" 83 case "nulls.text": 84 return "nulls.String" 85 case "uuid": 86 return "uuid.UUID" 87 case "json", "jsonb": 88 return "slices.Map" 89 case "[]string": 90 return "slices.String" 91 case "[]int": 92 return "slices.Int" 93 case "slices.float", "[]float", "[]float32", "[]float64": 94 return "slices.Float" 95 case "decimal", "float": 96 return "float64" 97 case "[]byte", "blob": 98 return "[]byte" 99 default: 100 return s 101 } 102 }