-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
field.go
118 lines (100 loc) · 2.84 KB
/
field.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package ds
import (
"fmt"
"reflect"
"strings"
)
// Field describes a field
type Field struct {
Name string
Tag string
Type string
}
func (table *Table) getFields() []Field {
return structFieldsToFields(allFields(table.typeOf))
}
func structFieldsToFields(fields []reflect.StructField) []Field {
newFields := make([]Field, len(fields))
for i, field := range fields {
newFields[i] = Field{
Name: field.Name,
Tag: field.Tag.Get("ds"),
Type: field.Type.Name(),
}
}
return newFields
}
func (table *Table) getKeysFromFields() (string, []string, []string, error) {
var primaryKey string
var indexes []string
var uniques []string
fields := allFields(table.typeOf)
if len(fields) == 0 {
return "", nil, nil, fmt.Errorf("type '%s' has no fields", table.typeOf.Name())
}
for _, field := range fields {
tag := field.Tag.Get("ds")
if len(tag) == 0 {
continue
}
table.log.Debug("Field: %s, tag: %s", field.Name, tag)
if strings.Contains(tag, "primary") {
if len(primaryKey) > 0 {
table.log.Error("Cannot specify multiple primary keys")
return "", nil, nil, fmt.Errorf("cannot specify multiple primary keys")
}
table.log.Debug("Primary key field '%s'", field.Name)
primaryKey = field.Name
} else if strings.Contains(tag, "index") {
table.log.Debug("Adding indexed field '%s'", field.Name)
indexes = append(indexes, field.Name)
} else if strings.Contains(tag, "unique") {
table.log.Debug("Adding unique field '%s'", field.Name)
uniques = append(uniques, field.Name)
} else {
table.log.Error("Unknown struct tag '%s' on field '%s'", tag, field.Name)
return "", nil, nil, fmt.Errorf("unknown struct tag '%s' on field '%s'", tag, field.Name)
}
}
if len(primaryKey) <= 0 {
table.log.Error("A primary key is required")
return "", nil, nil, fmt.Errorf("a primary key is required")
}
return primaryKey, indexes, uniques, nil
}
func compareFields(oldFields, newFields []Field) error {
var oldPrimary Field
var newPrimary Field
for _, newField := range newFields {
if newField.Tag == "primary" {
newPrimary = newField
}
for _, oldField := range oldFields {
if oldField.Tag == "primary" {
oldPrimary = oldField
}
if newField.Name != oldField.Name {
continue
}
if newField.Type != oldField.Type {
return fmt.Errorf("cannot change type of field '%s' without migration", newField.Name)
}
if newField.Tag != oldField.Tag {
return fmt.Errorf("cannot change tag of field '%s' without migration", newField.Name)
}
}
}
if newPrimary.Name != oldPrimary.Name {
return fmt.Errorf("cannot change name of primary field '%s'", oldPrimary.Name)
}
return nil
}
func allFields(typeOf reflect.Type) []reflect.StructField {
i := 0
fields := make([]reflect.StructField, typeOf.NumField())
for i < typeOf.NumField() {
fields[i] = typeOf.Field(i)
i++
}
return fields
}