Skip to content

Commit 3e4b3fe

Browse files
authored
Merge pull request globalsign#2 from eaglerayp/feature/bulkUpdateError
Feature/bulk update error
2 parents 3e2c238 + b873cea commit 3e4b3fe

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

bulk_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,28 @@ func (s *S) TestBulkUpdate(c *C) {
317317
c.Assert(res, DeepEquals, []doc{{10}, {20}, {30}})
318318
}
319319

320+
func (s *S) TestBulkUpdateOver1000(c *C) {
321+
session, err := mgo.Dial("localhost:40001")
322+
c.Assert(err, IsNil)
323+
defer session.Close()
324+
325+
coll := session.DB("mydb").C("mycoll")
326+
327+
bulk := coll.Bulk()
328+
for i := 0; i < 1010; i++ {
329+
bulk.Insert(M{"n": i})
330+
}
331+
_, err = bulk.Run()
332+
c.Assert(err, IsNil)
333+
bulk = coll.Bulk()
334+
for i := 0; i < 1010; i++ {
335+
bulk.Update(M{"n": i}, M{"$set": M{"m": i}})
336+
}
337+
// if not handle well, mongo will return error here
338+
_, err = bulk.Run()
339+
c.Assert(err, IsNil)
340+
}
341+
320342
func (s *S) TestBulkUpdateError(c *C) {
321343
session, err := mgo.Dial("localhost:40001")
322344
c.Assert(err, IsNil)

session.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4766,6 +4766,58 @@ func (c *Collection) writeOp(op interface{}, ordered bool) (lerr *LastError, err
47664766
}
47674767
return &lerr, nil
47684768
}
4769+
if updateOp, ok := op.(bulkUpdateOp); ok && len(updateOp) > 1000 {
4770+
var lerr LastError
4771+
4772+
// Maximum batch size is 1000. Must split out in separate operations for compatibility.
4773+
for i := 0; i < len(updateOp); i += 1000 {
4774+
l := i + 1000
4775+
if l > len(updateOp) {
4776+
l = len(updateOp)
4777+
}
4778+
4779+
oplerr, err := c.writeOpCommand(socket, safeOp, updateOp[i:l], ordered, bypassValidation)
4780+
4781+
lerr.N += oplerr.N
4782+
lerr.modified += oplerr.modified
4783+
if err != nil {
4784+
lerr.ecases = append(lerr.ecases, BulkErrorCase{i, err})
4785+
if ordered {
4786+
break
4787+
}
4788+
}
4789+
}
4790+
if len(lerr.ecases) != 0 {
4791+
return &lerr, lerr.ecases[0].Err
4792+
}
4793+
return &lerr, nil
4794+
}
4795+
if deleteOps, ok := op.(bulkDeleteOp); ok && len(deleteOps) > 1000 {
4796+
var lerr LastError
4797+
4798+
// Maximum batch size is 1000. Must split out in separate operations for compatibility.
4799+
for i := 0; i < len(deleteOps); i += 1000 {
4800+
l := i + 1000
4801+
if l > len(deleteOps) {
4802+
l = len(deleteOps)
4803+
}
4804+
4805+
oplerr, err := c.writeOpCommand(socket, safeOp, deleteOps[i:l], ordered, bypassValidation)
4806+
4807+
lerr.N += oplerr.N
4808+
lerr.modified += oplerr.modified
4809+
if err != nil {
4810+
lerr.ecases = append(lerr.ecases, BulkErrorCase{i, err})
4811+
if ordered {
4812+
break
4813+
}
4814+
}
4815+
}
4816+
if len(lerr.ecases) != 0 {
4817+
return &lerr, lerr.ecases[0].Err
4818+
}
4819+
return &lerr, nil
4820+
}
47694821
return c.writeOpCommand(socket, safeOp, op, ordered, bypassValidation)
47704822
} else if updateOps, ok := op.(bulkUpdateOp); ok {
47714823
var lerr LastError

0 commit comments

Comments
 (0)