private Map<String, Object> findAndModify(Collection collection,
UpdateOp updateOp,
boolean upsert,
boolean checkConditions) {
DBCollection dbCollection = getDBCollection(collection);
QueryBuilder query = getByKeyQuery(updateOp.key);
BasicDBObject setUpdates = new BasicDBObject();
BasicDBObject incUpdates = new BasicDBObject();
BasicDBObject unsetUpdates = new BasicDBObject();
for (Entry<String, Operation> entry : updateOp.changes.entrySet()) {
String k = entry.getKey();
if (k.equals(UpdateOp.ID)) {
// avoid exception "Mod on _id not allowed"
continue;
}
Operation op = entry.getValue();
switch (op.type) {
case SET: {
setUpdates.append(k, op.value);
break;
}
case INCREMENT: {
incUpdates.append(k, op.value);
break;
}
case SET_MAP_ENTRY: {
setUpdates.append(k, op.value);
break;
}
case REMOVE_MAP_ENTRY: {
unsetUpdates.append(k, "1");
break;
}
case SET_MAP: {
String[] kv = k.split("\\.");
BasicDBObject sub = new BasicDBObject();
sub.put(kv[1], op.value);
setUpdates.append(kv[0], sub);
break;
}
case CONTAINS_MAP_ENTRY: {
if (checkConditions) {
query.and(k).exists(op.value);
}
break;
}
}
}
BasicDBObject update = new BasicDBObject();
if (!setUpdates.isEmpty()) {
update.append("$set", setUpdates);
}
if (!incUpdates.isEmpty()) {
update.append("$inc", incUpdates);
}
if (!unsetUpdates.isEmpty()) {
update.append("$unset", unsetUpdates);
}
// dbCollection.update(query, update, true /*upsert*/, false /*multi*/,
// WriteConcern.SAFE);
// return null;
long start = start();
try {
DBObject oldNode = dbCollection.findAndModify(query.get(), null /*fields*/,
null /*sort*/, false /*remove*/, update, false /*returnNew*/,
upsert /*upsert*/);
if (checkConditions && oldNode == null) {
return null;
}