-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtable.go
113 lines (96 loc) · 2.38 KB
/
table.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
package gorm
import (
"errors"
"fmt"
"reflect"
"strings"
)
// CreateTable will create a new table based upon the DataObject given
func (db *DatabaseConnection) CreateTable(obj DataObject) error {
var query strings.Builder
t := reflect.TypeOf(obj).Elem()
db.log("Creating table ", t.Name(), "...")
query.WriteString("CREATE TABLE ")
query.WriteString(db.Schema)
query.WriteByte('.')
query.WriteString(t.Name())
query.WriteString(" (\n\t")
hasPk := false
everInserted := false
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
isPrimary := f.Tag.Get("primary") == "true"
if isPrimary {
if hasPk {
return errors.New("Multiple PKs defined")
}
db.pkCache[t] = f.Name
hasPk = true
}
everInserted = getColumnDef(&query, f, isPrimary, everInserted)
}
if !hasPk {
return errors.New("No PK defined")
}
query.WriteString("\n);")
db.log(query.String())
_, err := db.connection.Exec(query.String())
return errorWithQuery(err, query.String())
}
// DropTable will drop the table related the given DataObject
func (db *DatabaseConnection) DropTable(obj DataObject) error {
table := reflect.TypeOf(obj).Name()
db.log("Dropping table ", table, "...")
query := fmt.Sprintf("DROP TABLE %s.%s", db.Schema, table)
_, err := db.connection.Exec(query)
return errorWithQuery(err, query)
}
func getColumnDef(s *strings.Builder, f reflect.StructField, isPrimary, everInserted bool) bool {
if f.Tag.Get("exclude") == "true" {
return everInserted
}
if isFlattenableStruct(f) {
for i := 0; i < f.Type.NumField(); i++ {
everInserted = getColumnDef(s, f.Type.Field(i), false, everInserted)
}
return everInserted
}
if !isSupported(f) {
return everInserted
}
if everInserted {
s.WriteString(",\n\t")
}
isUnique := f.Tag.Get("unique") == "true"
size, hasSize := f.Tag.Lookup("size")
fkObj, hasFkObj := f.Tag.Lookup("fk")
fkID, hasFkID := f.Tag.Lookup("fkid")
s.WriteString(f.Name)
s.WriteByte('\t')
if isPrimary {
s.WriteString("SERIAL PRIMARY KEY")
return true
}
s.WriteString(golangToPostgresTypes[f.Type.Kind()])
if hasSize {
s.WriteByte('(')
s.WriteString(size)
s.WriteByte(')')
}
if isUnique {
s.WriteString(" UNIQUE")
}
if hasFkObj {
s.WriteString(" REFERENCES ")
s.WriteString(fkObj)
s.WriteRune('(')
if hasFkID {
s.WriteString(fkID)
} else {
s.WriteString(fkObj)
s.WriteString("ID")
}
s.WriteRune(')')
}
return true
}