Skip to content

Commit dd9689b

Browse files
committed
fix sqlbuilder
1 parent f62f11d commit dd9689b

3 files changed

Lines changed: 215 additions & 50 deletions

File tree

sqlbuilder.go

Lines changed: 167 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,71 @@
11
package qsql
22

3+
import (
4+
"strconv"
5+
"strings"
6+
)
7+
38
type SqlBuilder struct {
4-
innerBuilder *SqlBuilder
5-
table []string
6-
7-
whereStr []string
8-
whereParams []interface{}
9-
whereOrStr []string
10-
whereOrParams []interface{}
11-
groupByStr []string
12-
havingStr []string
13-
havingParams []interface{}
14-
havingOrStr []string
15-
havingOrParams []interface{}
16-
orderByStr []string
17-
offset int
18-
limit int
19-
}
20-
21-
func NewSqlBuilder(table string) *SqlBuilder {
9+
table []string
10+
initArg []interface{}
11+
12+
whereStr []string
13+
whereArg []interface{}
14+
whereInStr []string
15+
whereInArg [][]interface{}
16+
17+
// TODO: how to treat or
18+
whereOrStr []string
19+
whereOrArg []interface{}
20+
whereOrInStr []string
21+
whereOrInArg [][]interface{}
22+
23+
groupByStr []string
24+
havingStr []string
25+
havingArg []interface{}
26+
havingOrStr []string
27+
havingOrArg []interface{}
28+
orderByStr []string
29+
offset int
30+
limit int
31+
}
32+
33+
func NewSqlBuilder(table string, args ...interface{}) *SqlBuilder {
2234
return &SqlBuilder{
23-
table: []string{table},
35+
table: []string{table},
36+
initArg: args,
2437
}
2538
}
2639

2740
func (b *SqlBuilder) Copy() *SqlBuilder {
2841
n := &SqlBuilder{
29-
innerBuilder: b.innerBuilder,
30-
table: make([]string, len(b.table)),
31-
whereStr: make([]string, len(b.whereStr)),
32-
whereParams: make([]interface{}, len(b.whereParams)),
33-
whereOrStr: make([]string, len(b.whereOrStr)),
34-
whereOrParams: make([]interface{}, len(b.whereOrParams)),
35-
groupByStr: make([]string, len(b.groupByStr)),
36-
havingStr: make([]string, len(b.havingStr)),
37-
havingParams: make([]interface{}, len(b.havingParams)),
38-
havingOrStr: make([]string, len(b.havingOrStr)),
39-
havingOrParams: make([]interface{}, len(b.havingOrParams)),
40-
orderByStr: make([]string, len(b.orderByStr)),
41-
offset: b.offset,
42-
limit: b.limit,
42+
table: make([]string, len(b.table)),
43+
whereStr: make([]string, len(b.whereStr)),
44+
whereArg: make([]interface{}, len(b.whereArg)),
45+
whereOrStr: make([]string, len(b.whereOrStr)),
46+
whereOrArg: make([]interface{}, len(b.whereOrArg)),
47+
groupByStr: make([]string, len(b.groupByStr)),
48+
havingStr: make([]string, len(b.havingStr)),
49+
havingArg: make([]interface{}, len(b.havingArg)),
50+
havingOrStr: make([]string, len(b.havingOrStr)),
51+
havingOrArg: make([]interface{}, len(b.havingOrArg)),
52+
orderByStr: make([]string, len(b.orderByStr)),
53+
offset: b.offset,
54+
limit: b.limit,
4355
}
4456
copy(n.table, b.table)
4557
copy(n.whereStr, b.whereStr)
46-
copy(n.whereParams, b.whereParams)
58+
copy(n.whereArg, b.whereArg)
4759
copy(n.whereOrStr, b.whereOrStr)
48-
copy(n.whereOrParams, b.whereOrParams)
60+
copy(n.whereOrArg, b.whereOrArg)
4961
copy(n.groupByStr, b.groupByStr)
5062
copy(n.havingStr, b.havingStr)
51-
copy(n.havingParams, b.havingParams)
63+
copy(n.havingArg, b.havingArg)
5264
copy(n.havingOrStr, b.havingOrStr)
53-
copy(n.havingOrParams, b.havingOrParams)
54-
65+
copy(n.havingOrArg, b.havingOrArg)
66+
n.orderByStr = b.orderByStr
67+
n.offset = b.offset
68+
n.limit = b.limit
5569
return n
5670
}
5771

