@@ -729,11 +729,11 @@ def process_update_operator_rename(self, key, update_expression):
729729 def process_update_operator_set_on_insert (self , key , update_expression , new_doc = False ):
730730 # print "Update Operator: $setOnInsert ", key, update_expression
731731 if new_doc :
732- self .data [key ] = OrderedDict (self .data [key ].items () + update_expression .items ())
732+ self .data [key ] = OrderedDict (self .data [key ].items () + deepcopy ( update_expression .items () ))
733733
734734 def process_update_operator_set (self , key , update_expression ):
735735 # print "Update Operator: $set ", update
736- self .data [key ] = OrderedDict (self .data [key ].items () + update_expression .items ())
736+ self .data [key ] = OrderedDict (self .data [key ].items () + deepcopy ( update_expression .items () ))
737737
738738 def process_update_operator_unset (self , key , update_expression ):
739739 # print "Update Operator: $unset ", update
@@ -837,11 +837,9 @@ def process_update_operator_pull_all(self, key, update_expression):
837837 raise MongoModelException ("Cannot apply $pullAll to a non-array field." , code = 10142 )
838838
839839 def evaluate (self , query , document ):
840- if len (query ) == 0 :
841- # If we made it here, the evaluate function must NOT be called from the `find` function, and thus
842- # we can return false. Note in find() function, an empty query means maches all documents.
843- return False
844840 acc = True
841+ if len (query ) == 0 :
842+ return len (document ) == 0
845843 for field in query .keys ():
846844 if field == '_id' :
847845 tmp = OrderedDict ()
@@ -962,21 +960,15 @@ def has_operator_expressions(doc):
962960
963961 def process_update_operator (self , key , update , new_doc = False ):
964962 op_update = self .has_operator_expressions (update )
965- old_data = None
966-
967- try :
968- old_data = deepcopy (self .data [key ])
969- if op_update :
970- for k in update :
971- if k == '$setOnInsert' :
972- self .mapUpdateOperator [k ](key , update [k ], new_doc = new_doc )
973- elif k in self .mapUpdateOperator :
974- self .mapUpdateOperator [k ](key , update [k ])
975- else :
976- self .replace (key , update )
977- except MongoModelException as e :
978- self .data [key ] = old_data
979- raise e
963+ old_data = deepcopy (self .data [key ])
964+ if op_update :
965+ for k in update :
966+ if k == '$setOnInsert' :
967+ self .mapUpdateOperator [k ](key , update [k ], new_doc = new_doc )
968+ elif k in self .mapUpdateOperator :
969+ self .mapUpdateOperator [k ](key , update [k ])
970+ else :
971+ self .replace (key , update )
980972
981973 def deep_transform_logical_operators (self , selector = None ):
982974 new_selector = {}
@@ -1126,26 +1118,27 @@ def update(self, query, update, upsert, multi):
11261118 raise MongoModelException ('multi update only works with $ operators' , code = 10158 )
11271119 if isOperatorUpdate :
11281120 self .validate_update_object (update )
1129- if len (query ) == 0 :
1130- return
1131- key = query .keys ()[0 ]
11321121 any = False
11331122 old_data = deepcopy (self .data )
11341123 n = 0
11351124 try :
1125+ if len (query ) == 0 :
1126+ # Update all existing docs. And since the query is empty, do NOT do upsert.
1127+ any = True
1128+ for k in self .data .keys ():
1129+ n += 1
1130+ self .process_update_operator (k , update )
1131+ if not multi :
1132+ break
1133+ key = query .keys ()[0 ]
11361134 for k , item in self .data .iteritems ():
11371135 if evaluate (key , query [key ], item , self .options ):
11381136 any = True
11391137 n += 1
11401138 # print "Result: ", item
1141- if len (update ) > 0 :
1142- self .process_update_operator (k , update )
1143- if not multi :
1144- return
1145- else :
1146- self .replace (k , update )
1147- if not multi :
1148- return
1139+ self .process_update_operator (k , update )
1140+ if not multi :
1141+ break
11491142 if any :
11501143 for index in self .indexes :
11511144 if not index .inError :
@@ -1186,7 +1179,7 @@ def update(self, query, update, upsert, multi):
11861179 if "_id" in query :
11871180 update ["_id" ] = query ["_id" ]
11881181 self .insert (update )
1189- else :
1182+ elif not any :
11901183 # mongoDB raise an exception for the '$setOnInsert' update operator even if the upsert is False
11911184 if '$setOnInsert' in update .keys () and len (update ['$setOnInsert' ]) == 0 :
11921185 raise MongoModelException (
@@ -1285,7 +1278,11 @@ def validate_and_build_entry(self, documents, first_build=False):
12851278 check_none_at_all = True ,
12861279 check_none_next = True ,
12871280 debug = False )
1288- entry = entry + reduce ((lambda acc , x : acc + x ), map ((lambda x : str (x )), _values ), "" )
1281+ if len (_values ) == 0 :
1282+ # empty array
1283+ entry = entry + '[]'
1284+ else :
1285+ entry = entry + reduce ((lambda acc , x : acc + x ), map ((lambda x : str (x )), _values ), "" )
12891286 if entry in seen :
12901287 # print "[{}] in {} ? {}".format(entry, seen, entry in seen)
12911288 # print "Violating keys " + str(key)
0 commit comments