Skip to content

Commit

Permalink
Add GroupBy test
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhu committed Mar 8, 2020
1 parent ce0e6f9 commit a158d1a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 15 deletions.
8 changes: 7 additions & 1 deletion chainable_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion clause/benchmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}}},
}
Expand Down
8 changes: 4 additions & 4 deletions clause/group_by.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package clause
// GroupBy group by clause
type GroupBy struct {
Columns []Column
Having Where
Having []Expression
}

// Name from clause name
Expand All @@ -21,17 +21,17 @@ 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)
}
}

// MergeClause merge group by clause
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
}
6 changes: 3 additions & 3 deletions clause/group_by_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
},
Expand Down
6 changes: 0 additions & 6 deletions finisher_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 62 additions & 0 deletions tests/group_by.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
2 changes: 2 additions & 0 deletions tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit a158d1a

Please sign in to comment.