11package qsql
22
3+ import (
4+ "strconv"
5+ "strings"
6+ )
7+
38type 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
2740func (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
6377func (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}
79110func (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}
84115func (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+
102197func (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}
0 commit comments