1// Copyright 2015 TiDB Author. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package orm
16
17import (
18	"fmt"
19	"strconv"
20	"strings"
21)
22
23// TiDBQueryBuilder is the SQL build
24type TiDBQueryBuilder struct {
25	Tokens []string
26}
27
28// Select will join the fields
29func (qb *TiDBQueryBuilder) Select(fields ...string) QueryBuilder {
30	qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
31	return qb
32}
33
34// ForUpdate add the FOR UPDATE clause
35func (qb *TiDBQueryBuilder) ForUpdate() QueryBuilder {
36	qb.Tokens = append(qb.Tokens, "FOR UPDATE")
37	return qb
38}
39
40// From join the tables
41func (qb *TiDBQueryBuilder) From(tables ...string) QueryBuilder {
42	qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
43	return qb
44}
45
46// InnerJoin INNER JOIN the table
47func (qb *TiDBQueryBuilder) InnerJoin(table string) QueryBuilder {
48	qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
49	return qb
50}
51
52// LeftJoin LEFT JOIN the table
53func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
54	qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
55	return qb
56}
57
58// RightJoin RIGHT JOIN the table
59func (qb *TiDBQueryBuilder) RightJoin(table string) QueryBuilder {
60	qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
61	return qb
62}
63
64// On join with on cond
65func (qb *TiDBQueryBuilder) On(cond string) QueryBuilder {
66	qb.Tokens = append(qb.Tokens, "ON", cond)
67	return qb
68}
69
70// Where join the Where cond
71func (qb *TiDBQueryBuilder) Where(cond string) QueryBuilder {
72	qb.Tokens = append(qb.Tokens, "WHERE", cond)
73	return qb
74}
75
76// And join the and cond
77func (qb *TiDBQueryBuilder) And(cond string) QueryBuilder {
78	qb.Tokens = append(qb.Tokens, "AND", cond)
79	return qb
80}
81
82// Or join the or cond
83func (qb *TiDBQueryBuilder) Or(cond string) QueryBuilder {
84	qb.Tokens = append(qb.Tokens, "OR", cond)
85	return qb
86}
87
88// In join the IN (vals)
89func (qb *TiDBQueryBuilder) In(vals ...string) QueryBuilder {
90	qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
91	return qb
92}
93
94// OrderBy join the Order by fields
95func (qb *TiDBQueryBuilder) OrderBy(fields ...string) QueryBuilder {
96	qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
97	return qb
98}
99
100// Asc join the asc
101func (qb *TiDBQueryBuilder) Asc() QueryBuilder {
102	qb.Tokens = append(qb.Tokens, "ASC")
103	return qb
104}
105
106// Desc join the desc
107func (qb *TiDBQueryBuilder) Desc() QueryBuilder {
108	qb.Tokens = append(qb.Tokens, "DESC")
109	return qb
110}
111
112// Limit join the limit num
113func (qb *TiDBQueryBuilder) Limit(limit int) QueryBuilder {
114	qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
115	return qb
116}
117
118// Offset join the offset num
119func (qb *TiDBQueryBuilder) Offset(offset int) QueryBuilder {
120	qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
121	return qb
122}
123
124// GroupBy join the Group by fields
125func (qb *TiDBQueryBuilder) GroupBy(fields ...string) QueryBuilder {
126	qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
127	return qb
128}
129
130// Having join the Having cond
131func (qb *TiDBQueryBuilder) Having(cond string) QueryBuilder {
132	qb.Tokens = append(qb.Tokens, "HAVING", cond)
133	return qb
134}
135
136// Update join the update table
137func (qb *TiDBQueryBuilder) Update(tables ...string) QueryBuilder {
138	qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
139	return qb
140}
141
142// Set join the set kv
143func (qb *TiDBQueryBuilder) Set(kv ...string) QueryBuilder {
144	qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
145	return qb
146}
147
148// Delete join the Delete tables
149func (qb *TiDBQueryBuilder) Delete(tables ...string) QueryBuilder {
150	qb.Tokens = append(qb.Tokens, "DELETE")
151	if len(tables) != 0 {
152		qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
153	}
154	return qb
155}
156
157// InsertInto join the insert SQL
158func (qb *TiDBQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
159	qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
160	if len(fields) != 0 {
161		fieldsStr := strings.Join(fields, CommaSpace)
162		qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
163	}
164	return qb
165}
166
167// Values join the Values(vals)
168func (qb *TiDBQueryBuilder) Values(vals ...string) QueryBuilder {
169	valsStr := strings.Join(vals, CommaSpace)
170	qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
171	return qb
172}
173
174// Subquery join the sub as alias
175func (qb *TiDBQueryBuilder) Subquery(sub string, alias string) string {
176	return fmt.Sprintf("(%s) AS %s", sub, alias)
177}
178
179// String join all Tokens
180func (qb *TiDBQueryBuilder) String() string {
181	return strings.Join(qb.Tokens, " ")
182}
183