forked from gobuffalo/fizz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
foreign_keys.go
96 lines (85 loc) · 2.25 KB
/
foreign_keys.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
package fizz
import (
"encoding/json"
"fmt"
"sort"
"strings"
)
type ForeignKeyRef struct {
Table string
Columns []string
}
type ForeignKey struct {
Name string
Column string
References ForeignKeyRef
Options Options
}
func (f ForeignKey) String() string {
refs := fmt.Sprintf(`{"%s": ["%s"]}`, f.References.Table, strings.Join(f.References.Columns, `", "`))
var opts map[string]interface{}
if f.Options == nil {
opts = make(map[string]interface{})
} else {
opts = f.Options
}
o := make([]string, 0, len(opts))
for k, v := range opts {
vv, _ := json.Marshal(v)
o = append(o, fmt.Sprintf("%s: %s", k, string(vv)))
}
sort.SliceStable(o, func(i, j int) bool { return o[i] < o[j] })
return fmt.Sprintf(`t.ForeignKey("%s", %s, {%s})`, f.Column, refs, strings.Join(o, ", "))
}
func (f fizzer) AddForeignKey(table string, column string, refs interface{}, options Options) error {
fkr, err := parseForeignKeyRef(refs)
if err != nil {
return err
}
fk := ForeignKey{
Column: column,
References: fkr,
Options: options,
}
if options["name"] != nil {
var ok bool
fk.Name, ok = options["name"].(string)
if !ok {
return fmt.Errorf(`expected options field "name" to be of type "string" but got "%T"`, options["name"])
}
} else {
fk.Name = fmt.Sprintf("%s_%s_%s_fk", table, fk.References.Table, strings.Join(fk.References.Columns, "_"))
}
return f.add(f.Bubbler.AddForeignKey(Table{
Name: table,
ForeignKeys: []ForeignKey{fk},
}))
}
func (f fizzer) DropForeignKey(table string, fk string, options Options) error {
return f.add(f.Bubbler.DropForeignKey(Table{
Name: table,
ForeignKeys: []ForeignKey{
{
Name: fk,
Options: options,
},
},
}))
}
func parseForeignKeyRef(refs interface{}) (ForeignKeyRef, error) {
fkr := ForeignKeyRef{}
refMap, ok := refs.(map[string]interface{})
if !ok {
return fkr, fmt.Errorf(`invalid references format %s\nmust be "{"table": ["colum1", "column2"]}"`, refs)
}
if len(refMap) != 1 {
return fkr, fmt.Errorf("only one table is supported as Foreign key reference")
}
for table, columns := range refMap {
fkr.Table = table
for _, c := range columns.([]interface{}) {
fkr.Columns = append(fkr.Columns, fmt.Sprintf("%s", c))
}
}
return fkr, nil
}