improve prefix feature for package gdb

This commit is contained in:
John Guo
2021-11-17 21:29:46 +08:00
parent 6ad7baeb2c
commit f2ef7454c2
8 changed files with 272 additions and 77 deletions

View File

@ -376,7 +376,7 @@ func formatSql(sql string, args []interface{}) (newSql string, newArgs []interfa
return handleArguments(sql, args)
}
type formatWhereInput struct {
type formatWhereHolderInput struct {
Where interface{}
Args []interface{}
OmitNil bool
@ -386,8 +386,8 @@ type formatWhereInput struct {
Prefix string // Field prefix, eg: "user.", "order.".
}
// formatWhere formats where statement and its arguments for `Where` and `Having` statements.
func formatWhere(db DB, in formatWhereInput) (newWhere string, newArgs []interface{}) {
// formatWhereHolder formats where statement and its arguments for `Where` and `Having` statements.
func formatWhereHolder(db DB, in formatWhereHolderInput) (newWhere string, newArgs []interface{}) {
var (
buffer = bytes.NewBuffer(nil)
reflectInfo = utils.OriginValueAndKind(in.Where)
@ -454,8 +454,8 @@ func formatWhere(db DB, in formatWhereInput) (newWhere string, newArgs []interfa
var (
reflectType = reflectInfo.OriginValue.Type()
structField reflect.StructField
data = DataToMapDeep(in.Where)
)
data := DataToMapDeep(in.Where)
if in.Table != "" {
data, _ = db.GetCore().mappingAndFilterData(in.Schema, in.Table, data, true)
}
@ -484,9 +484,7 @@ func formatWhere(db DB, in formatWhereInput) (newWhere string, newArgs []interfa
default:
// Usually a string.
whereStr := gconv.String(in.Where)
// Is `whereStr` a field name which composed as a key-value condition?
// Eg:
// Where("id", 1)
@ -514,9 +512,7 @@ func formatWhere(db DB, in formatWhereInput) (newWhere string, newArgs []interfa
// Regular string and parameter place holder handling.
// Eg:
// Where("id in(?) and name=?", g.Slice{1,2,3}, "john")
i := 0
for {
if i >= len(in.Args) {
break
@ -608,13 +604,13 @@ func formatWhereInterfaces(db DB, where []interface{}, buffer *bytes.Buffer, new
}
type formatWhereKeyValueInput struct {
Db DB
Buffer *bytes.Buffer
Args []interface{}
Key string
Value interface{}
OmitEmpty bool
Prefix string // Field prefix, eg: "user.", "order.".
Db DB // Db is the underlying DB object for current operation.
Buffer *bytes.Buffer // Buffer is the sql statement string without Args for current operation.
Args []interface{} // Args is the full arguments of current operation.
Key string // The field name, eg: "id", "name", etc.
Value interface{} // The field value, can be any types.
OmitEmpty bool // Ignores current condition key if `value` is empty.
Prefix string // Field prefix, eg: "user", "order", etc.
}
// formatWhereKeyValue handles each key-value pair of the parameter map.

View File

@ -95,7 +95,7 @@ func (c *Core) Model(tableNameQueryOrStruct ...interface{}) *Model {
if len(tableNameQueryOrStruct) > 1 {
conditionStr := gconv.String(tableNameQueryOrStruct[0])
if gstr.Contains(conditionStr, "?") {
tableStr, extraArgs = formatWhere(c.db, formatWhereInput{
tableStr, extraArgs = formatWhereHolder(c.db, formatWhereHolderInput{
Where: conditionStr,
Args: tableNameQueryOrStruct[1:],
OmitNil: false,

View File

@ -37,21 +37,6 @@ func (m *Model) Where(where interface{}, args ...interface{}) *Model {
return model
}
// WherePrefix performs as Where, but it adds prefix to each field in where statement.
func (m *Model) WherePrefix(prefix string, where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]ModelWhereHolder, 0)
}
model.whereHolder = append(model.whereHolder, ModelWhereHolder{
Operator: whereHolderOperatorWhere,
Where: where,
Args: args,
Prefix: prefix,
})
return model
}
// Having sets the having statement for the model.
// The parameters of this function usage are as the same as function Where.
// See Where.
@ -79,6 +64,9 @@ func (m *Model) WherePri(where interface{}, args ...interface{}) *Model {
// Wheref builds condition string using fmt.Sprintf and arguments.
// Note that if the number of `args` is more than the placeholder in `format`,
// the extra `args` will be used as the where condition arguments of the Model.
// Eg:
// Wheref(`amount<? and status=%s`, "paid", 100) => WHERE `amount`<100 and status='paid'
// Wheref(`amount<%d and status=%s`, 100, "paid") => WHERE `amount`<100 and status='paid'
func (m *Model) Wheref(format string, args ...interface{}) *Model {
var (
placeHolderCount = gstr.Count(format, "?")
@ -109,53 +97,53 @@ func (m *Model) WhereGTE(column string, value interface{}) *Model {
// WhereBetween builds `column BETWEEN min AND max` statement.
func (m *Model) WhereBetween(column string, min, max interface{}) *Model {
return m.Wheref(`%s BETWEEN ? AND ?`, m.db.GetCore().QuoteWord(column), min, max)
return m.Wheref(`%s BETWEEN ? AND ?`, m.QuoteWord(column), min, max)
}
// WhereLike builds `column LIKE like` statement.
func (m *Model) WhereLike(column string, like interface{}) *Model {
return m.Wheref(`%s LIKE ?`, m.db.GetCore().QuoteWord(column), like)
return m.Wheref(`%s LIKE ?`, m.QuoteWord(column), like)
}
// WhereIn builds `column IN (in)` statement.
func (m *Model) WhereIn(column string, in interface{}) *Model {
return m.Wheref(`%s IN (?)`, m.db.GetCore().QuoteWord(column), in)
return m.Wheref(`%s IN (?)`, m.QuoteWord(column), in)
}
// WhereNull builds `columns[0] IS NULL AND columns[1] IS NULL ...` statement.
func (m *Model) WhereNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Wheref(`%s IS NULL`, m.db.GetCore().QuoteWord(column))
model = m.Wheref(`%s IS NULL`, m.QuoteWord(column))
}
return model
}
// WhereNotBetween builds `column NOT BETWEEN min AND max` statement.
func (m *Model) WhereNotBetween(column string, min, max interface{}) *Model {
return m.Wheref(`%s NOT BETWEEN ? AND ?`, m.db.GetCore().QuoteWord(column), min, max)
return m.Wheref(`%s NOT BETWEEN ? AND ?`, m.QuoteWord(column), min, max)
}
// WhereNotLike builds `column NOT LIKE like` statement.
func (m *Model) WhereNotLike(column string, like interface{}) *Model {
return m.Wheref(`%s NOT LIKE ?`, m.db.GetCore().QuoteWord(column), like)
return m.Wheref(`%s NOT LIKE ?`, m.QuoteWord(column), like)
}
// WhereNot builds `column != value` statement.
func (m *Model) WhereNot(column string, value interface{}) *Model {
return m.Wheref(`%s != ?`, m.db.GetCore().QuoteWord(column), value)
return m.Wheref(`%s != ?`, m.QuoteWord(column), value)
}
// WhereNotIn builds `column NOT IN (in)` statement.
func (m *Model) WhereNotIn(column string, in interface{}) *Model {
return m.Wheref(`%s NOT IN (?)`, m.db.GetCore().QuoteWord(column), in)
return m.Wheref(`%s NOT IN (?)`, m.QuoteWord(column), in)
}
// WhereNotNull builds `columns[0] IS NOT NULL AND columns[1] IS NOT NULL ...` statement.
func (m *Model) WhereNotNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Wheref(`%s IS NOT NULL`, m.db.GetCore().QuoteWord(column))
model = m.Wheref(`%s IS NOT NULL`, m.QuoteWord(column))
}
return model
}
@ -174,22 +162,10 @@ func (m *Model) WhereOr(where interface{}, args ...interface{}) *Model {
return model
}
// WhereOrPrefix performs as WhereOr, but it adds prefix to each field in where statement.
func (m *Model) WhereOrPrefix(prefix string, where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]ModelWhereHolder, 0)
}
model.whereHolder = append(model.whereHolder, ModelWhereHolder{
Operator: whereHolderOperatorOr,
Where: where,
Args: args,
Prefix: prefix,
})
return model
}
// WhereOrf builds `OR` condition string using fmt.Sprintf and arguments.
// Eg:
// WhereOrf(`amount<? and status=%s`, "paid", 100) => WHERE xxx OR `amount`<100 and status='paid'
// WhereOrf(`amount<%d and status=%s`, 100, "paid") => WHERE xxx OR `amount`<100 and status='paid'
func (m *Model) WhereOrf(format string, args ...interface{}) *Model {
var (
placeHolderCount = gstr.Count(format, "?")
@ -220,48 +196,48 @@ func (m *Model) WhereOrGTE(column string, value interface{}) *Model {
// WhereOrBetween builds `column BETWEEN min AND max` statement in `OR` conditions.
func (m *Model) WhereOrBetween(column string, min, max interface{}) *Model {
return m.WhereOrf(`%s BETWEEN ? AND ?`, m.db.GetCore().QuoteWord(column), min, max)
return m.WhereOrf(`%s BETWEEN ? AND ?`, m.QuoteWord(column), min, max)
}
// WhereOrLike builds `column LIKE like` statement in `OR` conditions.
func (m *Model) WhereOrLike(column string, like interface{}) *Model {
return m.WhereOrf(`%s LIKE ?`, m.db.GetCore().QuoteWord(column), like)
return m.WhereOrf(`%s LIKE ?`, m.QuoteWord(column), like)
}
// WhereOrIn builds `column IN (in)` statement in `OR` conditions.
func (m *Model) WhereOrIn(column string, in interface{}) *Model {
return m.WhereOrf(`%s IN (?)`, m.db.GetCore().QuoteWord(column), in)
return m.WhereOrf(`%s IN (?)`, m.QuoteWord(column), in)
}
// WhereOrNull builds `columns[0] IS NULL OR columns[1] IS NULL ...` statement in `OR` conditions.
func (m *Model) WhereOrNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOrf(`%s IS NULL`, m.db.GetCore().QuoteWord(column))
model = m.WhereOrf(`%s IS NULL`, m.QuoteWord(column))
}
return model
}
// WhereOrNotBetween builds `column NOT BETWEEN min AND max` statement in `OR` conditions.
func (m *Model) WhereOrNotBetween(column string, min, max interface{}) *Model {
return m.WhereOrf(`%s NOT BETWEEN ? AND ?`, m.db.GetCore().QuoteWord(column), min, max)
return m.WhereOrf(`%s NOT BETWEEN ? AND ?`, m.QuoteWord(column), min, max)
}
// WhereOrNotLike builds `column NOT LIKE like` statement in `OR` conditions.
func (m *Model) WhereOrNotLike(column string, like interface{}) *Model {
return m.WhereOrf(`%s NOT LIKE ?`, m.db.GetCore().QuoteWord(column), like)
return m.WhereOrf(`%s NOT LIKE ?`, m.QuoteWord(column), like)
}
// WhereOrNotIn builds `column NOT IN (in)` statement.
func (m *Model) WhereOrNotIn(column string, in interface{}) *Model {
return m.WhereOrf(`%s NOT IN (?)`, m.db.GetCore().QuoteWord(column), in)
return m.WhereOrf(`%s NOT IN (?)`, m.QuoteWord(column), in)
}
// WhereOrNotNull builds `columns[0] IS NOT NULL OR columns[1] IS NOT NULL ...` statement in `OR` conditions.
func (m *Model) WhereOrNotNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOrf(`%s IS NOT NULL`, m.db.GetCore().QuoteWord(column))
model = m.WhereOrf(`%s IS NOT NULL`, m.QuoteWord(column))
}
return model
}
@ -317,7 +293,9 @@ func (m *Model) Page(page, limit int) *Model {
func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWhere string, conditionExtra string, conditionArgs []interface{}) {
autoPrefix := ""
if gstr.Contains(m.tables, " JOIN ") {
autoPrefix = m.db.GetCore().QuoteWord(m.tablesInit)
autoPrefix = m.db.GetCore().QuoteWord(
m.db.GetCore().guessPrimaryTableName(m.tablesInit),
)
}
if len(m.whereHolder) > 0 {
for _, v := range m.whereHolder {
@ -327,7 +305,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
switch v.Operator {
case whereHolderOperatorWhere:
if conditionWhere == "" {
newWhere, newArgs := formatWhere(m.db, formatWhereInput{
newWhere, newArgs := formatWhereHolder(m.db, formatWhereHolderInput{
Where: v.Where,
Args: v.Args,
OmitNil: m.option&optionOmitNilWhere > 0,
@ -345,7 +323,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
fallthrough
case whereHolderOperatorAnd:
newWhere, newArgs := formatWhere(m.db, formatWhereInput{
newWhere, newArgs := formatWhereHolder(m.db, formatWhereHolderInput{
Where: v.Where,
Args: v.Args,
OmitNil: m.option&optionOmitNilWhere > 0,
@ -366,7 +344,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
}
case whereHolderOperatorOr:
newWhere, newArgs := formatWhere(m.db, formatWhereInput{
newWhere, newArgs := formatWhereHolder(m.db, formatWhereHolderInput{
Where: v.Where,
Args: v.Args,
OmitNil: m.option&optionOmitNilWhere > 0,
@ -414,7 +392,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
}
// HAVING.
if len(m.having) > 0 {
havingStr, havingArgs := formatWhere(m.db, formatWhereInput{
havingStr, havingArgs := formatWhereHolder(m.db, formatWhereHolderInput{
Where: m.having[0],
Args: gconv.Interfaces(m.having[1]),
OmitNil: m.option&optionOmitNilWhere > 0,

View File

@ -0,0 +1,184 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// 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
// WherePrefix performs as Where, but it adds prefix to each field in where statement.
// Eg:
// WherePrefix("order", "status", "paid") => WHERE `order`.`status`='paid'
// WherePrefix("order", struct{Status:"paid", "channel":"bank"}) => WHERE `order`.`status`='paid' AND `order`.`channel`='bank'
func (m *Model) WherePrefix(prefix string, where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]ModelWhereHolder, 0)
}
model.whereHolder = append(model.whereHolder, ModelWhereHolder{
Operator: whereHolderOperatorWhere,
Where: where,
Args: args,
Prefix: prefix,
})
return model
}
// WherePrefixLT builds `prefix.column < value` statement.
func (m *Model) WherePrefixLT(prefix string, column string, value interface{}) *Model {
return m.Wheref(`%s.%s < ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WherePrefixLTE builds `prefix.column <= value` statement.
func (m *Model) WherePrefixLTE(prefix string, column string, value interface{}) *Model {
return m.Wheref(`%s.%s <= ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WherePrefixGT builds `prefix.column > value` statement.
func (m *Model) WherePrefixGT(prefix string, column string, value interface{}) *Model {
return m.Wheref(`%s.%s > ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WherePrefixGTE builds `prefix.column >= value` statement.
func (m *Model) WherePrefixGTE(prefix string, column string, value interface{}) *Model {
return m.Wheref(`%s.%s >= ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WherePrefixBetween builds `prefix.column BETWEEN min AND max` statement.
func (m *Model) WherePrefixBetween(prefix string, column string, min, max interface{}) *Model {
return m.Wheref(`%s.%s BETWEEN ? AND ?`, m.QuoteWord(prefix), m.QuoteWord(column), min, max)
}
// WherePrefixLike builds `prefix.column LIKE like` statement.
func (m *Model) WherePrefixLike(prefix string, column string, like interface{}) *Model {
return m.Wheref(`%s.%s LIKE ?`, m.QuoteWord(prefix), m.QuoteWord(column), like)
}
// WherePrefixIn builds `prefix.column IN (in)` statement.
func (m *Model) WherePrefixIn(prefix string, column string, in interface{}) *Model {
return m.Wheref(`%s.%s IN (?)`, m.QuoteWord(prefix), m.QuoteWord(column), in)
}
// WherePrefixNull builds `prefix.columns[0] IS NULL AND prefix.columns[1] IS NULL ...` statement.
func (m *Model) WherePrefixNull(prefix string, columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Wheref(`%s.%s IS NULL`, m.QuoteWord(prefix), m.QuoteWord(column))
}
return model
}
// WherePrefixNotBetween builds `prefix.column NOT BETWEEN min AND max` statement.
func (m *Model) WherePrefixNotBetween(prefix string, column string, min, max interface{}) *Model {
return m.Wheref(`%s.%s NOT BETWEEN ? AND ?`, m.QuoteWord(prefix), m.QuoteWord(column), min, max)
}
// WherePrefixNotLike builds `prefix.column NOT LIKE like` statement.
func (m *Model) WherePrefixNotLike(prefix string, column string, like interface{}) *Model {
return m.Wheref(`%s.%s NOT LIKE ?`, m.QuoteWord(prefix), m.QuoteWord(column), like)
}
// WherePrefixNot builds `prefix.column != value` statement.
func (m *Model) WherePrefixNot(prefix string, column string, value interface{}) *Model {
return m.Wheref(`%s.%s != ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WherePrefixNotIn builds `prefix.column NOT IN (in)` statement.
func (m *Model) WherePrefixNotIn(prefix string, column string, in interface{}) *Model {
return m.Wheref(`%s.%s NOT IN (?)`, m.QuoteWord(prefix), m.QuoteWord(column), in)
}
// WherePrefixNotNull builds `prefix.columns[0] IS NOT NULL AND prefix.columns[1] IS NOT NULL ...` statement.
func (m *Model) WherePrefixNotNull(prefix string, columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Wheref(`%s.%s IS NOT NULL`, m.QuoteWord(prefix), m.QuoteWord(column))
}
return model
}
// WhereOrPrefix performs as WhereOr, but it adds prefix to each field in where statement.
// Eg:
// WhereOrPrefix("order", "status", "paid") => WHERE xxx OR (`order`.`status`='paid')
// WhereOrPrefix("order", struct{Status:"paid", "channel":"bank"}) => WHERE xxx OR (`order`.`status`='paid' AND `order`.`channel`='bank')
func (m *Model) WhereOrPrefix(prefix string, where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]ModelWhereHolder, 0)
}
model.whereHolder = append(model.whereHolder, ModelWhereHolder{
Operator: whereHolderOperatorOr,
Where: where,
Args: args,
Prefix: prefix,
})
return model
}
// WhereOrPrefixLT builds `prefix.column < value` statement in `OR` conditions..
func (m *Model) WhereOrPrefixLT(prefix string, column string, value interface{}) *Model {
return m.WhereOrf(`%s.%s < ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WhereOrPrefixLTE builds `prefix.column <= value` statement in `OR` conditions..
func (m *Model) WhereOrPrefixLTE(prefix string, column string, value interface{}) *Model {
return m.WhereOrf(`%s.%s <= ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WhereOrPrefixGT builds `prefix.column > value` statement in `OR` conditions..
func (m *Model) WhereOrPrefixGT(prefix string, column string, value interface{}) *Model {
return m.WhereOrf(`%s.%s > ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WhereOrPrefixGTE builds `prefix.column >= value` statement in `OR` conditions..
func (m *Model) WhereOrPrefixGTE(prefix string, column string, value interface{}) *Model {
return m.WhereOrf(`%s.%s >= ?`, m.QuoteWord(prefix), m.QuoteWord(column), value)
}
// WhereOrPrefixBetween builds `prefix.column BETWEEN min AND max` statement in `OR` conditions.
func (m *Model) WhereOrPrefixBetween(prefix string, column string, min, max interface{}) *Model {
return m.WhereOrf(`%s.%s BETWEEN ? AND ?`, m.QuoteWord(prefix), m.QuoteWord(column), min, max)
}
// WhereOrPrefixLike builds `prefix.column LIKE like` statement in `OR` conditions.
func (m *Model) WhereOrPrefixLike(prefix string, column string, like interface{}) *Model {
return m.WhereOrf(`%s.%s LIKE ?`, m.QuoteWord(prefix), m.QuoteWord(column), like)
}
// WhereOrPrefixIn builds `prefix.column IN (in)` statement in `OR` conditions.
func (m *Model) WhereOrPrefixIn(prefix string, column string, in interface{}) *Model {
return m.WhereOrf(`%s.%s IN (?)`, m.QuoteWord(prefix), m.QuoteWord(column), in)
}
// WhereOrPrefixNull builds `prefix.columns[0] IS NULL OR prefix.columns[1] IS NULL ...` statement in `OR` conditions.
func (m *Model) WhereOrPrefixNull(prefix string, columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOrf(`%s.%s IS NULL`, m.QuoteWord(prefix), m.QuoteWord(column))
}
return model
}
// WhereOrPrefixNotBetween builds `prefix.column NOT BETWEEN min AND max` statement in `OR` conditions.
func (m *Model) WhereOrPrefixNotBetween(prefix string, column string, min, max interface{}) *Model {
return m.WhereOrf(`%s.%s NOT BETWEEN ? AND ?`, m.QuoteWord(prefix), m.QuoteWord(column), min, max)
}
// WhereOrPrefixNotLike builds `prefix.column NOT LIKE like` statement in `OR` conditions.
func (m *Model) WhereOrPrefixNotLike(prefix string, column string, like interface{}) *Model {
return m.WhereOrf(`%s.%s NOT LIKE ?`, m.QuoteWord(prefix), m.QuoteWord(column), like)
}
// WhereOrPrefixNotIn builds `prefix.column NOT IN (in)` statement.
func (m *Model) WhereOrPrefixNotIn(prefix string, column string, in interface{}) *Model {
return m.WhereOrf(`%s.%s NOT IN (?)`, m.QuoteWord(prefix), m.QuoteWord(column), in)
}
// WhereOrPrefixNotNull builds `prefix.columns[0] IS NOT NULL OR prefix.columns[1] IS NOT NULL ...` statement in `OR` conditions.
func (m *Model) WhereOrPrefixNotNull(prefix string, columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOrf(`%s.%s IS NOT NULL`, m.QuoteWord(prefix), m.QuoteWord(column))
}
return model
}

View File

@ -111,7 +111,7 @@ func (m *Model) FieldCount(column string, as ...string) *Model {
if len(as) > 0 && as[0] != "" {
asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0]))
}
return m.appendFieldsByStr(fmt.Sprintf(`COUNT(%s)%s`, m.db.GetCore().QuoteWord(column), asStr))
return m.appendFieldsByStr(fmt.Sprintf(`COUNT(%s)%s`, m.QuoteWord(column), asStr))
}
// FieldSum formats and appends commonly used field `SUM(column)` to the select fields of model.
@ -120,7 +120,7 @@ func (m *Model) FieldSum(column string, as ...string) *Model {
if len(as) > 0 && as[0] != "" {
asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0]))
}
return m.appendFieldsByStr(fmt.Sprintf(`SUM(%s)%s`, m.db.GetCore().QuoteWord(column), asStr))
return m.appendFieldsByStr(fmt.Sprintf(`SUM(%s)%s`, m.QuoteWord(column), asStr))
}
// FieldMin formats and appends commonly used field `MIN(column)` to the select fields of model.
@ -129,7 +129,7 @@ func (m *Model) FieldMin(column string, as ...string) *Model {
if len(as) > 0 && as[0] != "" {
asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0]))
}
return m.appendFieldsByStr(fmt.Sprintf(`MIN(%s)%s`, m.db.GetCore().QuoteWord(column), asStr))
return m.appendFieldsByStr(fmt.Sprintf(`MIN(%s)%s`, m.QuoteWord(column), asStr))
}
// FieldMax formats and appends commonly used field `MAX(column)` to the select fields of model.
@ -138,7 +138,7 @@ func (m *Model) FieldMax(column string, as ...string) *Model {
if len(as) > 0 && as[0] != "" {
asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0]))
}
return m.appendFieldsByStr(fmt.Sprintf(`MAX(%s)%s`, m.db.GetCore().QuoteWord(column), asStr))
return m.appendFieldsByStr(fmt.Sprintf(`MAX(%s)%s`, m.QuoteWord(column), asStr))
}
// FieldAvg formats and appends commonly used field `AVG(column)` to the select fields of model.
@ -147,7 +147,7 @@ func (m *Model) FieldAvg(column string, as ...string) *Model {
if len(as) > 0 && as[0] != "" {
asStr = fmt.Sprintf(` AS %s`, m.db.GetCore().QuoteWord(as[0]))
}
return m.appendFieldsByStr(fmt.Sprintf(`AVG(%s)%s`, m.db.GetCore().QuoteWord(column), asStr))
return m.appendFieldsByStr(fmt.Sprintf(`AVG(%s)%s`, m.QuoteWord(column), asStr))
}
func (m *Model) appendFieldsByStr(fields string) *Model {

View File

@ -373,7 +373,7 @@ func (m *Model) Min(column string) (float64, error) {
if len(column) == 0 {
return 0, nil
}
value, err := m.Fields(fmt.Sprintf(`MIN(%s)`, m.db.GetCore().QuoteWord(column))).Value()
value, err := m.Fields(fmt.Sprintf(`MIN(%s)`, m.QuoteWord(column))).Value()
if err != nil {
return 0, err
}
@ -385,7 +385,7 @@ func (m *Model) Max(column string) (float64, error) {
if len(column) == 0 {
return 0, nil
}
value, err := m.Fields(fmt.Sprintf(`MAX(%s)`, m.db.GetCore().QuoteWord(column))).Value()
value, err := m.Fields(fmt.Sprintf(`MAX(%s)`, m.QuoteWord(column))).Value()
if err != nil {
return 0, err
}
@ -397,7 +397,7 @@ func (m *Model) Avg(column string) (float64, error) {
if len(column) == 0 {
return 0, nil
}
value, err := m.Fields(fmt.Sprintf(`AVG(%s)`, m.db.GetCore().QuoteWord(column))).Value()
value, err := m.Fields(fmt.Sprintf(`AVG(%s)`, m.QuoteWord(column))).Value()
if err != nil {
return 0, err
}
@ -409,7 +409,7 @@ func (m *Model) Sum(column string) (float64, error) {
if len(column) == 0 {
return 0, nil
}
value, err := m.Fields(fmt.Sprintf(`SUM(%s)`, m.db.GetCore().QuoteWord(column))).Value()
value, err := m.Fields(fmt.Sprintf(`SUM(%s)`, m.QuoteWord(column))).Value()
if err != nil {
return 0, err
}

View File

@ -17,6 +17,15 @@ import (
"github.com/gogf/gf/v2/util/gutil"
)
// QuoteWord checks given string `s` a word,
// if true it quotes `s` with security chars of the database
// and returns the quoted string; or else it returns `s` without any change.
//
// The meaning of a `word` can be considered as a column name.
func (m *Model) QuoteWord(s string) string {
return m.db.GetCore().QuoteWord(s)
}
// TableFields retrieves and returns the fields information of specified table of current
// schema.
//

View File

@ -68,3 +68,31 @@ func Test_Model_WhereOrPrefix(t *testing.T) {
t.Assert(r[3]["id"], "9")
})
}
func Test_Model_WherePrefixLike(t *testing.T) {
var (
table1 = gtime.TimestampNanoStr() + "_table1"
table2 = gtime.TimestampNanoStr() + "_table2"
)
createInitTable(table1)
defer dropTable(table1)
createInitTable(table2)
defer dropTable(table2)
db.SetDebug(true)
gtest.C(t, func(t *gtest.T) {
r, err := db.Model(table1).
FieldsPrefix(table1, "*").
LeftJoinOnField(table2, "id").
WherePrefix(table1, g.Map{
"id": g.Slice{1, 2, 3},
}).
WherePrefix(table2, g.Map{
"id": g.Slice{3, 4, 5},
}).
WherePrefixLike(table2, "nickname", "name%").
Order("id asc").All()
t.AssertNil(err)
t.Assert(len(r), 1)
t.Assert(r[0]["id"], "3")
})
}