Add GroupBy test

This commit is contained in:
Jinzhu 2020-03-08 18:05:22 +08:00
parent ce0e6f9f33
commit a158d1ada0
7 changed files with 79 additions and 15 deletions

View File

@ -135,14 +135,20 @@ func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
}
// Group specify the group method on the find
func (db *DB) Group(column string) (tx *DB) {
func (db *DB) Group(name string) (tx *DB) {
tx = db.getInstance()
tx.Statement.AddClause(clause.GroupBy{
Columns: []clause.Column{{Name: name}},
})
return
}
// Having specify HAVING conditions for GROUP BY
func (db *DB) Having(query interface{}, args ...interface{}) (tx *DB) {
tx = db.getInstance()
tx.Statement.AddClause(clause.GroupBy{
Having: tx.Statement.BuildCondtion(query, args...),
})
return
}

View File

@ -41,7 +41,7 @@ func BenchmarkComplexSelect(b *testing.B) {
clause.Where{Exprs: []clause.Expression{
clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}),
}},
clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}}},
clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}},
clause.Limit{Limit: 10, Offset: 20},
clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
}

View File

@ -3,7 +3,7 @@ package clause
// GroupBy group by clause
type GroupBy struct {
Columns []Column
Having Where
Having []Expression
}
// Name from clause name
@ -21,9 +21,9 @@ func (groupBy GroupBy) Build(builder Builder) {
builder.WriteQuoted(column)
}
if len(groupBy.Having.Exprs) > 0 {
if len(groupBy.Having) > 0 {
builder.Write(" HAVING ")
groupBy.Having.Build(builder)
Where{Exprs: groupBy.Having}.Build(builder)
}
}
@ -31,7 +31,7 @@ func (groupBy GroupBy) Build(builder Builder) {
func (groupBy GroupBy) MergeClause(clause *Clause) {
if v, ok := clause.Expression.(GroupBy); ok {
groupBy.Columns = append(v.Columns, groupBy.Columns...)
groupBy.Having.Exprs = append(v.Having.Exprs, groupBy.Having.Exprs...)
groupBy.Having = append(v.Having, groupBy.Having...)
}
clause.Expression = groupBy
}

View File

@ -16,17 +16,17 @@ func TestGroupBy(t *testing.T) {
{
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
Columns: []clause.Column{{Name: "role"}},
Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}},
Having: []clause.Expression{clause.Eq{"role", "admin"}},
}},
"SELECT * FROM `users` GROUP BY `role` HAVING `role` = ?", []interface{}{"admin"},
},
{
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
Columns: []clause.Column{{Name: "role"}},
Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}},
Having: []clause.Expression{clause.Eq{"role", "admin"}},
}, clause.GroupBy{
Columns: []clause.Column{{Name: "gender"}},
Having: clause.Where{[]clause.Expression{clause.Neq{"gender", "U"}}},
Having: []clause.Expression{clause.Neq{"gender", "U"}},
}},
"SELECT * FROM `users` GROUP BY `role`,`gender` HAVING `role` = ? AND `gender` <> ?", []interface{}{"admin", "U"},
},

View File

@ -145,12 +145,6 @@ func (db *DB) Delete(value interface{}, conds ...interface{}) (tx *DB) {
return
}
//Preloads only preloads relations, don`t touch out
func (db *DB) Preloads(out interface{}) (tx *DB) {
tx = db.getInstance()
return
}
func (db *DB) Count(value interface{}) (tx *DB) {
tx = db.getInstance()
return

62
tests/group_by.go Normal file
View File

@ -0,0 +1,62 @@
package tests
import (
"testing"
"github.com/jinzhu/gorm"
)
func TestGroupBy(t *testing.T, db *gorm.DB) {
db.Migrator().DropTable(&User{})
db.AutoMigrate(&User{})
t.Run("GroupBy", func(t *testing.T) {
var users = []User{{
Name: "groupby",
Age: 10,
Birthday: Now(),
}, {
Name: "groupby",
Age: 20,
Birthday: Now(),
}, {
Name: "groupby",
Age: 30,
Birthday: Now(),
}, {
Name: "groupby1",
Age: 110,
Birthday: Now(),
}, {
Name: "groupby1",
Age: 220,
Birthday: Now(),
}, {
Name: "groupby1",
Age: 330,
Birthday: Now(),
}}
if err := db.Create(&users).Error; err != nil {
t.Errorf("errors happened when create: %v", err)
}
var name string
var total int
if err := db.Model(&User{}).Select("name, sum(age)").Where("name = ?", "groupby").Group("name").Row().Scan(&name, &total); err != nil {
t.Errorf("no error should happen, but got %v", err)
}
if name != "groupby" || total != 60 {
t.Errorf("name should be groupby, but got %v, total should be 60, but got %v", name, total)
}
if err := db.Model(&User{}).Select("name, sum(age) as total").Where("name LIKE ?", "groupby%").Group("name").Having("name = ?", "groupby1").Row().Scan(&name, &total); err != nil {
t.Errorf("no error should happen, but got %v", err)
}
if name != "groupby1" || total != 660 {
t.Errorf("name should be groupby, but got %v, total should be 660, but got %v", name, total)
}
})
}

View File

@ -20,6 +20,8 @@ func RunTestsSuit(t *testing.T, db *gorm.DB) {
TestFind(t, db)
TestUpdate(t, db)
TestDelete(t, db)
TestGroupBy(t, db)
}
func TestCreate(t *testing.T, db *gorm.DB) {