|
1 | 1 | package qsql |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "strconv" |
5 | 4 | "strings" |
6 | 5 | ) |
7 | 6 |
|
8 | 7 | type SqlBuilder struct { |
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 |
| 8 | + drvName string |
| 9 | + buff strings.Builder |
| 10 | + args []interface{} |
31 | 11 | } |
32 | 12 |
|
33 | | -func NewSqlBuilder(table string, args ...interface{}) *SqlBuilder { |
34 | | - return &SqlBuilder{ |
35 | | - table: []string{table}, |
36 | | - initArg: args, |
| 13 | +func NewSqlBuilder(drvName ...string) *SqlBuilder { |
| 14 | + b := &SqlBuilder{} |
| 15 | + if len(drvName) > 0 { |
| 16 | + b.drvName = drvName[0] |
| 17 | + } else { |
| 18 | + b.drvName = DRV_NAME_SQLITE3 |
37 | 19 | } |
| 20 | + return b |
38 | 21 | } |
39 | 22 |
|
40 | | -func (b *SqlBuilder) Copy() *SqlBuilder { |
41 | | - n := &SqlBuilder{ |
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, |
55 | | - } |
56 | | - copy(n.table, b.table) |
57 | | - copy(n.whereStr, b.whereStr) |
58 | | - copy(n.whereArg, b.whereArg) |
59 | | - copy(n.whereOrStr, b.whereOrStr) |
60 | | - copy(n.whereOrArg, b.whereOrArg) |
61 | | - copy(n.groupByStr, b.groupByStr) |
62 | | - copy(n.havingStr, b.havingStr) |
63 | | - copy(n.havingArg, b.havingArg) |
64 | | - copy(n.havingOrStr, b.havingOrStr) |
65 | | - copy(n.havingOrArg, b.havingOrArg) |
66 | | - n.orderByStr = b.orderByStr |
67 | | - n.offset = b.offset |
68 | | - n.limit = b.limit |
69 | | - return n |
| 23 | +func (b *SqlBuilder) String() string { |
| 24 | + return b.buff.String() |
70 | 25 | } |
71 | | - |
72 | | -func (b *SqlBuilder) Joins(table string) *SqlBuilder { |
73 | | - b.table = append(b.table, table) |
74 | | - return b |
| 26 | +func (b *SqlBuilder) Args() []interface{} { |
| 27 | + return b.args |
75 | 28 | } |
76 | 29 |
|
77 | | -func (b *SqlBuilder) Where(cond string, args ...interface{}) *SqlBuilder { |
78 | | - b.whereStr = append(b.whereStr, cond) |
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 |
| 30 | +func (b *SqlBuilder) Add(key string, args ...interface{}) *SqlBuilder { |
| 31 | + if len(key) > 0 { |
| 32 | + b.buff.WriteString(key) |
85 | 33 | } |
86 | | - b.whereInStr = append(b.whereInStr, column) |
87 | | - b.whereInArg = append(b.whereInArg, args) |
| 34 | + if len(args) > 0 { |
| 35 | + b.args = append(b.args, args...) |
| 36 | + } |
| 37 | + b.buff.WriteString("\n") |
88 | 38 | return b |
89 | 39 | } |
90 | 40 |
|
91 | | -func (b *SqlBuilder) WhereOr(cond string, args ...interface{}) *SqlBuilder { |
92 | | - b.whereOrStr = append(b.whereOrStr, cond) |
93 | | - b.whereOrArg = append(b.whereOrArg, args...) |
94 | | - return b |
| 41 | +func (b *SqlBuilder) AddTab(key string, args ...interface{}) *SqlBuilder { |
| 42 | + b.buff.WriteString(" ") |
| 43 | + return b.Add(key, args) |
95 | 44 | } |
96 | | - |
97 | | -func (b *SqlBuilder) WhereOrIn(cond string, args []interface{}) *SqlBuilder { |
98 | | - if len(args) == 0 { |
| 45 | +func (b *SqlBuilder) AddTabOk(ok bool, key string, args ...interface{}) *SqlBuilder { |
| 46 | + if !ok { |
99 | 47 | return b |
100 | 48 | } |
101 | | - b.whereOrInStr = append(b.whereOrInStr, cond) |
102 | | - b.whereOrInArg = append(b.whereOrInArg, args) |
103 | | - return b |
104 | | -} |
105 | | - |
106 | | -func (b *SqlBuilder) GroupBy(cond ...string) *SqlBuilder { |
107 | | - b.groupByStr = append(b.groupByStr, cond...) |
108 | | - return b |
109 | | -} |
110 | | -func (b *SqlBuilder) Having(cond string, args ...interface{}) *SqlBuilder { |
111 | | - b.havingStr = append(b.havingStr, cond) |
112 | | - b.havingArg = append(b.havingArg, args...) |
113 | | - return b |
114 | | -} |
115 | | -func (b *SqlBuilder) HavingOr(cond string, args ...interface{}) *SqlBuilder { |
116 | | - b.havingOrStr = append(b.havingOrStr, cond) |
117 | | - b.havingOrArg = append(b.havingOrArg, args...) |
118 | | - return b |
| 49 | + return b.AddTab(key, args...) |
119 | 50 | } |
120 | 51 |
|
121 | | -func (b *SqlBuilder) OrderBy(cond string) *SqlBuilder { |
122 | | - b.orderByStr = append(b.orderByStr, cond) |
123 | | - return b |
124 | | -} |
125 | | -func (b *SqlBuilder) Offset(offset int) *SqlBuilder { |
126 | | - b.offset = offset |
127 | | - return b |
128 | | -} |
129 | | -func (b *SqlBuilder) Limit(limit int) *SqlBuilder { |
130 | | - b.limit = limit |
131 | | - return b |
132 | | -} |
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 "" |
| 52 | +func (b *SqlBuilder) In(in []interface{}) string { |
| 53 | + if len(in) == 0 { |
| 54 | + panic("need condition") |
187 | 55 | } |
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) + " " |
| 56 | + b.args = append(b.args, in...) |
| 57 | + return stmtIn(len(b.args)-1, len(in), b.drvName) |
195 | 58 | } |
196 | 59 |
|
197 | | -func (b *SqlBuilder) Select(column ...string) (string, []interface{}) { |
198 | | - if len(b.table) == 0 { |
199 | | - panic("table not set") |
200 | | - } |
201 | | - selectStr := "*" |
| 60 | +func (b *SqlBuilder) Select(column ...string) string { |
202 | 61 | if len(column) > 0 { |
203 | | - selectStr = strings.Join(column, ", ") |
| 62 | + return strings.Join(column, ", ") |
| 63 | + } else { |
| 64 | + return "*" |
204 | 65 | } |
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...) |
| 66 | +} |
| 67 | +func (b *SqlBuilder) SelectStruct(obj interface{}) string { |
| 68 | + fields, err := reflectInsertStruct(obj, b.drvName) |
| 69 | + if err != nil { |
| 70 | + panic(err) |
221 | 71 | } |
222 | | - |
223 | | - query += b.buildOrderBy() |
224 | | - query += b.buildOffset() |
225 | | - query += b.buildLimit() |
226 | | - return query, args |
| 72 | + return fields.Names |
227 | 73 | } |
0 commit comments