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