From 3dc8d0d79f06a568288e402d876f81763d6b08e9 Mon Sep 17 00:00:00 2001 From: Eden Kirin Date: Tue, 25 Jun 2024 01:52:50 +0200 Subject: [PATCH] Count method --- app/main.go | 18 ++++++++- app/repository/method_count.go | 32 +++++++++++++++ app/repository/method_count_test.go | 60 +++++++++++++++++++++++++++++ app/repository/method_list_test.go | 7 ++-- app/repository/repository.go | 12 ++++-- 5 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 app/repository/method_count.go create mode 100644 app/repository/method_count_test.go diff --git a/app/main.go b/app/main.go index cea5f66..bfbada5 100644 --- a/app/main.go +++ b/app/main.go @@ -89,6 +89,21 @@ func doList(db *gorm.DB) { } } +func doCount(db *gorm.DB) { + repo := repository.RepoBase[models.Cert]{} + repo.Init(db, nil) + + filter := CertFilter{ + Alive: &TRUE, + } + + count, err := repo.Count(filter) + if err != nil { + panic(err) + } + fmt.Printf(">>> count: %d\n", count) +} + func doGet(db *gorm.DB) { repo := repository.RepoBase[models.Cert]{} repo.Init(db, nil) @@ -130,8 +145,9 @@ func main() { db := db.InitDB() - doMagic(db) + // doMagic(db) // doList(db) + doCount(db) // doGet(db) // doExists(db) // inheritance.DoInheritanceTest() diff --git a/app/repository/method_count.go b/app/repository/method_count.go new file mode 100644 index 0000000..d4c8568 --- /dev/null +++ b/app/repository/method_count.go @@ -0,0 +1,32 @@ +package repository + +import ( + "repo-pattern/app/repository/smartfilter" + + "gorm.io/gorm/schema" +) + +type CountMethod[T schema.Tabler] struct { + repo *RepoBase[T] +} + +func (m *CountMethod[T]) Init(repo *RepoBase[T]) { + m.repo = repo +} + +func (m CountMethod[T]) Count(filter interface{}) (int64, error) { + var ( + model T + count int64 + ) + + query := m.repo.dbConn.Model(model) + + query, err := smartfilter.ToQuery(model, filter, query) + if err != nil { + return 0, err + } + + query.Count(&count) + return count, nil +} diff --git a/app/repository/method_count_test.go b/app/repository/method_count_test.go new file mode 100644 index 0000000..2decb41 --- /dev/null +++ b/app/repository/method_count_test.go @@ -0,0 +1,60 @@ +package repository + +import ( + "fmt" + "regexp" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" +) + +func TestCountMethod(t *testing.T) { + t.Run("Count without filter", func(t *testing.T) { + sqldb, db, mock := NewMockDB() + defer sqldb.Close() + + repo := RepoBase[MyModel]{} + repo.Init(db, nil) + + filter := MyModelFilter{} + + sql := "SELECT count(*) FROM my_models" + mock.ExpectQuery(fmt.Sprintf("^%s$", regexp.QuoteMeta(sql))) + + result, err := repo.Count(filter) + assert.Equal(t, result, int64(0)) + assert.Nil(t, err) + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expectations: %s", err) + } + }) + + t.Run("Count with filter", func(t *testing.T) { + sqldb, db, mock := NewMockDB() + defer sqldb.Close() + + repo := RepoBase[MyModel]{} + repo.Init(db, nil) + + id1 := uuid.New() + id2 := uuid.New() + id3 := uuid.New() + filter := MyModelFilter{ + Ids: &[]uuid.UUID{id1, id2, id3}, + } + + sql := "SELECT count(*) FROM my_models WHERE my_models.id IN ($1,$2,$3)" + mock.ExpectQuery(fmt.Sprintf("^%s$", regexp.QuoteMeta(sql))). + WithArgs(id1, id2, id3) + + result, err := repo.Count(filter) + assert.Equal(t, result, int64(0)) + assert.Nil(t, err) + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expectations: %s", err) + } + }) +} diff --git a/app/repository/method_list_test.go b/app/repository/method_list_test.go index fe255ff..e4e3b6f 100644 --- a/app/repository/method_list_test.go +++ b/app/repository/method_list_test.go @@ -43,9 +43,10 @@ func (m MyModel) TableName() string { } type MyModelFilter struct { - Id *uuid.UUID `filterfield:"field=id,operator=EQ"` - Value *string `filterfield:"field=value,operator=EQ"` - Count *int `filterfield:"field=count,operator=GT"` + Id *uuid.UUID `filterfield:"field=id,operator=EQ"` + Ids *[]uuid.UUID `filterfield:"field=id,operator=IN"` + Value *string `filterfield:"field=value,operator=EQ"` + Count *int `filterfield:"field=count,operator=GT"` } func TestListMethod(t *testing.T) { diff --git a/app/repository/repository.go b/app/repository/repository.go index d07ce37..bc2950b 100644 --- a/app/repository/repository.go +++ b/app/repository/repository.go @@ -20,10 +20,11 @@ type RepoBase[T schema.Tabler] struct { ListMethod[T] GetMethod[T] ExistsMethod[T] + CountMethod[T] methods []MethodInitInterface[T] } -func (repo *RepoBase[T]) InitMethods(dbConn *gorm.DB) { +func (repo *RepoBase[T]) InitMethods() { for _, method := range repo.methods { method.Init(repo) } @@ -41,6 +42,11 @@ func (m *RepoBase[T]) Init(dbConn *gorm.DB, options *RepoOptions) { } } - m.methods = []MethodInitInterface[T]{&m.ListMethod, &m.GetMethod, &m.ExistsMethod} - m.InitMethods(dbConn) + m.methods = []MethodInitInterface[T]{ + &m.ListMethod, + &m.GetMethod, + &m.ExistsMethod, + &m.CountMethod, + } + m.InitMethods() }