public static void applyUpdateCommands(BsonDocument doc, BsonDocument change_spec)
{
foreach (var field in change_spec) {
if (field.Name.Length > 0 && field.Name[0] == '$') {
// update command
switch (field.Name) {
case "$set":
_applySet(doc, field.Value.AsBsonDocument);
break;
case "$inc":
_applyInc(doc, field.Value.AsBsonDocument);
break;
case "$unset":
_applyUnset(doc, field.Value.AsBsonDocument);
break;
case "$push":
case "$pushAll":
case "$addToSet":
case "$pop":
case "$pull":
case "$pullAll":
case "$rename":
case "$":
throw new Exception("unimplemented update operator: " + field.Name);
default:
throw new Exception("unknown update operator: " + field.Name);
}
} else {
// field replace
if (field.Value.BsonType == BsonType.Document) {
if (!doc.Contains(field.Name) ||
doc.GetElement(field.Name).Value.BsonType != BsonType.Document) {
// make a document to hold the recurse
doc.Set(field.Name, new BsonDocument());
}
// recursively apply changes
applyUpdateCommands(doc.GetElement(field.Name).Value.AsBsonDocument,
field.Value.AsBsonDocument);
} else {
// otherwise just apply the change directly
doc.Set(field.Name, field.Value);
}
}
}
}