Esempio n. 1
0
DeleteOp parseDeleteCommand(StringData dbName, const BSONObj& cmd) {
    BSONElement deletes;
    DeleteOp op;
    parseWriteCommand(dbName, cmd, "deletes", &deletes, &op);
    checkBSONType(Array, deletes);
    for (auto doc : deletes.Obj()) {
        checkTypeInArray(Object, doc, deletes);
        op.deletes.emplace_back();
        auto& del = op.deletes.back();  // delete is a reserved word.
        bool haveQ = false;
        bool haveLimit = false;
        for (auto field : doc.Obj()) {
            const StringData fieldName = field.fieldNameStringData();
            if (fieldName == "q") {
                haveQ = true;
                checkBSONType(Object, field);
                del.query = field.Obj();
            } else if (fieldName == "collation") {
                checkBSONType(Object, field);
                del.collation = field.Obj();
            } else if (fieldName == "limit") {
                haveLimit = true;
                uassert(ErrorCodes::TypeMismatch,
                        str::stream()
                            << "The limit field in delete objects must be a number. Got a "
                            << typeName(field.type()),
                        field.isNumber());

                // Using a double to avoid throwing away illegal fractional portion. Don't want to
                // accept 0.5 here.
                const double limit = field.numberDouble();
                uassert(ErrorCodes::FailedToParse,
                        str::stream() << "The limit field in delete objects must be 0 or 1. Got "
                                      << limit,
                        limit == 0 || limit == 1);
                del.multi = (limit == 0);
            } else {
                uasserted(ErrorCodes::FailedToParse,
                          str::stream() << "Unrecognized field in delete operation: " << fieldName);
            }
        }
        uassert(ErrorCodes::FailedToParse, "The 'q' field is required for all deletes", haveQ);
        uassert(
            ErrorCodes::FailedToParse, "The 'limit' field is required for all deletes", haveLimit);
    }
    checkOpCountForCommand(op.deletes.size());
    return op;
}
Esempio n. 2
0
UpdateOp parseUpdateCommand(StringData dbName, const BSONObj& cmd) {
    BSONElement updates;
    UpdateOp op;
    parseWriteCommand(dbName, cmd, "updates", &updates, &op);
    checkBSONType(Array, updates);
    for (auto doc : updates.Obj()) {
        checkTypeInArray(Object, doc, updates);
        op.updates.emplace_back();
        auto& update = op.updates.back();
        bool haveQ = false;
        bool haveU = false;
        for (auto field : doc.Obj()) {
            const StringData fieldName = field.fieldNameStringData();
            if (fieldName == "q") {
                haveQ = true;
                checkBSONType(Object, field);
                update.query = field.Obj();
            } else if (fieldName == "u") {
                haveU = true;
                checkBSONType(Object, field);
                update.update = field.Obj();
            } else if (fieldName == "collation") {
                checkBSONType(Object, field);
                update.collation = field.Obj();
            } else if (fieldName == "arrayFilters") {
                checkBSONType(Array, field);
                for (auto arrayFilter : field.Obj()) {
                    checkBSONType(Object, arrayFilter);
                    update.arrayFilters.push_back(arrayFilter.Obj());
                }
            } else if (fieldName == "multi") {
                checkBSONType(Bool, field);
                update.multi = field.Bool();
            } else if (fieldName == "upsert") {
                checkBSONType(Bool, field);
                update.upsert = field.Bool();
            } else {
                uasserted(ErrorCodes::FailedToParse,
                          str::stream() << "Unrecognized field in update operation: " << fieldName);
            }
        }

        uassert(ErrorCodes::FailedToParse, "The 'q' field is required for all updates", haveQ);
        uassert(ErrorCodes::FailedToParse, "The 'u' field is required for all updates", haveU);
    }
    checkOpCountForCommand(op.updates.size());
    return op;
}
Esempio n. 3
0
InsertOp parseInsertCommand(StringData dbName, const BSONObj& cmd) {
    BSONElement documents;
    InsertOp op;
    parseWriteCommand(dbName, cmd, "documents", &documents, &op);
    checkType(Array, documents);
    for (auto doc : documents.Obj()) {
        checkTypeInArray(Object, doc, documents);
        op.documents.push_back(doc.Obj());
    }
    checkOpCountForCommand(op.documents.size());

    if (op.ns.isSystemDotIndexes()) {
        // This is only for consistency with sharding.
        uassert(ErrorCodes::InvalidLength,
                "Insert commands to system.indexes are limited to a single insert",
                op.documents.size() == 1);
    }

    return op;
}