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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
package builder
type optype byte
const (
condType optype = iota // only conditions
selectType // select
insertType // insert
updateType // update
deleteType // delete
)
type join struct {
joinType string
joinTable string
joinCond Cond
}
type Builder struct {
optype
tableName string
cond Cond
selects []string
joins []join
inserts Eq
updates []Eq
}
func Select(cols ...string) *Builder {
builder := &Builder{cond: NewCond()}
return builder.Select(cols...)
}
func Insert(eq Eq) *Builder {
builder := &Builder{cond: NewCond()}
return builder.Insert(eq)
}
func Update(updates ...Eq) *Builder {
builder := &Builder{cond: NewCond()}
return builder.Update(updates...)
}
func Delete(conds ...Cond) *Builder {
builder := &Builder{cond: NewCond()}
return builder.Delete(conds...)
}
func (b *Builder) Where(cond Cond) *Builder {
b.cond = b.cond.And(cond)
return b
}
func (b *Builder) From(tableName string) *Builder {
b.tableName = tableName
return b
}
func (b *Builder) Into(tableName string) *Builder {
b.tableName = tableName
return b
}
func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
switch joinCond.(type) {
case Cond:
b.joins = append(b.joins, join{joinType, joinTable, joinCond.(Cond)})
case string:
b.joins = append(b.joins, join{joinType, joinTable, Expr(joinCond.(string))})
}
return b
}
func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("INNER", joinTable, joinCond)
}
func (b *Builder) LeftJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("LEFT", joinTable, joinCond)
}
func (b *Builder) RightJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("RIGHT", joinTable, joinCond)
}
func (b *Builder) CrossJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("CROSS", joinTable, joinCond)
}
func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("FULL", joinTable, joinCond)
}
func (b *Builder) Select(cols ...string) *Builder {
b.selects = cols
b.optype = selectType
return b
}
func (b *Builder) And(cond Cond) *Builder {
b.cond = And(b.cond, cond)
return b
}
func (b *Builder) Or(cond Cond) *Builder {
b.cond = Or(b.cond, cond)
return b
}
func (b *Builder) Insert(eq Eq) *Builder {
b.inserts = eq
b.optype = insertType
return b
}
func (b *Builder) Update(updates ...Eq) *Builder {
b.updates = updates
b.optype = updateType
return b
}
func (b *Builder) Delete(conds ...Cond) *Builder {
b.cond = b.cond.And(conds...)
b.optype = deleteType
return b
}
func (b *Builder) WriteTo(w Writer) error {
switch b.optype {
case condType:
return b.cond.WriteTo(w)
case selectType:
return b.selectWriteTo(w)
case insertType:
return b.insertWriteTo(w)
case updateType:
return b.updateWriteTo(w)
case deleteType:
return b.deleteWriteTo(w)
}
return ErrNotSupportType
}
// ToSQL convert a builder to SQL and args
func (b *Builder) ToSQL() (string, []interface{}, error) {
w := NewWriter()
if err := b.WriteTo(w); err != nil {
return "", nil, err
}
return w.writer.String(), w.args, nil
}
// ToSQL convert a builder or condtions to SQL and args
func ToSQL(cond interface{}) (string, []interface{}, error) {
switch cond.(type) {
case Cond:
return condToSQL(cond.(Cond))
case *Builder:
return cond.(*Builder).ToSQL()
}
return "", nil, ErrNotSupportType
}
|