@@ -62,13 +76,30 @@ func (b *SqlBuilder) Joins(table string) *SqlBuilder {
6276

6377
func (b *SqlBuilder) Where(cond string, args ...interface{}) *SqlBuilder {
6478
b.whereStr = append(b.whereStr, cond)
65-
b.whereParams = append(b.whereParams, args...)
79+
b.whereArg = append(b.whereArg, args...)
80+
return b
81+
}
82+
func (b *SqlBuilder) WhereIn(column string, args []interface{}) *SqlBuilder {
83+
if len(args) == 0 {
84+
return b
85+
}
86+
b.whereInStr = append(b.whereInStr, column)
87+
b.whereInArg = append(b.whereInArg, args)
6688
return b
6789
}
6890

69-
func (b *SqlBuilder) Or(cond string, args ...interface{}) *SqlBuilder {
91+
func (b *SqlBuilder) WhereOr(cond string, args ...interface{}) *SqlBuilder {
7092
b.whereOrStr = append(b.whereOrStr, cond)
71-
b.whereOrParams = append(b.whereOrParams, args...)
93+
b.whereOrArg = append(b.whereOrArg, args...)
94+
return b
95+
}
96+
97+
func (b *SqlBuilder) WhereOrIn(cond string, args []interface{}) *SqlBuilder {
98+
if len(args) == 0 {
99+
return b
100+
}
101+
b.whereOrInStr = append(b.whereOrInStr, cond)
102+
b.whereOrInArg = append(b.whereOrInArg, args)
72103
return b
73104
}
74105

@@ -78,12 +109,12 @@ func (b *SqlBuilder) GroupBy(cond ...string) *SqlBuilder {
78109
}
79110
func (b *SqlBuilder) Having(cond string, args ...interface{}) *SqlBuilder {
80111
b.havingStr = append(b.havingStr, cond)
81-
b.havingParams = append(b.havingParams, args...)
112+
b.havingArg = append(b.havingArg, args...)
82113
return b
83114
}
84115
func (b *SqlBuilder) HavingOr(cond string, args ...interface{}) *SqlBuilder {
85116
b.havingOrStr = append(b.havingOrStr, cond)
86-
b.havingOrParams = append(b.havingOrParams, args...)
117+
b.havingOrArg = append(b.havingOrArg, args...)
87118
return b
88119
}
89120

@@ -99,6 +130,98 @@ func (b *SqlBuilder) Limit(limit int) *SqlBuilder {
99130
b.limit = limit
100131
return b
101132
}
133+
func (b *SqlBuilder) buildWhere() (string, []interface{}) {
134+
args := []interface{}{}
135+
if len(b.whereStr) == 0 && len(b.whereOrStr) == 0 {
136+
return "", args
137+
}
138+
139+
query := "WHERE "
140+
if len(b.whereStr) > 0 {
141+
query += "(" + strings.Join(b.whereStr, " AND ") + ") "
142+
args = append(args, b.whereArg...)
143+
}
144+
if len(b.whereOrStr) > 0 {
145+
if len(b.whereStr) > 0 {
146+
query += "OR "
147+
}
148+
query += "(" + strings.Join(b.whereOrStr, " OR ") + ") "
149+
args = append(args, b.whereOrArg...)
150+
}
151+
return query, args
152+
}
153+
func (b *SqlBuilder) buildGroupBy() string {
154+
if len(b.groupByStr) == 0 {
155+
return ""
156+
}
157+
return "GROUP BY " + strings.Join(b.groupByStr, ", ") + " "
158+
}
159+
func (b *SqlBuilder) buildHaving() (string, []interface{}) {
160+
args := []interface{}{}
161+
if len(b.havingStr) == 0 && len(b.havingOrStr) == 0 {
162+
return "", args
163+
}
164+
query := "HAVING "
165+
if len(b.havingStr) > 0 {
166+
query += "(" + strings.Join(b.havingStr, " AND ") + ") "
167+
args = append(args, b.havingArg...)
168+
}
169+
if len(b.havingOrStr) > 0 {
170+
if len(b.havingStr) > 0 {
171+
query += "OR "
172+
}
173+
query += "(" + strings.Join(b.havingOrStr, " OR ") + ") "
174+
args = append(args, b.havingOrArg...)
175+
}
176+
return query, args
177+
}
178+
func (b *SqlBuilder) buildOrderBy() string {
179+
if len(b.orderByStr) == 0 {
180+
return ""
181+
}
182+
return "ORDER BY " + strings.Join(b.orderByStr, ", ") + " "
183+
}
184+
func (b *SqlBuilder) buildOffset() string {
185+
if b.offset == 0 {
186+
return ""
187+
}
188+
return "OFFSET " + strconv.Itoa(b.offset) + " "
189+
}
190+
func (b *SqlBuilder) buildLimit() string {
191+
if b.limit == 0 {
192+
return ""
193+
}
194+
return "LIMIT " + strconv.Itoa(b.limit) + " "
195+
}
196+
102197
func (b *SqlBuilder) Select(column ...string) (string, []interface{}) {
103-
return "TODO", nil
198+
if len(b.table) == 0 {
199+
panic("table not set")
200+
}
201+
selectStr := "*"
202+
if len(column) > 0 {
203+
selectStr = strings.Join(column, ", ")
204+
}
205+
args := b.initArg
206+
query := "SELECT " + selectStr + " "
207+
query += "FROM " + strings.Join(b.table, " ") + " "
208+
209+
whereStr, whereArg := b.buildWhere()
210+
if len(whereStr) > 0 {
211+
query += whereStr
212+
args = append(args, whereArg...)
213+
}
214+
215+
query += b.buildGroupBy()
216+
217+
havingStr, havingArg := b.buildHaving()
218+
if len(havingStr) > 0 {
219+
query += havingStr
220+
args = append(args, havingArg...)
221+
}
222+
223+
query += b.buildOrderBy()
224+
query += b.buildOffset()
225+
query += b.buildLimit()
226+
return query, args
104227
}

sqlbuilder_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package qsql
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestSqlBuilder(t *testing.T) {
9+
sb := NewSqlBuilder("tmp tb1")
10+
fmt.Println(sb.Select("*"))
11+
12+
sb.Joins("INNER JOIN tmp1 tb2 ON tb2.id=tb2.tmp_id")
13+
fmt.Println(sb.Select("*"))
14+
15+
sb.Where("1=?", 0)
16+
fmt.Println(sb.Select("*"))
17+
18+
sb.WhereOr("1=1")
19+
fmt.Println(sb.Select("*"))
20+
21+
sb.GroupBy("tb1.id")
22+
fmt.Println(sb.Select("*"))
23+
24+
sb.GroupBy("tb2.id")
25+
fmt.Println(sb.Select("*"))
26+
27+
sb.Having("count(tb1.id)>?", 2)
28+
fmt.Println(sb.Select("*"))
29+
30+
sb.Offset(0)
31+
fmt.Println(sb.Select("*"))
32+
sb.Offset(1)
33+
fmt.Println(sb.Select("*"))
34+
35+
sb.Limit(0)
36+
fmt.Println(sb.Select("*"))
37+
sb.Limit(1)
38+
fmt.Println(sb.Select("*"))
39+
40+
mTable, args := sb.Select("id")
41+
fmt.Println(NewSqlBuilder("("+mTable+") tmp", args...).Select("*"))
42+
}

where_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ package qsql
22

33
import "testing"
44

5-
func TestStmtWhereIn(t *testing.T) {
6-
sqlite3Output := StmtWhereIn(0, 3, DRV_NAME_SQLITE3)
5+
func TestStmtIn(t *testing.T) {
6+
sqlite3Output := StmtIn(0, 3, DRV_NAME_SQLITE3)
77
if sqlite3Output != "?,?,?" {
88
t.Fatalf("expect '?,?,?', but: %s", sqlite3Output)
99
}
10-
pgOutput := StmtWhereIn(0, 3, DRV_NAME_POSTGRES)
10+
pgOutput := StmtIn(0, 3, DRV_NAME_POSTGRES)
1111
if pgOutput != ":0,:1,:2" {
1212
t.Fatalf("expect ':0,:1,:2', but: %s", pgOutput)
1313
}
14-
pgOutput1 := StmtWhereIn(1, 3, DRV_NAME_POSTGRES)
14+
pgOutput1 := StmtIn(1, 3, DRV_NAME_POSTGRES)
1515
if pgOutput1 != ":1,:2,:3" {
1616
t.Fatalf("expect ':1,:2,:3', but: %s", pgOutput1)
1717
}
18-
msOutput := StmtWhereIn(0, 3, DRV_NAME_SQLSERVER)
18+
msOutput := StmtIn(0, 3, DRV_NAME_SQLSERVER)
1919
if msOutput != "@p0,@p1,@p2" {
2020
t.Fatalf("expect '@p0,@p1,@p2', but@ %s", msOutput)
2121
}
22-
msOutput1 := StmtWhereIn(1, 3, DRV_NAME_SQLSERVER)
22+
msOutput1 := StmtIn(1, 3, DRV_NAME_SQLSERVER)
2323
if msOutput1 != "@p1,@p2,@p3" {
2424
t.Fatalf("expect '@p1,@p2,@p3', but@ %s", msOutput1)
2525
}

0 commit comments

Comments
 (0)