forked from slicebit/qb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
constraint.go
129 lines (107 loc) · 3.44 KB
/
constraint.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
119
120
121
122
123
124
125
126
127
128
129
package qb
import (
"fmt"
"strings"
)
// Null generates generic null constraint
func Null() ConstraintElem {
return ConstraintElem{"NULL"}
}
// NotNull generates generic not null constraint
func NotNull() ConstraintElem {
return ConstraintElem{"NOT NULL"}
}
// Default generates generic default constraint
func Default(value interface{}) ConstraintElem {
return ConstraintElem{fmt.Sprintf("DEFAULT '%v'", value)}
}
// Unique generates generic unique constraint
// if cols are given, then composite unique constraint will be built
func Unique() ConstraintElem {
return ConstraintElem{"UNIQUE"}
}
// Constraint generates a custom constraint due to variation of adapters
func Constraint(name string) ConstraintElem {
return ConstraintElem{name}
}
// ConstraintElem is the definition of column & table constraints
type ConstraintElem struct {
Name string
}
// String returns the constraint as an sql clause
func (c ConstraintElem) String() string {
return c.Name
}
// PrimaryKey generates a primary key constraint of any table
func PrimaryKey(cols ...string) PrimaryKeyConstraint {
return PrimaryKeyConstraint{cols}
}
// PrimaryKeyConstraint is the definition of primary key constraints of any table
type PrimaryKeyConstraint struct {
Columns []string
}
// String returns the primary key constraints as an sql clause
func (c PrimaryKeyConstraint) String(dialect Dialect) string {
cols := []string{}
for _, col := range c.Columns {
cols = append(cols, dialect.Escape(col))
}
return fmt.Sprintf("PRIMARY KEY(%s)", strings.Join(cols, ", "))
}
// ForeignKey generates a foreign key for table constraint definitions
func ForeignKey() ForeignKeyConstraints {
return ForeignKeyConstraints{[]Reference{}}
}
// ForeignKeyConstraints is the definition of foreign keys in any table
type ForeignKeyConstraints struct {
Refs []Reference
}
func (c ForeignKeyConstraints) String(adapter Dialect) string {
clauses := []string{}
for _, ref := range c.Refs {
clauses = append(clauses, fmt.Sprintf(
"\tFOREIGN KEY(%s) REFERENCES %s(%s)",
strings.Join(adapter.EscapeAll(ref.Cols), ", "),
adapter.Escape(ref.RefTable),
strings.Join(adapter.EscapeAll(ref.RefCols), ", "),
))
}
return strings.Join(clauses, ",\n")
}
// Ref generates a reference after the definition of foreign key by chaining
func (c ForeignKeyConstraints) Ref(col string, refTable string, refCol string) ForeignKeyConstraints {
for k, v := range c.Refs {
if refTable == v.RefTable {
c.Refs[k].Cols = append(c.Refs[k].Cols, col)
c.Refs[k].RefCols = append(c.Refs[k].RefCols, refCol)
return c
}
}
ref := Reference{[]string{}, refTable, []string{}}
ref.Cols = append(ref.Cols, col)
ref.RefCols = append(ref.RefCols, refCol)
c.Refs = append(c.Refs, ref)
return c
}
// Reference is the main struct for defining foreign key references
type Reference struct {
Cols []string
RefTable string
RefCols []string
}
// UniqueKey generates UniqueKeyConstraint given columns as strings
func UniqueKey(cols ...string) UniqueKeyConstraint {
return UniqueKeyConstraint{
fmt.Sprintf("u_%s", strings.Join(cols, "_")),
cols,
}
}
// UniqueKeyConstraint is the base struct to define composite unique indexes of tables
type UniqueKeyConstraint struct {
name string
cols []string
}
// String generates composite unique indices as sql clause
func (c UniqueKeyConstraint) String(dialect Dialect) string {
return fmt.Sprintf("CONSTRAINT %s UNIQUE(%s)", c.name, strings.Join(dialect.EscapeAll(c.cols), ", "))
}