diff --git a/examples/comparison/gorm4/autogenerated_gorm4.go b/examples/comparison/gorm4/autogenerated_gorm4.go index f1b2c8c..ef11c08 100644 --- a/examples/comparison/gorm4/autogenerated_gorm4.go +++ b/examples/comparison/gorm4/autogenerated_gorm4.go @@ -97,6 +97,20 @@ func (o *User) Delete(db *gorm.DB) error { return db.Delete(o).Error } +// DeleteNum is an autogenerated method +// nolint: dupl +func (qs UserQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(User{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs UserQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(User{}) + return db.RowsAffected, db.Error +} + // DeletedAtEq is an autogenerated method // nolint: dupl func (qs UserQuerySet) DeletedAtEq(deletedAt time.Time) UserQuerySet { diff --git a/queryset/compile b/queryset/compile new file mode 100644 index 0000000..28efd77 Binary files /dev/null and b/queryset/compile differ diff --git a/queryset/methods/queryset.go b/queryset/methods/queryset.go index dc5aa9d..724a4c1 100644 --- a/queryset/methods/queryset.go +++ b/queryset/methods/queryset.go @@ -253,20 +253,73 @@ func NewGetUpdaterMethod(qsTypeName, updaterTypeMethod string) GetUpdaterMethod // DeleteMethod creates Delete method type DeleteMethod struct { baseQuerySetMethod + namedMethod noArgsMethod + gormErroredMethod } // NewDeleteMethod creates Delete method func NewDeleteMethod(qsTypeName, structTypeName string) DeleteMethod { return DeleteMethod{ - baseQuerySetMethod: newBaseQuerySetMethod(qsTypeName), + namedMethod: newNamedMethod("Delete"), + baseQuerySetMethod: newBaseQuerySetMethod(qsTypeName), gormErroredMethod: newGormErroredMethod("Delete", structTypeName+"{}", qsDbName), } } +// DeleteNumMethod creates DeleteNum method +type DeleteNumMethod struct { + namedMethod + baseQuerySetMethod + + noArgsMethod + constBodyMethod + constRetMethod +} + +// NewDeleteNumMethod delete row count +func NewDeleteNumMethod(qsTypeName, structTypeName string) DeleteNumMethod { + return DeleteNumMethod{ + namedMethod: newNamedMethod("DeleteNum"), + baseQuerySetMethod: newBaseQuerySetMethod(qsTypeName), + constRetMethod: newConstRetMethod("(int64, error)"), + constBodyMethod: newConstBodyMethod( + strings.Join([]string{ + "db := qs.db.Delete(" + structTypeName + "{}" + ")", + "return db.RowsAffected, db.Error", + }, "\n"), + ), + } +} + +// DeleteNumUnscopedMethod creates DeleteNumUnscoped method for performing hard deletes +type DeleteNumUnscopedMethod struct { + namedMethod + baseQuerySetMethod + + noArgsMethod + constBodyMethod + constRetMethod +} + +// NewDeleteNumUnscopedMethod delete row count for hard deletes +func NewDeleteNumUnscopedMethod(qsTypeName, structTypeName string) DeleteNumUnscopedMethod { + return DeleteNumUnscopedMethod{ + namedMethod: newNamedMethod("DeleteNumUnscoped"), + baseQuerySetMethod: newBaseQuerySetMethod(qsTypeName), + constRetMethod: newConstRetMethod("(int64, error)"), + constBodyMethod: newConstBodyMethod( + strings.Join([]string{ + "db := qs.db.Unscoped().Delete(" + structTypeName + "{}" + ")", + "return db.RowsAffected, db.Error", + }, "\n"), + ), + } +} + // CountMethod creates Count method type CountMethod struct { baseQuerySetMethod diff --git a/queryset/methodsbuilder.go b/queryset/methodsbuilder.go index 4fdfa06..64777a3 100644 --- a/queryset/methodsbuilder.go +++ b/queryset/methodsbuilder.go @@ -123,7 +123,9 @@ func (b *methodsBuilder) buildCRUDMethods() *methodsBuilder { methods.NewGetUpdaterMethod(b.qsTypeName(), getUpdaterTypeName(b.s.TypeName)), methods.NewDeleteMethod(b.qsTypeName(), b.s.TypeName), methods.NewStructModifierMethod("Create", b.s.TypeName), - methods.NewStructModifierMethod("Delete", b.s.TypeName)) + methods.NewStructModifierMethod("Delete", b.s.TypeName), + methods.NewDeleteNumMethod(b.qsTypeName(), b.s.TypeName), + methods.NewDeleteNumUnscopedMethod(b.qsTypeName(), b.s.TypeName)) return b } diff --git a/queryset/queryset_test.go b/queryset/queryset_test.go index ff624af..fd7790c 100644 --- a/queryset/queryset_test.go +++ b/queryset/queryset_test.go @@ -120,6 +120,8 @@ func TestQueries(t *testing.T) { testUserQueryFilters, testUsersCount, testUsersUpdateNum, + testUsersDeleteNum, + testUsersDeleteNumUnscoped, } for _, f := range funcs { f := f // save range var @@ -328,6 +330,36 @@ func testUserDeleteByPK(t *testing.T, m sqlmock.Sqlmock, db *gorm.DB) { assert.Nil(t, u.Delete(db)) } +func testUsersDeleteNum(t *testing.T, m sqlmock.Sqlmock, db *gorm.DB) { + usersNum := 2 + users := getTestUsers(usersNum) + req := "UPDATE `users` SET deleted_at=? WHERE `users`.deleted_at IS NULL AND ((email IN (?,?)))" + m.ExpectExec(fixedFullRe(req)). + WithArgs(sqlmock.AnyArg(), users[0].Email, users[1].Email). + WillReturnResult(sqlmock.NewResult(0, int64(usersNum))) + + num, err := test.NewUserQuerySet(db). + EmailIn(users[0].Email, users[1].Email). + DeleteNum() + assert.Nil(t, err) + assert.Equal(t, int64(usersNum), num) +} + +func testUsersDeleteNumUnscoped(t *testing.T, m sqlmock.Sqlmock, db *gorm.DB) { + usersNum := 2 + users := getTestUsers(usersNum) + req := "DELETE FROM `users` WHERE (email IN (?,?))" + m.ExpectExec(fixedFullRe(req)). + WithArgs(users[0].Email, users[1].Email). + WillReturnResult(sqlmock.NewResult(0, int64(usersNum))) + + num, err := test.NewUserQuerySet(db). + EmailIn(users[0].Email, users[1].Email). + DeleteNumUnscoped() + assert.Nil(t, err) + assert.Equal(t, int64(usersNum), num) +} + func testUsersUpdateNum(t *testing.T, m sqlmock.Sqlmock, db *gorm.DB) { usersNum := 2 users := getTestUsers(usersNum) diff --git a/queryset/test/autogenerated_models.go b/queryset/test/autogenerated_models.go index e3e0704..48fe53a 100644 --- a/queryset/test/autogenerated_models.go +++ b/queryset/test/autogenerated_models.go @@ -86,16 +86,30 @@ func (qs BlogQuerySet) CreatedAtNe(createdAt time.Time) BlogQuerySet { return qs.w(qs.db.Where("created_at != ?", createdAt)) } +// Delete is an autogenerated method +// nolint: dupl +func (qs BlogQuerySet) Delete() error { + return qs.db.Delete(Blog{}).Error +} + // Delete is an autogenerated method // nolint: dupl func (o *Blog) Delete(db *gorm.DB) error { return db.Delete(o).Error } -// Delete is an autogenerated method +// DeleteNum is an autogenerated method // nolint: dupl -func (qs BlogQuerySet) Delete() error { - return qs.db.Delete(Blog{}).Error +func (qs BlogQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(Blog{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs BlogQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(Blog{}) + return db.RowsAffected, db.Error } // DeletedAtEq is an autogenerated method @@ -513,6 +527,20 @@ func (qs CheckReservedKeywordsQuerySet) Delete() error { return qs.db.Delete(CheckReservedKeywords{}).Error } +// DeleteNum is an autogenerated method +// nolint: dupl +func (qs CheckReservedKeywordsQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(CheckReservedKeywords{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs CheckReservedKeywordsQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(CheckReservedKeywords{}) + return db.RowsAffected, db.Error +} + // GetUpdater is an autogenerated method // nolint: dupl func (qs CheckReservedKeywordsQuerySet) GetUpdater() CheckReservedKeywordsUpdater { @@ -814,16 +842,30 @@ func (qs PostQuerySet) CreatedAtNe(createdAt time.Time) PostQuerySet { return qs.w(qs.db.Where("created_at != ?", createdAt)) } +// Delete is an autogenerated method +// nolint: dupl +func (qs PostQuerySet) Delete() error { + return qs.db.Delete(Post{}).Error +} + // Delete is an autogenerated method // nolint: dupl func (o *Post) Delete(db *gorm.DB) error { return db.Delete(o).Error } -// Delete is an autogenerated method +// DeleteNum is an autogenerated method // nolint: dupl -func (qs PostQuerySet) Delete() error { - return qs.db.Delete(Post{}).Error +func (qs PostQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(Post{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs PostQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(Post{}) + return db.RowsAffected, db.Error } // DeletedAtEq is an autogenerated method @@ -1344,16 +1386,30 @@ func (qs UserQuerySet) CreatedAtNe(createdAt time.Time) UserQuerySet { return qs.w(qs.db.Where("created_at != ?", createdAt)) } +// Delete is an autogenerated method +// nolint: dupl +func (qs UserQuerySet) Delete() error { + return qs.db.Delete(User{}).Error +} + // Delete is an autogenerated method // nolint: dupl func (o *User) Delete(db *gorm.DB) error { return db.Delete(o).Error } -// Delete is an autogenerated method +// DeleteNum is an autogenerated method // nolint: dupl -func (qs UserQuerySet) Delete() error { - return qs.db.Delete(User{}).Error +func (qs UserQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(User{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs UserQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(User{}) + return db.RowsAffected, db.Error } // DeletedAtEq is an autogenerated method diff --git a/queryset/test/pkgimport/autogenerated_models.go b/queryset/test/pkgimport/autogenerated_models.go index a57ea4d..0545eff 100644 --- a/queryset/test/pkgimport/autogenerated_models.go +++ b/queryset/test/pkgimport/autogenerated_models.go @@ -169,16 +169,30 @@ func (qs ExampleQuerySet) Currency3NotIn(currency3 ...forex.Currency3) ExampleQu return qs.w(qs.db.Where("currency3 NOT IN (?)", currency3)) } +// Delete is an autogenerated method +// nolint: dupl +func (o *Example) Delete(db *gorm.DB) error { + return db.Delete(o).Error +} + // Delete is an autogenerated method // nolint: dupl func (qs ExampleQuerySet) Delete() error { return qs.db.Delete(Example{}).Error } -// Delete is an autogenerated method +// DeleteNum is an autogenerated method // nolint: dupl -func (o *Example) Delete(db *gorm.DB) error { - return db.Delete(o).Error +func (qs ExampleQuerySet) DeleteNum() (int64, error) { + db := qs.db.Delete(Example{}) + return db.RowsAffected, db.Error +} + +// DeleteNumUnscoped is an autogenerated method +// nolint: dupl +func (qs ExampleQuerySet) DeleteNumUnscoped() (int64, error) { + db := qs.db.Unscoped().Delete(Example{}) + return db.RowsAffected, db.Error } // GetUpdater is an autogenerated method