diff --git a/daos/base.go b/daos/base.go index bc6aab85..0a6d0e30 100644 --- a/daos/base.go +++ b/daos/base.go @@ -29,7 +29,8 @@ func NewMultiDB(concurrentDB, nonconcurrentDB dbx.Builder) *Dao { } // Dao handles various db operations. -// Think of Dao as a repository and service layer in one. +// +// You can think of Dao as a repository and service layer in one. type Dao struct { // in a transaction both refer to the same *dbx.TX instance concurrentDB dbx.Builder @@ -43,6 +44,7 @@ type Dao struct { // This field has no effect if an explicit query context is already specified. ModelQueryTimeout time.Duration + // write hooks BeforeCreateFunc func(eventDao *Dao, m models.Model) error AfterCreateFunc func(eventDao *Dao, m models.Model) BeforeUpdateFunc func(eventDao *Dao, m models.Model) error @@ -81,6 +83,21 @@ func (dao *Dao) Clone() *Dao { return &clone } +// WithoutHooks returns a new Dao with the same configuration options +// as the current one, but without create/update/delete hooks. +func (dao *Dao) WithoutHooks() *Dao { + new := dao.Clone() + + new.BeforeCreateFunc = nil + new.AfterCreateFunc = nil + new.BeforeUpdateFunc = nil + new.AfterUpdateFunc = nil + new.BeforeDeleteFunc = nil + new.AfterDeleteFunc = nil + + return new +} + // ModelQuery creates a new preconfigured select query with preset // SELECT, FROM and other common fields based on the provided model. func (dao *Dao) ModelQuery(m models.Model) *dbx.SelectQuery { diff --git a/daos/base_test.go b/daos/base_test.go index 459e8391..4606c32e 100644 --- a/daos/base_test.go +++ b/daos/base_test.go @@ -120,6 +120,72 @@ func TestDaoClone(t *testing.T) { } } +func TestDaoWithoutHooks(t *testing.T) { + testApp, _ := tests.NewTestApp() + defer testApp.Cleanup() + + hookCalls := map[string]int{} + + dao := daos.NewMultiDB(testApp.Dao().ConcurrentDB(), testApp.Dao().NonconcurrentDB()) + dao.MaxLockRetries = 1 + dao.ModelQueryTimeout = 2 + dao.BeforeDeleteFunc = func(eventDao *daos.Dao, m models.Model) error { + hookCalls["BeforeDeleteFunc"]++ + return nil + } + dao.BeforeUpdateFunc = func(eventDao *daos.Dao, m models.Model) error { + hookCalls["BeforeUpdateFunc"]++ + return nil + } + dao.BeforeCreateFunc = func(eventDao *daos.Dao, m models.Model) error { + hookCalls["BeforeCreateFunc"]++ + return nil + } + dao.AfterDeleteFunc = func(eventDao *daos.Dao, m models.Model) { + hookCalls["AfterDeleteFunc"]++ + } + dao.AfterUpdateFunc = func(eventDao *daos.Dao, m models.Model) { + hookCalls["AfterUpdateFunc"]++ + } + dao.AfterCreateFunc = func(eventDao *daos.Dao, m models.Model) { + hookCalls["AfterCreateFunc"]++ + } + + new := dao.WithoutHooks() + + if new.MaxLockRetries != dao.MaxLockRetries { + t.Fatalf("Expected MaxLockRetries %d, got %d", new.Clone().MaxLockRetries, dao.MaxLockRetries) + } + + if new.ModelQueryTimeout != dao.ModelQueryTimeout { + t.Fatalf("Expected ModelQueryTimeout %d, got %d", new.Clone().ModelQueryTimeout, dao.ModelQueryTimeout) + } + + if new.BeforeDeleteFunc != nil { + t.Fatal("Expected BeforeDeleteFunc to be nil") + } + + if new.BeforeUpdateFunc != nil { + t.Fatal("Expected BeforeUpdateFunc to be nil") + } + + if new.BeforeCreateFunc != nil { + t.Fatal("Expected BeforeCreateFunc to be nil") + } + + if new.AfterDeleteFunc != nil { + t.Fatal("Expected AfterDeleteFunc to be nil") + } + + if new.AfterUpdateFunc != nil { + t.Fatal("Expected AfterUpdateFunc to be nil") + } + + if new.AfterCreateFunc != nil { + t.Fatal("Expected AfterCreateFunc to be nil") + } +} + func TestDaoModelQuery(t *testing.T) { testApp, _ := tests.NewTestApp() defer testApp.Cleanup()