Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
go tool cover -html coverage/coverage.out -o coverage/coverage.html

Comment on lines +23 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure coverage directory exists before writing outputs

Without creating the directory first, go test -coverprofile coverage/coverage.out and go tool cover ... -o coverage/coverage.html can fail with “no such file or directory”.

Apply:

 .PHONY: coverage
 coverage:
+	mkdir -p 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
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.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: coverage
coverage:
mkdir -p 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
🤖 Prompt for AI Agents
In Makefile around lines 23 to 28, the target writes coverage files into the
coverage/ directory without ensuring it exists; update the target to create the
directory first (e.g., run mkdir -p coverage) before running go test and go tool
cover so the coverage output and HTML file can be written successfully.

.PHONY: benchmark
benchmark:
go test ./... -benchmem -bench=. -run=^Benchmark_$
27 changes: 21 additions & 6 deletions mutation.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,48 @@ 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 {
tx = tx.Where(where)
} 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
Expand Down
48 changes: 44 additions & 4 deletions mutation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}

Expand Down