2020-05-24 06:32:59 +03:00
package tests_test
import (
"fmt"
2020-08-03 05:30:25 +03:00
"regexp"
2020-12-06 09:04:37 +03:00
"sort"
"strings"
2020-05-24 06:32:59 +03:00
"testing"
2020-06-23 17:41:41 +03:00
"gorm.io/gorm"
2020-06-02 05:34:50 +03:00
. "gorm.io/gorm/utils/tests"
2020-05-24 06:32:59 +03:00
)
2023-03-23 06:19:53 +03:00
func TestCountWithGroup ( t * testing . T ) {
DB . Create ( [ ] Company {
{ Name : "company_count_group_a" } ,
{ Name : "company_count_group_a" } ,
{ Name : "company_count_group_a" } ,
{ Name : "company_count_group_b" } ,
{ Name : "company_count_group_c" } ,
} )
var count1 int64
if err := DB . Model ( & Company { } ) . Where ( "name = ?" , "company_count_group_a" ) . Group ( "name" ) . Count ( & count1 ) . Error ; err != nil {
t . Errorf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
}
if count1 != 1 {
t . Errorf ( "Count with group should be 1, but got count: %v" , count1 )
}
var count2 int64
if err := DB . Debug ( ) . Model ( & Company { } ) . Where ( "name in ?" , [ ] string { "company_count_group_b" , "company_count_group_c" } ) . Group ( "name" ) . Count ( & count2 ) . Error ; err != nil {
t . Errorf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
}
if count2 != 2 {
t . Errorf ( "Count with group should be 2, but got count: %v" , count2 )
}
}
2020-05-24 06:32:59 +03:00
func TestCount ( t * testing . T ) {
var (
user1 = * GetUser ( "count-1" , Config { } )
user2 = * GetUser ( "count-2" , Config { } )
user3 = * GetUser ( "count-3" , Config { } )
users [ ] User
count , count1 , count2 int64
)
DB . Save ( & user1 ) . Save ( & user2 ) . Save ( & user3 )
if err := DB . Where ( "name = ?" , user1 . Name ) . Or ( "name = ?" , user3 . Name ) . Find ( & users ) . Count ( & count ) . Error ; err != nil {
t . Errorf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
2020-07-01 05:19:52 +03:00
}
if count != int64 ( len ( users ) ) {
t . Errorf ( "Count() method should get correct value, expect: %v, got %v" , count , len ( users ) )
}
if err := DB . Model ( & User { } ) . Where ( "name = ?" , user1 . Name ) . Or ( "name = ?" , user3 . Name ) . Count ( & count ) . Find ( & users ) . Error ; err != nil {
t . Errorf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
2020-05-24 06:32:59 +03:00
}
if count != int64 ( len ( users ) ) {
t . Errorf ( "Count() method should get correct value, expect: %v, got %v" , count , len ( users ) )
}
DB . Model ( & User { } ) . Where ( "name = ?" , user1 . Name ) . Count ( & count1 ) . Or ( "name in ?" , [ ] string { user2 . Name , user3 . Name } ) . Count ( & count2 )
if count1 != 1 || count2 != 3 {
t . Errorf ( "multiple count in chain should works" )
}
2020-11-17 10:41:17 +03:00
tx := DB . Model ( & User { } ) . Where ( "name = ?" , user1 . Name ) . Session ( & gorm . Session { } )
2020-06-23 17:41:41 +03:00
tx . Count ( & count1 )
tx . Or ( "name in ?" , [ ] string { user2 . Name , user3 . Name } ) . Count ( & count2 )
if count1 != 1 || count2 != 3 {
t . Errorf ( "count after new session should works" )
}
2020-05-24 06:32:59 +03:00
var count3 int64
if err := DB . Model ( & User { } ) . Where ( "name in ?" , [ ] string { user2 . Name , user2 . Name , user3 . Name } ) . Group ( "id" ) . Count ( & count3 ) . Error ; err != nil {
2020-05-24 12:24:23 +03:00
t . Errorf ( "Error happened when count with group, but got %v" , err )
2020-05-24 06:32:59 +03:00
}
if count3 != 2 {
t . Errorf ( "Should get correct count for count with group, but got %v" , count3 )
}
2020-08-03 05:30:25 +03:00
dryDB := DB . Session ( & gorm . Session { DryRun : true } )
result := dryDB . Table ( "users" ) . Select ( "name" ) . Count ( & count )
if ! regexp . MustCompile ( ` SELECT COUNT\(.name.\) FROM .*users.* ` ) . MatchString ( result . Statement . SQL . String ( ) ) {
t . Fatalf ( "Build count with select, but got %v" , result . Statement . SQL . String ( ) )
}
result = dryDB . Table ( "users" ) . Distinct ( "name" ) . Count ( & count )
if ! regexp . MustCompile ( ` SELECT COUNT\(DISTINCT\(.name.\)\) FROM .*users.* ` ) . MatchString ( result . Statement . SQL . String ( ) ) {
t . Fatalf ( "Build count with select, but got %v" , result . Statement . SQL . String ( ) )
}
2020-08-13 07:18:36 +03:00
var count4 int64
2020-10-19 09:49:42 +03:00
if err := DB . Table ( "users" ) . Joins ( "LEFT JOIN companies on companies.name = users.name" ) . Where ( "users.name = ?" , user1 . Name ) . Count ( & count4 ) . Error ; err != nil || count4 != 1 {
2020-10-22 06:28:43 +03:00
t . Errorf ( "count with join, got error: %v, count %v" , err , count4 )
}
var count5 int64
if err := DB . Table ( "users" ) . Where ( "users.name = ?" , user1 . Name ) . Order ( "name" ) . Count ( & count5 ) . Error ; err != nil || count5 != 1 {
2020-08-13 07:18:36 +03:00
t . Errorf ( "count with join, got error: %v, count %v" , err , count )
}
2020-12-06 09:04:37 +03:00
var count6 int64
if err := DB . Model ( & User { } ) . Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) . Select (
"(CASE WHEN name=? THEN ? ELSE ? END) as name" , "count-1" , "main" , "other" ,
) . Count ( & count6 ) . Find ( & users ) . Error ; err != nil || count6 != 3 {
t . Fatalf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
}
2022-01-06 10:02:53 +03:00
expects := [ ] User { { Name : "main" } , { Name : "other" } , { Name : "other" } }
2020-12-06 09:04:37 +03:00
sort . SliceStable ( users , func ( i , j int ) bool {
return strings . Compare ( users [ i ] . Name , users [ j ] . Name ) < 0
} )
AssertEqual ( t , users , expects )
var count7 int64
if err := DB . Model ( & User { } ) . Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) . Select (
"(CASE WHEN name=? THEN ? ELSE ? END) as name, age" , "count-1" , "main" , "other" ,
) . Count ( & count7 ) . Find ( & users ) . Error ; err != nil || count7 != 3 {
t . Fatalf ( fmt . Sprintf ( "Count should work, but got err %v" , err ) )
}
2022-01-06 10:02:53 +03:00
expects = [ ] User { { Name : "main" , Age : 18 } , { Name : "other" , Age : 18 } , { Name : "other" , Age : 18 } }
2020-12-06 09:04:37 +03:00
sort . SliceStable ( users , func ( i , j int ) bool {
return strings . Compare ( users [ i ] . Name , users [ j ] . Name ) < 0
} )
AssertEqual ( t , users , expects )
var count8 int64
if err := DB . Model ( & User { } ) . Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) . Select (
"(CASE WHEN age=18 THEN 1 ELSE 2 END) as age" , "name" ,
) . Count ( & count8 ) . Find ( & users ) . Error ; err != nil || count8 != 3 {
2021-09-16 06:17:54 +03:00
t . Fatalf ( "Count should work, but got err %v" , err )
2020-12-06 09:04:37 +03:00
}
2022-01-06 10:02:53 +03:00
expects = [ ] User { { Name : "count-1" , Age : 1 } , { Name : "count-2" , Age : 1 } , { Name : "count-3" , Age : 1 } }
2020-12-06 09:04:37 +03:00
sort . SliceStable ( users , func ( i , j int ) bool {
return strings . Compare ( users [ i ] . Name , users [ j ] . Name ) < 0
} )
AssertEqual ( t , users , expects )
2021-03-24 11:17:49 +03:00
var count9 int64
2021-09-16 06:17:54 +03:00
if err := DB . Scopes ( func ( tx * gorm . DB ) * gorm . DB {
2021-03-24 11:17:49 +03:00
return tx . Table ( "users" )
} ) . Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) . Count ( & count9 ) . Find ( & users ) . Error ; err != nil || count9 != 3 {
2021-09-16 06:17:54 +03:00
t . Fatalf ( "Count should work, but got err %v" , err )
2021-03-24 11:17:49 +03:00
}
2021-09-16 06:17:54 +03:00
var count10 int64
if err := DB . Model ( & User { } ) . Select ( "*" ) . Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) . Count ( & count10 ) . Error ; err != nil || count10 != 3 {
t . Fatalf ( "Count should be 3, but got count: %v err %v" , count10 , err )
}
2021-11-29 15:14:23 +03:00
var count11 int64
sameUsers := make ( [ ] * User , 0 )
for i := 0 ; i < 3 ; i ++ {
sameUsers = append ( sameUsers , GetUser ( "count-4" , Config { } ) )
}
DB . Create ( sameUsers )
2023-03-23 06:19:53 +03:00
if err := DB . Model ( & User { } ) . Where ( "name = ?" , "count-4" ) . Group ( "name" ) . Count ( & count11 ) . Error ; err != nil || count11 != 1 {
t . Fatalf ( "Count should be 1, but got count: %v err %v" , count11 , err )
2021-11-29 15:14:23 +03:00
}
2022-01-30 13:17:06 +03:00
var count12 int64
if err := DB . Table ( "users" ) .
Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) .
Preload ( "Toys" , func ( db * gorm . DB ) * gorm . DB {
return db . Table ( "toys" ) . Select ( "name" )
2022-03-17 06:22:25 +03:00
} ) . Count ( & count12 ) . Error ; err == nil {
t . Errorf ( "error should raise when using preload without schema" )
}
var count13 int64
if err := DB . Model ( User { } ) .
Where ( "name in ?" , [ ] string { user1 . Name , user2 . Name , user3 . Name } ) .
Preload ( "Toys" , func ( db * gorm . DB ) * gorm . DB {
return db . Table ( "toys" ) . Select ( "name" )
} ) . Count ( & count13 ) . Error ; err != nil {
t . Errorf ( "no error should raise when using count with preload, but got %v" , err )
2022-01-30 13:17:06 +03:00
}
2020-05-24 06:32:59 +03:00
}