diff --git a/Makefile b/Makefile index b922f76..e5c10b8 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,31 @@ -.PHONY: test-coverage +.PHONY: audit +audit: + go mod verify + go vet ./... + go run golang.org/x/vuln/cmd/govulncheck@latest ./... -test-coverage: +.PHONY: format +format: + go run mvdan.cc/gofumpt@latest -w -l . + +.PHONY: lint +lint: + golangci-lint run + +.PHONY: tidy +tidy: + go mod tidy -v + +.PHONY: test +test: + go test -cover ./... + +.PHONY: coverage +coverage: go clean -testcache go test -v ./... -covermode=count -coverpkg=./... -coverprofile coverage/coverage.out - go tool cover -html coverage/coverage.out -o coverage/coverage.html \ No newline at end of file + go tool cover -html coverage/coverage.out -o coverage/coverage.html + +.PHONY: benchmark +benchmark: + go test ./... -benchmem -bench=. -run=^Benchmark_$ \ No newline at end of file diff --git a/mutation.go b/mutation.go index 94065dc..a3ed8e3 100644 --- a/mutation.go +++ b/mutation.go @@ -50,26 +50,37 @@ func (repo *Repository[M]) UpdateMany(where interface{}, val interface{}) error return nil } -func (repo *Repository[M]) DeleteOne(where interface{}) error { - record, err := repo.FindOne(where, FindOneOptions{}) +func (repo *Repository[M]) DeleteOne(where interface{}, isForceDelete ...bool) error { + withDeleted := false + if len(isForceDelete) > 0 && isForceDelete[0] { + withDeleted = true + } + + record, err := repo.FindOne(where, FindOneOptions{ + WithDeleted: withDeleted, + }) if err != nil { return err } if record == nil { return gorm.ErrRecordNotFound } - result := repo.DB.Delete(record) + tx := repo.DB + if withDeleted { + tx = tx.Unscoped() + } + result := tx.Delete(record) if result.Error != nil { return result.Error } return nil } -func (repo *Repository[M]) DeleteByID(id any) error { - return repo.DeleteOne(map[string]any{"id": id}) +func (repo *Repository[M]) DeleteByID(id any, isForceDelete ...bool) error { + return repo.DeleteOne(map[string]any{"id": id}, isForceDelete...) } -func (repo *Repository[M]) DeleteMany(where interface{}) error { +func (repo *Repository[M]) DeleteMany(where interface{}, isForceDelete ...bool) error { var model M tx := repo.DB if where != nil { @@ -77,6 +88,10 @@ func (repo *Repository[M]) DeleteMany(where interface{}) error { } else { tx = tx.Where("1 = 1") } + + if len(isForceDelete) > 0 && isForceDelete[0] { + tx = tx.Unscoped() + } result := tx.Delete(&model) if result.Error != nil { return result.Error diff --git a/mutation_test.go b/mutation_test.go index 8c80c08..858b947 100644 --- a/mutation_test.go +++ b/mutation_test.go @@ -154,26 +154,66 @@ func Test_Delete(t *testing.T) { err = repo.DeleteByID(result.ID.String()) require.Nil(t, err) + + found, err := repo.FindByID(result.ID.String(), sqlorm.FindOneOptions{ + WithDeleted: true, + }) + require.Nil(t, err) + require.NotNil(t, found) + + err = repo.DeleteByID(result.ID.String(), true) + require.Nil(t, err) + + found, err = repo.FindByID(result.ID.String(), sqlorm.FindOneOptions{ + WithDeleted: true, + }) + require.Nil(t, err) + require.Nil(t, found) }) } func Test_DeleteMany(t *testing.T) { db := prepareBeforeTest(t) - type Todo struct { + type TodoDeleteMany struct { sqlorm.Model `gorm:"embedded"` Name string `gorm:"type:varchar(255);not null"` } - err := db.AutoMigrate(&Todo{}) + err := db.AutoMigrate(&TodoDeleteMany{}) require.Nil(t, err) - repo := sqlorm.Repository[Todo]{DB: db} + repo := sqlorm.Repository[TodoDeleteMany]{DB: db} require.NotPanics(t, func() { - err := repo.DeleteMany(map[string]interface{}{"name": "lulu"}) + type CreateTodo struct { + Name string + } + _, err = repo.BatchCreate([]*CreateTodo{ + {Name: "abc"}, + {Name: "def"}, + {Name: "ghi"}, + {Name: "jkl"}, + }, 5) + require.Nil(t, err) + err := repo.DeleteMany(map[string]interface{}{"name": "abc"}) require.Nil(t, err) err = repo.DeleteMany(nil) require.Nil(t, err) + + found, err := repo.FindAll(nil, sqlorm.FindOptions{ + WithDeleted: true, + }) + require.Nil(t, err) + require.Greater(t, len(found), 0) + + err = repo.DeleteMany(nil, true) + require.Nil(t, err) + + found, err = repo.FindAll(nil, sqlorm.FindOptions{ + WithDeleted: true, + }) + require.Nil(t, err) + require.Len(t, found, 0) }) }