2021-01-17 21:46:25 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
|
|
|
|
package gdb
|
|
|
|
|
2020-04-20 22:36:28 +08:00
|
|
|
import (
|
2021-05-02 12:17:06 +08:00
|
|
|
"fmt"
|
2020-04-20 22:36:28 +08:00
|
|
|
"strings"
|
|
|
|
)
|
2020-03-13 17:21:30 +08:00
|
|
|
|
2021-02-08 17:57:21 +08:00
|
|
|
// Where sets the condition statement for the model. The parameter `where` can be type of
|
2020-03-13 17:21:30 +08:00
|
|
|
// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
|
|
|
|
// multiple conditions will be joined into where statement using "AND".
|
|
|
|
// Eg:
|
|
|
|
// Where("uid=10000")
|
|
|
|
// Where("uid", 10000)
|
|
|
|
// Where("money>? AND name like ?", 99999, "vip_%")
|
|
|
|
// Where("uid", 1).Where("name", "john")
|
|
|
|
// Where("status IN (?)", g.Slice{1,2,3})
|
|
|
|
// Where("age IN(?,?)", 18, 50)
|
|
|
|
// Where(User{ Id : 1, UserName : "john"})
|
|
|
|
func (m *Model) Where(where interface{}, args ...interface{}) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
if model.whereHolder == nil {
|
|
|
|
model.whereHolder = make([]*whereHolder, 0)
|
|
|
|
}
|
|
|
|
model.whereHolder = append(model.whereHolder, &whereHolder{
|
2020-11-29 23:47:57 +08:00
|
|
|
operator: whereHolderWhere,
|
2020-03-13 17:21:30 +08:00
|
|
|
where: where,
|
|
|
|
args: args,
|
|
|
|
})
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2020-04-11 10:11:52 +08:00
|
|
|
// Having sets the having statement for the model.
|
|
|
|
// The parameters of this function usage are as the same as function Where.
|
|
|
|
// See Where.
|
|
|
|
func (m *Model) Having(having interface{}, args ...interface{}) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
model.having = []interface{}{
|
|
|
|
having, args,
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2021-02-08 17:57:21 +08:00
|
|
|
// WherePri does the same logic as Model.Where except that if the parameter `where`
|
2020-03-13 17:21:30 +08:00
|
|
|
// is a single condition like int/string/float/slice, it treats the condition as the primary
|
2021-02-08 17:57:21 +08:00
|
|
|
// key value. That is, if primary key is "id" and given `where` parameter as "123", the
|
2020-04-26 21:31:55 +08:00
|
|
|
// WherePri function treats the condition as "id=123", but Model.Where treats the condition
|
|
|
|
// as string "123".
|
2020-03-13 17:21:30 +08:00
|
|
|
func (m *Model) WherePri(where interface{}, args ...interface{}) *Model {
|
|
|
|
if len(args) > 0 {
|
|
|
|
return m.Where(where, args...)
|
|
|
|
}
|
|
|
|
newWhere := GetPrimaryKeyCondition(m.getPrimaryKey(), where)
|
|
|
|
return m.Where(newWhere[0], newWhere[1:]...)
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// WhereBetween builds `xxx BETWEEN x AND y` statement.
|
|
|
|
func (m *Model) WhereBetween(column string, min, max interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereLike builds `xxx LIKE x` statement.
|
|
|
|
func (m *Model) WhereLike(column string, like interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s LIKE ?`, m.db.QuoteWord(column)), like)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereIn builds `xxx IN (x)` statement.
|
|
|
|
func (m *Model) WhereIn(column string, in interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s IN (?)`, m.db.QuoteWord(column)), in)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereNull builds `xxx IS NULL` statement.
|
|
|
|
func (m *Model) WhereNull(columns ...string) *Model {
|
|
|
|
model := m
|
|
|
|
for _, column := range columns {
|
|
|
|
model = m.Where(fmt.Sprintf(`%s IS NULL`, m.db.QuoteWord(column)))
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereNotBetween builds `xxx NOT BETWEEN x AND y` statement.
|
|
|
|
func (m *Model) WhereNotBetween(column string, min, max interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s NOT BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereNotLike builds `xxx NOT LIKE x` statement.
|
|
|
|
func (m *Model) WhereNotLike(column string, like interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s NOT LIKE ?`, m.db.QuoteWord(column)), like)
|
|
|
|
}
|
|
|
|
|
2021-05-19 22:33:50 +08:00
|
|
|
// WhereNot builds `xxx != x` statement.
|
|
|
|
func (m *Model) WhereNot(column string, value interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s != ?`, m.db.QuoteWord(column)), value)
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// WhereNotIn builds `xxx NOT IN (x)` statement.
|
|
|
|
func (m *Model) WhereNotIn(column string, in interface{}) *Model {
|
|
|
|
return m.Where(fmt.Sprintf(`%s NOT IN (?)`, m.db.QuoteWord(column)), in)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereNotNull builds `xxx IS NOT NULL` statement.
|
|
|
|
func (m *Model) WhereNotNull(columns ...string) *Model {
|
|
|
|
model := m
|
|
|
|
for _, column := range columns {
|
|
|
|
model = m.Where(fmt.Sprintf(`%s IS NOT NULL`, m.db.QuoteWord(column)))
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOr adds "OR" condition to the where statement.
|
|
|
|
func (m *Model) WhereOr(where interface{}, args ...interface{}) *Model {
|
2020-03-13 17:21:30 +08:00
|
|
|
model := m.getModel()
|
|
|
|
if model.whereHolder == nil {
|
|
|
|
model.whereHolder = make([]*whereHolder, 0)
|
|
|
|
}
|
|
|
|
model.whereHolder = append(model.whereHolder, &whereHolder{
|
2021-05-02 12:17:06 +08:00
|
|
|
operator: whereHolderOr,
|
2020-03-13 17:21:30 +08:00
|
|
|
where: where,
|
|
|
|
args: args,
|
|
|
|
})
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// WhereOrBetween builds `xxx BETWEEN x AND y` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrBetween(column string, min, max interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrLike builds `xxx LIKE x` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrLike(column string, like interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s LIKE ?`, m.db.QuoteWord(column)), like)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrIn builds `xxx IN (x)` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrIn(column string, in interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s IN (?)`, m.db.QuoteWord(column)), in)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrNull builds `xxx IS NULL` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrNull(columns ...string) *Model {
|
|
|
|
model := m
|
|
|
|
for _, column := range columns {
|
|
|
|
model = m.WhereOr(fmt.Sprintf(`%s IS NULL`, m.db.QuoteWord(column)))
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrNotBetween builds `xxx NOT BETWEEN x AND y` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrNotBetween(column string, min, max interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s NOT BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrNotLike builds `xxx NOT LIKE x` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrNotLike(column string, like interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s NOT LIKE ?`, m.db.QuoteWord(column)), like)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrNotIn builds `xxx NOT IN (x)` statement.
|
|
|
|
func (m *Model) WhereOrNotIn(column string, in interface{}) *Model {
|
|
|
|
return m.WhereOr(fmt.Sprintf(`%s NOT IN (?)`, m.db.QuoteWord(column)), in)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WhereOrNotNull builds `xxx IS NOT NULL` statement in `OR` conditions.
|
|
|
|
func (m *Model) WhereOrNotNull(columns ...string) *Model {
|
|
|
|
model := m
|
|
|
|
for _, column := range columns {
|
|
|
|
model = m.WhereOr(fmt.Sprintf(`%s IS NOT NULL`, m.db.QuoteWord(column)))
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// Group sets the "GROUP BY" statement for the model.
|
|
|
|
func (m *Model) Group(groupBy string) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
model.groupBy = m.db.QuoteString(groupBy)
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// And adds "AND" condition to the where statement.
|
|
|
|
// Deprecated, use Where instead.
|
|
|
|
func (m *Model) And(where interface{}, args ...interface{}) *Model {
|
2020-03-13 17:21:30 +08:00
|
|
|
model := m.getModel()
|
|
|
|
if model.whereHolder == nil {
|
|
|
|
model.whereHolder = make([]*whereHolder, 0)
|
|
|
|
}
|
|
|
|
model.whereHolder = append(model.whereHolder, &whereHolder{
|
2021-05-02 12:17:06 +08:00
|
|
|
operator: whereHolderAnd,
|
2020-03-13 17:21:30 +08:00
|
|
|
where: where,
|
|
|
|
args: args,
|
|
|
|
})
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// Or adds "OR" condition to the where statement.
|
|
|
|
// Deprecated, use WhereOr instead.
|
|
|
|
func (m *Model) Or(where interface{}, args ...interface{}) *Model {
|
|
|
|
return m.WhereOr(where, args...)
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GroupBy is alias of Model.Group.
|
|
|
|
// See Model.Group.
|
2021-03-30 13:43:08 +08:00
|
|
|
// Deprecated, use Group instead.
|
2020-03-13 17:21:30 +08:00
|
|
|
func (m *Model) GroupBy(groupBy string) *Model {
|
|
|
|
return m.Group(groupBy)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Order sets the "ORDER BY" statement for the model.
|
2020-04-20 22:36:28 +08:00
|
|
|
func (m *Model) Order(orderBy ...string) *Model {
|
2021-05-02 12:17:06 +08:00
|
|
|
if len(orderBy) == 0 {
|
|
|
|
return m
|
|
|
|
}
|
2020-03-13 17:21:30 +08:00
|
|
|
model := m.getModel()
|
2020-04-20 22:36:28 +08:00
|
|
|
model.orderBy = m.db.QuoteString(strings.Join(orderBy, " "))
|
2020-03-13 17:21:30 +08:00
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// OrderAsc sets the "ORDER BY xxx ASC" statement for the model.
|
|
|
|
func (m *Model) OrderAsc(column string) *Model {
|
|
|
|
if len(column) == 0 {
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
model := m.getModel()
|
|
|
|
model.orderBy = m.db.QuoteWord(column) + " ASC"
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// OrderDesc sets the "ORDER BY xxx DESC" statement for the model.
|
|
|
|
func (m *Model) OrderDesc(column string) *Model {
|
|
|
|
if len(column) == 0 {
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
model := m.getModel()
|
|
|
|
model.orderBy = m.db.QuoteWord(column) + " DESC"
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// OrderRandom sets the "ORDER BY RANDOM()" statement for the model.
|
2021-05-02 16:42:34 +08:00
|
|
|
func (m *Model) OrderRandom() *Model {
|
2021-05-02 12:17:06 +08:00
|
|
|
model := m.getModel()
|
|
|
|
model.orderBy = "RAND()"
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2020-03-13 17:21:30 +08:00
|
|
|
// OrderBy is alias of Model.Order.
|
|
|
|
// See Model.Order.
|
2021-03-30 13:43:08 +08:00
|
|
|
// Deprecated, use Order instead.
|
2020-03-13 17:21:30 +08:00
|
|
|
func (m *Model) OrderBy(orderBy string) *Model {
|
|
|
|
return m.Order(orderBy)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit sets the "LIMIT" statement for the model.
|
2021-02-08 17:57:21 +08:00
|
|
|
// The parameter `limit` can be either one or two number, if passed two number is passed,
|
2020-03-13 17:21:30 +08:00
|
|
|
// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
|
|
|
|
// statement.
|
|
|
|
func (m *Model) Limit(limit ...int) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
switch len(limit) {
|
|
|
|
case 1:
|
|
|
|
model.limit = limit[0]
|
|
|
|
case 2:
|
|
|
|
model.start = limit[0]
|
|
|
|
model.limit = limit[1]
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// Offset sets the "OFFSET" statement for the model.
|
|
|
|
// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
|
|
|
|
func (m *Model) Offset(offset int) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
model.offset = offset
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// Distinct forces the query to only return distinct results.
|
|
|
|
func (m *Model) Distinct() *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
model.distinct = "DISTINCT "
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2020-03-13 17:21:30 +08:00
|
|
|
// Page sets the paging number for the model.
|
2021-02-08 17:57:21 +08:00
|
|
|
// The parameter `page` is started from 1 for paging.
|
2020-08-04 09:22:21 +08:00
|
|
|
// Note that, it differs that the Limit function starts from 0 for "LIMIT" statement.
|
2020-03-13 17:21:30 +08:00
|
|
|
func (m *Model) Page(page, limit int) *Model {
|
|
|
|
model := m.getModel()
|
|
|
|
if page <= 0 {
|
|
|
|
page = 1
|
|
|
|
}
|
|
|
|
model.start = (page - 1) * limit
|
|
|
|
model.limit = limit
|
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
|
|
|
// ForPage is alias of Model.Page.
|
|
|
|
// See Model.Page.
|
2021-03-30 13:43:08 +08:00
|
|
|
// Deprecated, use Page instead.
|
2020-03-13 17:21:30 +08:00
|
|
|
func (m *Model) ForPage(page, limit int) *Model {
|
|
|
|
return m.Page(page, limit)
|
|
|
|
}
|