mirror of
https://gitee.com/johng/gf
synced 2026-07-06 21:45:34 +08:00
add function Having for gdb.Model
This commit is contained in:
@ -2,22 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := `user u LEFT JOIN user_detail ud ON(ud.id=u.id) LEFT JOIN user_stats us ON(us.id=u.id)`
|
||||
split := " JOIN "
|
||||
as := "my-as"
|
||||
if gstr.Contains(s, split) {
|
||||
// For join table.
|
||||
array := gstr.Split(s, split)
|
||||
array[len(array)-1], _ = gregex.ReplaceString(`(.+) ON`, fmt.Sprintf(`$1 AS %s ON`, as), array[len(array)-1])
|
||||
s = gstr.Join(array, split)
|
||||
} else {
|
||||
// For base table.
|
||||
s = gstr.TrimRight(s) + " AS " + as
|
||||
}
|
||||
fmt.Println(s)
|
||||
a := []interface{}{1}
|
||||
fmt.Println(a[1])
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ type Model struct {
|
||||
whereHolder []*whereHolder // Condition strings for where operation.
|
||||
groupBy string // Used for "group by" statement.
|
||||
orderBy string // Used for "order by" statement.
|
||||
having []interface{} // Used for "having..." statement.
|
||||
start int // Used for "select ... start, limit ..." statement.
|
||||
limit int // Used for "select ... start, limit ..." statement.
|
||||
option int // Option for extra operation features.
|
||||
|
||||
@ -32,6 +32,17 @@ func (m *Model) Where(where interface{}, args ...interface{}) *Model {
|
||||
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.
|
||||
func (m *Model) Having(having interface{}, args ...interface{}) *Model {
|
||||
model := m.getModel()
|
||||
model.having = []interface{}{
|
||||
having, args,
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
// WherePri does the same logic as Model.Where except that if the parameter <where>
|
||||
// is a single condition like int/string/float/slice, it treats the condition as the primary
|
||||
// key value. That is, if primary key is "id" and given <where> parameter as "123", the
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"github.com/gogf/gf/internal/empty"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -159,7 +160,9 @@ func (m *Model) formatCondition(limit bool) (conditionWhere string, conditionExt
|
||||
switch v.operator {
|
||||
case gWHERE_HOLDER_WHERE:
|
||||
if conditionWhere == "" {
|
||||
newWhere, newArgs := formatWhere(m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0)
|
||||
newWhere, newArgs := formatWhere(
|
||||
m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0,
|
||||
)
|
||||
if len(newWhere) > 0 {
|
||||
conditionWhere = newWhere
|
||||
conditionArgs = newArgs
|
||||
@ -169,7 +172,9 @@ func (m *Model) formatCondition(limit bool) (conditionWhere string, conditionExt
|
||||
fallthrough
|
||||
|
||||
case gWHERE_HOLDER_AND:
|
||||
newWhere, newArgs := formatWhere(m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0)
|
||||
newWhere, newArgs := formatWhere(
|
||||
m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0,
|
||||
)
|
||||
if len(newWhere) > 0 {
|
||||
if conditionWhere[0] == '(' {
|
||||
conditionWhere = fmt.Sprintf(`%s AND (%s)`, conditionWhere, newWhere)
|
||||
@ -180,7 +185,9 @@ func (m *Model) formatCondition(limit bool) (conditionWhere string, conditionExt
|
||||
}
|
||||
|
||||
case gWHERE_HOLDER_OR:
|
||||
newWhere, newArgs := formatWhere(m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0)
|
||||
newWhere, newArgs := formatWhere(
|
||||
m.db, v.where, v.args, m.option&OPTION_OMITEMPTY > 0,
|
||||
)
|
||||
if len(newWhere) > 0 {
|
||||
if conditionWhere[0] == '(' {
|
||||
conditionWhere = fmt.Sprintf(`%s OR (%s)`, conditionWhere, newWhere)
|
||||
@ -201,6 +208,15 @@ func (m *Model) formatCondition(limit bool) (conditionWhere string, conditionExt
|
||||
if m.orderBy != "" {
|
||||
conditionExtra += " ORDER BY " + m.orderBy
|
||||
}
|
||||
if len(m.having) > 0 {
|
||||
havingStr, havingArgs := formatWhere(
|
||||
m.db, m.having[0], gconv.Interfaces(m.having[1]), m.option&OPTION_OMITEMPTY > 0,
|
||||
)
|
||||
if len(havingStr) > 0 {
|
||||
conditionExtra += " HAVING " + havingStr
|
||||
conditionArgs = append(conditionArgs, havingArgs...)
|
||||
}
|
||||
}
|
||||
if m.limit != 0 {
|
||||
if m.start >= 0 {
|
||||
conditionExtra += fmt.Sprintf(" LIMIT %d,%d", m.start, m.limit)
|
||||
|
||||
@ -2200,3 +2200,29 @@ func Test_Model_Cache(t *testing.T) {
|
||||
t.Assert(one["passport"], "user_200")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_Having(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
all, err := db.Table(table).Where("id > 1").Having("id > 8").All()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(all), 2)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
all, err := db.Table(table).Where("id > 1").Having("id > ?", 8).All()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(all), 2)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
all, err := db.Table(table).Where("id > ?", 1).Having("id > ?", 8).All()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(all), 2)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
all, err := db.Table(table).Where("id > ?", 1).Having("id", 8).All()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(all), 1)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user