Skip to content

Commit 775b654

Browse files
committed
Add methods that return ChangeInfo for Update/Remove
1 parent b5ab11f commit 775b654

File tree

2 files changed

+95
-6
lines changed

2 files changed

+95
-6
lines changed

session.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -3090,6 +3090,11 @@ func (c *Collection) Insert(docs ...interface{}) error {
30903090
// http://www.mongodb.org/display/DOCS/Atomic+Operations
30913091
//
30923092
func (c *Collection) Update(selector interface{}, update interface{}) error {
3093+
_, err := c.UpdateWithChangeInfo(selector, update)
3094+
return err
3095+
}
3096+
3097+
func (c *Collection) UpdateWithChangeInfo(selector interface{}, update interface{}) (info *ChangeInfo, err error) {
30933098
if selector == nil {
30943099
selector = bson.D{}
30953100
}
@@ -3099,10 +3104,13 @@ func (c *Collection) Update(selector interface{}, update interface{}) error {
30993104
Update: update,
31003105
}
31013106
lerr, err := c.writeOp(&op, true)
3102-
if err == nil && lerr != nil && !lerr.UpdatedExisting {
3103-
return ErrNotFound
3107+
if err == nil && lerr != nil {
3108+
if !lerr.UpdatedExisting {
3109+
return info, ErrNotFound
3110+
}
3111+
info = &ChangeInfo{Updated: lerr.modified, Matched: lerr.N}
31043112
}
3105-
return err
3113+
return info, err
31063114
}
31073115

31083116
// UpdateId is a convenience helper equivalent to:
@@ -3247,14 +3255,22 @@ func (c *Collection) UpsertId(id interface{}, update interface{}) (info *ChangeI
32473255
// http://www.mongodb.org/display/DOCS/Removing
32483256
//
32493257
func (c *Collection) Remove(selector interface{}) error {
3258+
_, err := c.RemoveWithChangeInfo(selector)
3259+
return err
3260+
}
3261+
3262+
func (c *Collection) RemoveWithChangeInfo(selector interface{}) (info *ChangeInfo, err error) {
32503263
if selector == nil {
32513264
selector = bson.D{}
32523265
}
32533266
lerr, err := c.writeOp(&deleteOp{c.FullName, selector, 1, 1}, true)
3254-
if err == nil && lerr != nil && lerr.N == 0 {
3255-
return ErrNotFound
3267+
if err == nil && lerr != nil {
3268+
if lerr.N == 0 {
3269+
return nil, ErrNotFound
3270+
}
3271+
info = &ChangeInfo{Removed: lerr.N, Matched: lerr.N}
32563272
}
3257-
return err
3273+
return info, err
32583274
}
32593275

32603276
// RemoveId is a convenience helper equivalent to:

session_test.go

+73
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,46 @@ func (s *S) TestUpdate(c *C) {
683683
c.Assert(err, Equals, mgo.ErrNotFound)
684684
}
685685

686+
func (s *S) TestUpdateWithChangeInfo(c *C) {
687+
session, err := mgo.Dial("localhost:40001")
688+
c.Assert(err, IsNil)
689+
defer session.Close()
690+
691+
coll := session.DB("mydb").C("mycoll")
692+
693+
ns := []int{40, 41, 42, 43, 44, 45, 46}
694+
for _, n := range ns {
695+
err := coll.Insert(M{"k": n, "n": n})
696+
c.Assert(err, IsNil)
697+
}
698+
699+
// No changes is a no-op and shouldn't return an error.
700+
info, err := coll.UpdateWithChangeInfo(M{"k": 42}, M{"$set": M{"n": 42}})
701+
c.Assert(err, IsNil)
702+
c.Assert(info.Matched, Equals, 1)
703+
c.Assert(info.Updated, Equals, 0)
704+
c.Assert(info.Removed, Equals, 0)
705+
c.Assert(info.UpsertedId, IsNil)
706+
707+
info, err = coll.UpdateWithChangeInfo(M{"k": 42}, M{"$inc": M{"n": 1}})
708+
c.Assert(err, IsNil)
709+
c.Assert(info.Matched, Equals, 1)
710+
c.Assert(info.Updated, Equals, 1)
711+
c.Assert(info.Removed, Equals, 0)
712+
c.Assert(info.UpsertedId, IsNil)
713+
714+
result := make(M)
715+
err = coll.Find(M{"k": 42}).One(result)
716+
c.Assert(err, IsNil)
717+
c.Assert(result["n"], Equals, 43)
718+
719+
info, err = coll.UpdateWithChangeInfo(M{"k": 47}, M{"k": 47, "n": 47})
720+
c.Assert(err, Equals, mgo.ErrNotFound)
721+
722+
err = coll.Find(M{"k": 47}).One(result)
723+
c.Assert(err, Equals, mgo.ErrNotFound)
724+
}
725+
686726
func (s *S) TestUpdateId(c *C) {
687727
session, err := mgo.Dial("localhost:40001")
688728
c.Assert(err, IsNil)
@@ -986,6 +1026,39 @@ func (s *S) TestRemove(c *C) {
9861026
c.Assert(result.N, Equals, 44)
9871027
}
9881028

1029+
func (s *S) TestRemoveWithChangeInfo(c *C) {
1030+
session, err := mgo.Dial("localhost:40001")
1031+
c.Assert(err, IsNil)
1032+
defer session.Close()
1033+
1034+
coll := session.DB("mydb").C("mycoll")
1035+
1036+
ns := []int{40, 41, 42, 43, 44, 45, 46}
1037+
for _, n := range ns {
1038+
err := coll.Insert(M{"n": n})
1039+
c.Assert(err, IsNil)
1040+
}
1041+
1042+
info, err := coll.RemoveWithChangeInfo(M{"n": M{"$gt": 42}})
1043+
c.Assert(err, IsNil)
1044+
c.Assert(info.Removed, Equals, 1)
1045+
c.Assert(info.Matched, Equals, 1)
1046+
c.Assert(info.Updated, Equals, 0)
1047+
c.Assert(info.UpsertedId, IsNil)
1048+
1049+
result := &struct{ N int }{}
1050+
err = coll.Find(M{"n": 42}).One(result)
1051+
c.Assert(err, IsNil)
1052+
c.Assert(result.N, Equals, 42)
1053+
1054+
err = coll.Find(M{"n": 43}).One(result)
1055+
c.Assert(err, Equals, mgo.ErrNotFound)
1056+
1057+
err = coll.Find(M{"n": 44}).One(result)
1058+
c.Assert(err, IsNil)
1059+
c.Assert(result.N, Equals, 44)
1060+
}
1061+
9891062
func (s *S) TestRemoveId(c *C) {
9901063
session, err := mgo.Dial("localhost:40001")
9911064
c.Assert(err, IsNil)

0 commit comments

Comments
 (0)