add bulk delete interface

This commit is contained in:
zhuyasen
2023-01-14 16:24:07 +08:00
parent e1c8522372
commit 0a44474a80
11 changed files with 271 additions and 32 deletions

View File

@@ -82,7 +82,7 @@ const docTemplate = `{
} }
}, },
"put": { "put": {
"description": "update userExample information based on id", "description": "update userExample information by id",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -153,7 +153,7 @@ const docTemplate = `{
}, },
"/api/v1/userExamples": { "/api/v1/userExamples": {
"post": { "post": {
"description": "get a list of userExamples using a post request", "description": "paging and conditional fetching of userExamples lists using post requests",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -163,7 +163,7 @@ const docTemplate = `{
"tags": [ "tags": [
"userExample" "userExample"
], ],
"summary": "get a list of userExample", "summary": "get a list of userExamples",
"parameters": [ "parameters": [
{ {
"description": "query parameters", "description": "query parameters",
@@ -185,9 +185,9 @@ const docTemplate = `{
} }
} }
}, },
"/api/v1/userExamples/ids": { "/api/v1/userExamples/delete/ids": {
"post": { "post": {
"description": "get a list of userExample based on multiple ids using a post request", "description": "delete userExamples by multiple id using a post request",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -197,7 +197,41 @@ const docTemplate = `{
"tags": [ "tags": [
"userExample" "userExample"
], ],
"summary": "get multiple records based on multiple ids", "summary": "delete userExamples by multiple id",
"parameters": [
{
"description": "id array",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/types.DeleteUserExamplesByIDsRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/types.Result"
}
}
}
}
},
"/api/v1/userExamples/ids": {
"post": {
"description": "get userExamples by multiple id using a post request",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"userExample"
],
"summary": "get userExamples by multiple id",
"parameters": [ "parameters": [
{ {
"description": "id array", "description": "id array",
@@ -328,6 +362,19 @@ const docTemplate = `{
} }
} }
}, },
"types.DeleteUserExamplesByIDsRequest": {
"type": "object",
"properties": {
"ids": {
"description": "id list",
"type": "array",
"minItems": 1,
"items": {
"type": "integer"
}
}
}
},
"types.GetUserExamplesByIDsRequest": { "types.GetUserExamplesByIDsRequest": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -78,7 +78,7 @@
} }
}, },
"put": { "put": {
"description": "update userExample information based on id", "description": "update userExample information by id",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -149,7 +149,7 @@
}, },
"/api/v1/userExamples": { "/api/v1/userExamples": {
"post": { "post": {
"description": "get a list of userExamples using a post request", "description": "paging and conditional fetching of userExamples lists using post requests",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -159,7 +159,7 @@
"tags": [ "tags": [
"userExample" "userExample"
], ],
"summary": "get a list of userExample", "summary": "get a list of userExamples",
"parameters": [ "parameters": [
{ {
"description": "query parameters", "description": "query parameters",
@@ -181,9 +181,9 @@
} }
} }
}, },
"/api/v1/userExamples/ids": { "/api/v1/userExamples/delete/ids": {
"post": { "post": {
"description": "get a list of userExample based on multiple ids using a post request", "description": "delete userExamples by multiple id using a post request",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@@ -193,7 +193,41 @@
"tags": [ "tags": [
"userExample" "userExample"
], ],
"summary": "get multiple records based on multiple ids", "summary": "delete userExamples by multiple id",
"parameters": [
{
"description": "id array",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/types.DeleteUserExamplesByIDsRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/types.Result"
}
}
}
}
},
"/api/v1/userExamples/ids": {
"post": {
"description": "get userExamples by multiple id using a post request",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"userExample"
],
"summary": "get userExamples by multiple id",
"parameters": [ "parameters": [
{ {
"description": "id array", "description": "id array",
@@ -324,6 +358,19 @@
} }
} }
}, },
"types.DeleteUserExamplesByIDsRequest": {
"type": "object",
"properties": {
"ids": {
"description": "id list",
"type": "array",
"minItems": 1,
"items": {
"type": "integer"
}
}
}
},
"types.GetUserExamplesByIDsRequest": { "types.GetUserExamplesByIDsRequest": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -50,6 +50,15 @@ definitions:
description: phone number, e164 means <+ country code> <cell phone number>. description: phone number, e164 means <+ country code> <cell phone number>.
type: string type: string
type: object type: object
types.DeleteUserExamplesByIDsRequest:
properties:
ids:
description: id list
items:
type: integer
minItems: 1
type: array
type: object
types.GetUserExamplesByIDsRequest: types.GetUserExamplesByIDsRequest:
properties: properties:
ids: ids:
@@ -188,7 +197,7 @@ paths:
put: put:
consumes: consumes:
- application/json - application/json
description: update userExample information based on id description: update userExample information by id
parameters: parameters:
- description: id - description: id
in: path in: path
@@ -215,7 +224,8 @@ paths:
post: post:
consumes: consumes:
- application/json - application/json
description: get a list of userExamples using a post request description: paging and conditional fetching of userExamples lists using post
requests
parameters: parameters:
- description: query parameters - description: query parameters
in: body in: body
@@ -230,14 +240,36 @@ paths:
description: OK description: OK
schema: schema:
$ref: '#/definitions/types.Result' $ref: '#/definitions/types.Result'
summary: get a list of userExample summary: get a list of userExamples
tags:
- userExample
/api/v1/userExamples/delete/ids:
post:
consumes:
- application/json
description: delete userExamples by multiple id using a post request
parameters:
- description: id array
in: body
name: data
required: true
schema:
$ref: '#/definitions/types.DeleteUserExamplesByIDsRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/types.Result'
summary: delete userExamples by multiple id
tags: tags:
- userExample - userExample
/api/v1/userExamples/ids: /api/v1/userExamples/ids:
post: post:
consumes: consumes:
- application/json - application/json
description: get a list of userExample based on multiple ids using a post request description: get userExamples by multiple id using a post request
parameters: parameters:
- description: id array - description: id array
in: body in: body
@@ -252,7 +284,7 @@ paths:
description: OK description: OK
schema: schema:
$ref: '#/definitions/types.Result' $ref: '#/definitions/types.Result'
summary: get multiple records based on multiple ids summary: get userExamples by multiple id
tags: tags:
- userExample - userExample
/health: /health:

2
go.mod
View File

@@ -26,6 +26,7 @@ require (
github.com/jinzhu/inflection v1.0.0 github.com/jinzhu/inflection v1.0.0
github.com/nacos-group/nacos-sdk-go/v2 v2.1.0 github.com/nacos-group/nacos-sdk-go/v2 v2.1.0
github.com/natefinch/lumberjack v2.0.0+incompatible github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.13.0 github.com/prometheus/client_golang v1.13.0
github.com/shirou/gopsutil/v3 v3.21.8 github.com/shirou/gopsutil/v3 v3.21.8
github.com/spf13/cast v1.5.0 github.com/spf13/cast v1.5.0
@@ -132,7 +133,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect

View File

@@ -24,6 +24,7 @@ var _ UserExampleDao = (*userExampleDao)(nil)
type UserExampleDao interface { type UserExampleDao interface {
Create(ctx context.Context, table *model.UserExample) error Create(ctx context.Context, table *model.UserExample) error
DeleteByID(ctx context.Context, id uint64) error DeleteByID(ctx context.Context, id uint64) error
DeleteByIDs(ctx context.Context, ids []uint64) error
UpdateByID(ctx context.Context, table *model.UserExample) error UpdateByID(ctx context.Context, table *model.UserExample) error
GetByID(ctx context.Context, id uint64) (*model.UserExample, error) GetByID(ctx context.Context, id uint64) (*model.UserExample, error)
GetByIDs(ctx context.Context, ids []uint64) ([]*model.UserExample, error) GetByIDs(ctx context.Context, ids []uint64) ([]*model.UserExample, error)
@@ -61,6 +62,21 @@ func (d *userExampleDao) DeleteByID(ctx context.Context, id uint64) error {
return nil return nil
} }
// DeleteByIDs batch delete multiple records
func (d *userExampleDao) DeleteByIDs(ctx context.Context, ids []uint64) error {
err := d.db.WithContext(ctx).Where("id IN (?)", ids).Delete(&model.UserExample{}).Error
if err != nil {
return err
}
// delete cache
for _, id := range ids {
_ = d.cache.Del(ctx, id)
}
return nil
}
// UpdateByID update records by id // UpdateByID update records by id
func (d *userExampleDao) UpdateByID(ctx context.Context, table *model.UserExample) error { func (d *userExampleDao) UpdateByID(ctx context.Context, table *model.UserExample) error {
if table.ID < 1 { if table.ID < 1 {

View File

@@ -81,6 +81,32 @@ func Test_userExampleDao_DeleteByID(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
func Test_userExampleDao_DeleteByIDs(t *testing.T) {
d := newUserExampleDao()
defer d.Close()
testData := d.TestData.(*model.UserExample)
testData.DeletedAt = gorm.DeletedAt{
Time: time.Now(),
Valid: false,
}
d.SQLMock.ExpectBegin()
d.SQLMock.ExpectExec("UPDATE .*").
WithArgs(d.AnyTime, testData.ID).
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
d.SQLMock.ExpectCommit()
err := d.IDao.(UserExampleDao).DeleteByID(d.Ctx, testData.ID)
if err != nil {
t.Fatal(err)
}
// zero id error
err = d.IDao.(UserExampleDao).DeleteByIDs(d.Ctx, []uint64{0})
assert.Error(t, err)
}
func Test_userExampleDao_UpdateByID(t *testing.T) { func Test_userExampleDao_UpdateByID(t *testing.T) {
d := newUserExampleDao() d := newUserExampleDao()
defer d.Close() defer d.Close()

View File

@@ -25,6 +25,7 @@ var _ UserExampleHandler = (*userExampleHandler)(nil)
type UserExampleHandler interface { type UserExampleHandler interface {
Create(c *gin.Context) Create(c *gin.Context)
DeleteByID(c *gin.Context) DeleteByID(c *gin.Context)
DeleteByIDs(c *gin.Context)
UpdateByID(c *gin.Context) UpdateByID(c *gin.Context)
GetByID(c *gin.Context) GetByID(c *gin.Context)
ListByIDs(c *gin.Context) ListByIDs(c *gin.Context)
@@ -105,9 +106,37 @@ func (h *userExampleHandler) DeleteByID(c *gin.Context) {
response.Success(c) response.Success(c)
} }
// UpdateByID update information based on id // DeleteByIDs delete records by multiple id
// @Summary delete userExamples by multiple id
// @Description delete userExamples by multiple id using a post request
// @Tags userExample
// @Param data body types.DeleteUserExamplesByIDsRequest true "id array"
// @Accept json
// @Produce json
// @Success 200 {object} types.Result{}
// @Router /api/v1/userExamples/delete/ids [post]
func (h *userExampleHandler) DeleteByIDs(c *gin.Context) {
form := &types.DeleteUserExamplesByIDsRequest{}
err := c.ShouldBindJSON(form)
if err != nil {
logger.Warn("ShouldBindJSON error: ", logger.Err(err), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return
}
err = h.iDao.DeleteByIDs(c.Request.Context(), form.IDs)
if err != nil {
logger.Error("GetByIDs error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
}
response.Success(c)
}
// UpdateByID update information by id
// @Summary update userExample information // @Summary update userExample information
// @Description update userExample information based on id // @Description update userExample information by id
// @Tags userExample // @Tags userExample
// @accept json // @accept json
// @Produce json // @Produce json
@@ -147,7 +176,7 @@ func (h *userExampleHandler) UpdateByID(c *gin.Context) {
response.Success(c) response.Success(c)
} }
// GetByID get a record based on id // GetByID get a record by id
// @Summary get userExample details // @Summary get userExample details
// @Description get userExample details by id // @Description get userExample details by id
// @Tags userExample // @Tags userExample
@@ -185,9 +214,9 @@ func (h *userExampleHandler) GetByID(c *gin.Context) {
response.Success(c, gin.H{"userExample": data}) response.Success(c, gin.H{"userExample": data})
} }
// ListByIDs get multiple records based on multiple ids // ListByIDs get records by multiple id
// @Summary get multiple records based on multiple ids // @Summary get userExamples by multiple id
// @Description get a list of userExample based on multiple ids using a post request // @Description get userExamples by multiple id using a post request
// @Tags userExample // @Tags userExample
// @Param data body types.GetUserExamplesByIDsRequest true "id array" // @Param data body types.GetUserExamplesByIDsRequest true "id array"
// @Accept json // @Accept json
@@ -223,8 +252,8 @@ func (h *userExampleHandler) ListByIDs(c *gin.Context) {
} }
// List Get multiple records by query parameters // List Get multiple records by query parameters
// @Summary get a list of userExample // @Summary get a list of userExamples
// @Description get a list of userExamples using a post request // @Description paging and conditional fetching of userExamples lists using post requests
// @Tags userExample // @Tags userExample
// @accept json // @accept json
// @Produce json // @Produce json

View File

@@ -55,6 +55,12 @@ func newUserExampleHandler() *gotest.Handler {
Path: "/userExample/:id", Path: "/userExample/:id",
HandlerFunc: h.IHandler.(UserExampleHandler).DeleteByID, HandlerFunc: h.IHandler.(UserExampleHandler).DeleteByID,
}, },
{
FuncName: "DeleteByIDs",
Method: http.MethodPost,
Path: "/userExamples/delete/ids",
HandlerFunc: h.IHandler.(UserExampleHandler).DeleteByIDs,
},
{ {
FuncName: "UpdateByID", FuncName: "UpdateByID",
Method: http.MethodPut, Method: http.MethodPut,
@@ -161,6 +167,35 @@ func Test_userExampleHandler_DeleteByID(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
func Test_userExampleHandler_DeleteByIDs(t *testing.T) {
h := newUserExampleHandler()
defer h.Close()
testData := h.TestData.(*model.UserExample)
h.MockDao.SQLMock.ExpectBegin()
h.MockDao.SQLMock.ExpectExec("UPDATE .*").
WithArgs(h.MockDao.AnyTime, testData.ID). // adjusted for the amount of test data
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
h.MockDao.SQLMock.ExpectCommit()
result := &gohttp.StdResult{}
err := gohttp.Post(result, h.GetRequestURL("DeleteByIDs"), &types.DeleteUserExamplesByIDsRequest{IDs: []uint64{testData.ID}})
if err != nil {
t.Fatal(err)
}
if result.Code != 0 {
t.Fatalf("%+v", result)
}
// zero id error test
err = gohttp.Post(result, h.GetRequestURL("DeleteByIDs"), nil)
assert.NoError(t, err)
// get error test
err = gohttp.Post(result, h.GetRequestURL("DeleteByIDs"), &types.DeleteUserExamplesByIDsRequest{IDs: []uint64{111}})
assert.Error(t, err)
}
func Test_userExampleHandler_UpdateByID(t *testing.T) { func Test_userExampleHandler_UpdateByID(t *testing.T) {
h := newUserExampleHandler() h := newUserExampleHandler()
defer h.Close() defer h.Close()

View File

@@ -52,12 +52,13 @@ func TestNewRouter2(t *testing.T) {
type mock struct{} type mock struct{}
func (u mock) Create(c *gin.Context) { return } func (u mock) Create(c *gin.Context) { return }
func (u mock) DeleteByID(c *gin.Context) { return } func (u mock) DeleteByID(c *gin.Context) { return }
func (u mock) UpdateByID(c *gin.Context) { return } func (u mock) DeleteByIDs(c *gin.Context) { return }
func (u mock) GetByID(c *gin.Context) { return } func (u mock) UpdateByID(c *gin.Context) { return }
func (u mock) ListByIDs(c *gin.Context) { return } func (u mock) GetByID(c *gin.Context) { return }
func (u mock) List(c *gin.Context) { return } func (u mock) ListByIDs(c *gin.Context) { return }
func (u mock) List(c *gin.Context) { return }
func Test_userExampleRouter(t *testing.T) { func Test_userExampleRouter(t *testing.T) {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)

View File

@@ -15,6 +15,7 @@ func init() {
func userExampleRouter(group *gin.RouterGroup, h handler.UserExampleHandler) { func userExampleRouter(group *gin.RouterGroup, h handler.UserExampleHandler) {
group.POST("/userExample", h.Create) group.POST("/userExample", h.Create)
group.DELETE("/userExample/:id", h.DeleteByID) group.DELETE("/userExample/:id", h.DeleteByID)
group.POST("/userExamples/delete/ids", h.DeleteByIDs)
group.PUT("/userExample/:id", h.UpdateByID) group.PUT("/userExample/:id", h.UpdateByID)
group.GET("/userExample/:id", h.GetByID) group.GET("/userExample/:id", h.GetByID)
group.POST("/userExamples/ids", h.ListByIDs) group.POST("/userExamples/ids", h.ListByIDs)

View File

@@ -52,6 +52,11 @@ type GetUserExampleByIDRespond struct {
// delete the templates code end // delete the templates code end
// DeleteUserExamplesByIDsRequest request form ids
type DeleteUserExamplesByIDsRequest struct {
IDs []uint64 `json:"ids" binding:"min=1"` // id list
}
// GetUserExamplesByIDsRequest request form ids // GetUserExamplesByIDsRequest request form ids
type GetUserExamplesByIDsRequest struct { type GetUserExamplesByIDsRequest struct {
IDs []uint64 `json:"ids" binding:"min=1"` // id list IDs []uint64 `json:"ids" binding:"min=1"` // id list