@@ -4895,18 +4895,22 @@ type findModifyCmd struct {
4895
4895
Collection string `bson:"findAndModify"`
4896
4896
Query , Update , Sort , Fields interface {} `bson:",omitempty"`
4897
4897
Upsert , Remove , New bool `bson:",omitempty"`
4898
+ WriteConcern interface {} `bson:",omitempty"`
4898
4899
}
4899
4900
4900
4901
type 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"`
4903
4905
}
4904
4906
4905
4907
// Apply runs the findAndModify MongoDB command, which allows updating, upserting
4906
4908
// or removing a document matching a query and atomically returning either the old
4907
4909
// version (the default) or the new version of the document (when ReturnNew is true).
4908
4910
// If no objects are found Apply returns ErrNotFound.
4909
4911
//
4912
+ // If the session is in safe mode, the LastError result will be returned as err.
4913
+ //
4910
4914
// The Sort and Select query methods affect the result of Apply. In case
4911
4915
// multiple documents match the query, Sort enables selecting which document to
4912
4916
// 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
4943
4947
dbname := op .collection [:c ]
4944
4948
cname := op .collection [c + 1 :]
4945
4949
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
+
4946
4961
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 ,
4955
4971
}
4956
4972
4957
4973
session = session .Clone ()
@@ -4994,6 +5010,14 @@ func (q *Query) Apply(change Change, result interface{}) (info *ChangeInfo, err
4994
5010
} else if change .Upsert {
4995
5011
info .UpsertedId = lerr .UpsertedId
4996
5012
}
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
+ }
4997
5021
return info , nil
4998
5022
}
4999
5023
0 commit comments