@@ -4895,18 +4895,22 @@ type findModifyCmd struct {
48954895 Collection string `bson:"findAndModify"`
48964896 Query , Update , Sort , Fields interface {} `bson:",omitempty"`
48974897 Upsert , Remove , New bool `bson:",omitempty"`
4898+ WriteConcern interface {} `bson:",omitempty"`
48984899}
48994900
49004901type valueResult struct {
4901- Value bson.Raw
4902- LastError LastError `bson:"lastErrorObject"`
4902+ Value bson.Raw
4903+ LastError LastError `bson:"lastErrorObject"`
4904+ ConcernError writeConcernError `bson:writeConcernError`
49034905}
49044906
49054907// Apply runs the findAndModify MongoDB command, which allows updating, upserting
49064908// or removing a document matching a query and atomically returning either the old
49074909// version (the default) or the new version of the document (when ReturnNew is true).
49084910// If no objects are found Apply returns ErrNotFound.
49094911//
4912+ // If the session is in safe mode, the LastError result will be returned as err.
4913+ //
49104914// The Sort and Select query methods affect the result of Apply. In case
49114915// multiple documents match the query, Sort enables selecting which document to
49124916// act upon by ordering it first. Select enables retrieving only a selection
@@ -4943,15 +4947,27 @@ func (q *Query) Apply(change Change, result interface{}) (info *ChangeInfo, err
49434947 dbname := op .collection [:c ]
49444948 cname := op .collection [c + 1 :]
49454949
4950+ // https://docs.mongodb.com/manual/reference/command/findAndModify/#dbcmd.findAndModify
4951+ session .m .RLock ()
4952+ safeOp := session .safeOp
4953+ session .m .RUnlock ()
4954+ var writeConcern interface {}
4955+ if safeOp == nil {
4956+ writeConcern = bson.D {{Name : "w" , Value : 0 }}
4957+ } else {
4958+ writeConcern = safeOp .query .(* getLastError )
4959+ }
4960+
49464961 cmd := findModifyCmd {
4947- Collection : cname ,
4948- Update : change .Update ,
4949- Upsert : change .Upsert ,
4950- Remove : change .Remove ,
4951- New : change .ReturnNew ,
4952- Query : op .query ,
4953- Sort : op .options .OrderBy ,
4954- Fields : op .selector ,
4962+ Collection : cname ,
4963+ Update : change .Update ,
4964+ Upsert : change .Upsert ,
4965+ Remove : change .Remove ,
4966+ New : change .ReturnNew ,
4967+ Query : op .query ,
4968+ Sort : op .options .OrderBy ,
4969+ Fields : op .selector ,
4970+ WriteConcern : writeConcern ,
49554971 }
49564972
49574973 session = session .Clone ()
@@ -4994,6 +5010,14 @@ func (q *Query) Apply(change Change, result interface{}) (info *ChangeInfo, err
49945010 } else if change .Upsert {
49955011 info .UpsertedId = lerr .UpsertedId
49965012 }
5013+ if doc .ConcernError .Code != 0 {
5014+ var lerr LastError
5015+ e := doc .ConcernError
5016+ lerr .Code = e .Code
5017+ lerr .Err = e .ErrMsg
5018+ err = & lerr
5019+ return info , err
5020+ }
49975021 return info , nil
49985022}
49995023
0 commit comments