Skip to content

Commit

Permalink
update: [Rest] add ArrayFilters to Update
Browse files Browse the repository at this point in the history
  • Loading branch information
kainonly committed Nov 6, 2023
1 parent 94f1817 commit 601b8de
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 54 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/bytedance/sonic v1.10.2
github.com/cloudwego/hertz v0.7.1
github.com/go-faker/faker/v4 v4.2.0
github.com/go-playground/validator/v10 v10.15.5
github.com/go-playground/validator/v10 v10.16.0
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/google/uuid v1.4.0
github.com/hertz-contrib/binding v0.1.0
Expand Down Expand Up @@ -56,11 +56,11 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
golang.org/x/arch v0.5.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -180,6 +182,8 @@ golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5P
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y=
golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
Expand All @@ -201,6 +205,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -215,6 +221,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -225,6 +233,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
Expand Down
70 changes: 40 additions & 30 deletions rest/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ type Controller struct {
type CreateDto struct {
Collection string `path:"collection" vd:"snake"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Xdata M `json:"xdata,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) Create(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -70,8 +70,8 @@ func (x *Controller) Create(ctx context.Context, c *app.RequestContext) {
type BulkCreateDto struct {
Collection string `path:"collection" vd:"snake"`
Data []M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Xdata M `json:"xdata,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) BulkCreate(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -123,7 +123,7 @@ func (x *Controller) BulkCreate(ctx context.Context, c *app.RequestContext) {
type SizeDto struct {
Collection string `path:"collection" vd:"snake"`
Filter M `json:"filter" vd:"required"`
Xfilter M `json:"xfilter"`
Xfilter M `json:"xfilter,omitempty"`
}

func (x *Controller) Size(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -158,9 +158,9 @@ type FindDto struct {
Pagesize int64 `header:"x-pagesize" vd:"omitempty,min=0,max=1000"`
Page int64 `header:"x-page" vd:"omitempty,min=0"`
Filter M `json:"filter" vd:"required"`
Xfilter M `json:"xfilter"`
Sort []string `query:"sort" vd:"omitempty,dive,sort"`
Keys []string `query:"keys"`
Xfilter M `json:"xfilter,omitempty"`
Sort []string `query:"sort,omitempty" vd:"omitempty,dive,sort"`
Keys []string `query:"keys,omitempty"`
}

func (x *Controller) Find(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -225,8 +225,8 @@ func (x *Controller) Find(ctx context.Context, c *app.RequestContext) {
type FindOneDto struct {
Collection string `path:"collection" vd:"snake"`
Filter M `json:"filter" vd:"gt=0"`
Xfilter M `json:"xfilter"`
Keys []string `query:"keys"`
Xfilter M `json:"xfilter,omitempty"`
Keys []string `query:"keys,omitempty"`
}

func (x *Controller) FindOne(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -261,7 +261,7 @@ func (x *Controller) FindOne(ctx context.Context, c *app.RequestContext) {
type FindByIdDto struct {
Collection string `path:"collection" vd:"snake"`
Id string `path:"id" vd:"mongodb"`
Keys []string `query:"keys"`
Keys []string `query:"keys,omitempty"`
}

func (x *Controller) FindById(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -290,12 +290,13 @@ func (x *Controller) FindById(ctx context.Context, c *app.RequestContext) {
}

type UpdateDto struct {
Collection string `path:"collection" vd:"snake"`
Filter M `json:"filter" vd:"gt=0"`
Xfilter M `json:"xfilter"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Collection string `path:"collection" vd:"snake"`
Filter M `json:"filter" vd:"gt=0"`
Xfilter M `json:"xfilter,omitempty"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata,omitempty"`
ArrayFilters []interface{} `json:"arrayFilters,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) Update(ctx context.Context, c *app.RequestContext) {
Expand All @@ -322,6 +323,10 @@ func (x *Controller) Update(ctx context.Context, c *app.RequestContext) {
dto.Data["$set"] = M{}
}
dto.Data["$set"].(M)["update_time"] = time.Now()
opt := options.Update()
if dto.ArrayFilters != nil {
opt = opt.SetArrayFilters(options.ArrayFilters{Filters: dto.ArrayFilters})
}

if dto.Txn != "" {
if err := x.Service.Pending(ctx, dto.Txn, PendingDto{
Expand All @@ -338,7 +343,7 @@ func (x *Controller) Update(ctx context.Context, c *app.RequestContext) {
return
}

r, err := x.Service.Update(ctx, dto.Collection, dto.Filter, dto.Data)
r, err := x.Service.Update(ctx, dto.Collection, dto.Filter, dto.Data, opt)
if err != nil {
c.Error(err)
return
Expand All @@ -348,11 +353,12 @@ func (x *Controller) Update(ctx context.Context, c *app.RequestContext) {
}

type UpdateByIdDto struct {
Collection string `path:"collection" vd:"snake"`
Id string `path:"id" vd:"mongodb"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Collection string `path:"collection" vd:"snake"`
Id string `path:"id" vd:"mongodb"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata,omitempty"`
ArrayFilters []interface{} `json:"arrayFilters,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) UpdateById(ctx context.Context, c *app.RequestContext) {
Expand All @@ -376,6 +382,10 @@ func (x *Controller) UpdateById(ctx context.Context, c *app.RequestContext) {
}
dto.Data["$set"].(M)["update_time"] = time.Now()
id, _ := primitive.ObjectIDFromHex(dto.Id)
opt := options.Update()
if dto.ArrayFilters != nil {
opt = opt.SetArrayFilters(options.ArrayFilters{Filters: dto.ArrayFilters})
}

if dto.Txn != "" {
if err := x.Service.Pending(ctx, dto.Txn, PendingDto{
Expand All @@ -392,7 +402,7 @@ func (x *Controller) UpdateById(ctx context.Context, c *app.RequestContext) {
return
}

r, err := x.Service.UpdateById(ctx, dto.Collection, id, dto.Data)
r, err := x.Service.UpdateById(ctx, dto.Collection, id, dto.Data, opt)
if err != nil {
c.Error(err)
return
Expand All @@ -405,8 +415,8 @@ type ReplaceDto struct {
Collection string `path:"collection" vd:"snake"`
Id string `path:"id" vd:"mongodb"`
Data M `json:"data" vd:"gt=0"`
Xdata M `json:"xdata"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Xdata M `json:"xdata,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) Replace(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -456,7 +466,7 @@ func (x *Controller) Replace(ctx context.Context, c *app.RequestContext) {
type DeleteDto struct {
Collection string `path:"collection" vd:"snake"`
Id string `path:"id" vd:"mongodb"`
Txn string `query:"txn" vd:"omitempty,uuid"`
Txn string `query:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) Delete(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -499,8 +509,8 @@ func (x *Controller) Delete(ctx context.Context, c *app.RequestContext) {
type BulkDeleteDto struct {
Collection string `path:"collection" vd:"snake"`
Filter M `json:"filter" vd:"gt=0"`
Xfilter M `json:"xfilter"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Xfilter M `json:"xfilter,omitempty"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

func (x *Controller) BulkDelete(ctx context.Context, c *app.RequestContext) {
Expand Down Expand Up @@ -546,7 +556,7 @@ func (x *Controller) BulkDelete(ctx context.Context, c *app.RequestContext) {
type SortDto struct {
Collection string `path:"collection" vd:"snake"`
Data SortDtoData `json:"data" vd:"structonly"`
Txn string `json:"txn" vd:"omitempty,uuid"`
Txn string `json:"txn,omitempty" vd:"omitempty,uuid"`
}

type SortDtoData struct {
Expand Down
70 changes: 57 additions & 13 deletions rest/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,15 +688,6 @@ func TestFindById(t *testing.T) {
assert.Empty(t, result["update_time"])
}

//func TestFindByIdKeysBad(t *testing.T) {
// u := Url(fmt.Sprintf(`/users/%s`, userId), Params{
// {"keys", "abc1"},
// })
// resp, err := Req("GET", u, nil)
// assert.NoError(t, err)
// assert.Equal(t, 400, resp.StatusCode())
//}

func TestUpdateValidateBad(t *testing.T) {
resp, err := Req("POST", "/users/update", M{})
assert.NoError(t, err)
Expand Down Expand Up @@ -1571,6 +1562,8 @@ func TestSortEventBad(t *testing.T) {
RecoverStream(t)
}

var couponId primitive.ObjectID

func TestMoreTransform(t *testing.T) {
resp, err := Req("POST", "/coupons/create", M{
"data": M{
Expand Down Expand Up @@ -1615,11 +1608,11 @@ func TestMoreTransform(t *testing.T) {
assert.NotEmpty(t, result)

id := result["InsertedID"].(string)
oid, _ := primitive.ObjectIDFromHex(id)
couponId, _ = primitive.ObjectIDFromHex(id)

var coupon M
err = service.Db.Collection("coupons").FindOne(context.TODO(), bson.M{
"_id": oid,
"_id": couponId,
}).Decode(&coupon)
assert.NoError(t, err)

Expand All @@ -1629,8 +1622,6 @@ func TestMoreTransform(t *testing.T) {
primitive.A{primitive.DateTime(1681336800906), primitive.DateTime(1681367405586)},
coupon["valid"],
)
//metadata := coupon["metadata"].(primitive.A)
//t.Log(metadata)
}

func TestCipherTransform(t *testing.T) {
Expand Down Expand Up @@ -2007,3 +1998,56 @@ func TestCommitTimeout(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 400, resp2.StatusCode())
}

func TestUpdateByIdWithArrayFilters(t *testing.T) {
resp, err := Req("PATCH", fmt.Sprintf(`/coupons/%s`, couponId.Hex()), M{
"data": M{
"$set": M{
"metadata.$[i].version": "v1",
},
},
"arrayFilters": []M{
{"i.name": "aps"},
},
})
assert.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode(), string(resp.Body()))

ctx := context.TODO()
var data M
err = service.Db.Collection("coupons").
FindOne(ctx, bson.M{"_id": couponId}).
Decode(&data)
assert.NoError(t, err)

assert.Equal(t, "体验卡", data["name"])
assert.Equal(t, "v1", data["metadata"].(primitive.A)[0].(M)["version"])
}

func TestUpdateWithArrayFilters(t *testing.T) {
resp, err := Req("POST", "/coupons/update", M{
"filter": M{
"name": "体验卡",
},
"data": M{
"$set": M{
"metadata.$[i].version": "v2",
},
},
"arrayFilters": []M{
{"i.name": "aps"},
},
})
assert.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode(), string(resp.Body()))

ctx := context.TODO()
var data M
err = service.Db.Collection("coupons").
FindOne(ctx, bson.M{"_id": couponId}).
Decode(&data)
assert.NoError(t, err)

assert.Equal(t, "体验卡", data["name"])
assert.Equal(t, "v2", data["metadata"].(primitive.A)[0].(M)["version"])
}
12 changes: 6 additions & 6 deletions rest/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func (x *Service) FindOne(ctx context.Context, name string, filter M, option *op
return
}

func (x *Service) Update(ctx context.Context, name string, filter M, update interface{}) (result interface{}, err error) {
if result, err = x.Db.Collection(name).UpdateMany(ctx, filter, update); err != nil {
func (x *Service) Update(ctx context.Context, name string, filter M, update interface{}, option *options.UpdateOptions) (result interface{}, err error) {
if result, err = x.Db.Collection(name).UpdateMany(ctx, filter, update, option); err != nil {
return
}
if err = x.Publish(ctx, name, PublishDto{
Expand All @@ -122,9 +122,9 @@ func (x *Service) Update(ctx context.Context, name string, filter M, update inte
return
}

func (x *Service) UpdateById(ctx context.Context, name string, id primitive.ObjectID, update interface{}) (result interface{}, err error) {
func (x *Service) UpdateById(ctx context.Context, name string, id primitive.ObjectID, update interface{}, option *options.UpdateOptions) (result interface{}, err error) {
filter := M{"_id": id}
if result, err = x.Db.Collection(name).UpdateOne(ctx, filter, update); err != nil {
if result, err = x.Db.Collection(name).UpdateOne(ctx, filter, update, option); err != nil {
return
}
if err = x.Publish(ctx, name, PublishDto{
Expand Down Expand Up @@ -330,9 +330,9 @@ func (x *Service) Invoke(ctx context.Context, dto PendingDto) (_ interface{}, _
case ActionBulkCreate:
return x.BulkCreate(ctx, dto.Name, dto.Data.(primitive.A))
case ActionUpdate:
return x.Update(ctx, dto.Name, dto.Filter, dto.Data)
return x.Update(ctx, dto.Name, dto.Filter, dto.Data, nil)
case ActionUpdateById:
return x.UpdateById(ctx, dto.Name, dto.Id, dto.Data)
return x.UpdateById(ctx, dto.Name, dto.Id, dto.Data, nil)
case ActionReplace:
return x.Replace(ctx, dto.Name, dto.Id, dto.Data)
case ActionDelete:
Expand Down

0 comments on commit 601b8de

Please sign in to comment.