Status LogBuilder::addToSetsWithNewFieldName(StringData name, const mutablebson::Element val) { mutablebson::Element elemToSet = _logRoot.getDocument().makeElementWithNewFieldName(name, val); if (!elemToSet.ok()) return Status(ErrorCodes::InternalError, str::stream() << "Could not create new '" << name << "' element from existing element '" << val.getFieldName() << "' of type " << typeName(val.getType())); return addToSets(elemToSet); }
Status createPathAt(const FieldRef& prefix, size_t idxFound, mutablebson::Element elemFound, mutablebson::Element newElem) { Status status = Status::OK(); // Sanity check that 'idxField' is an actual part. const size_t size = prefix.numParts(); if (idxFound >= size) { return Status(ErrorCodes::BadValue, "index larger than path size"); } mutablebson::Document& doc = elemFound.getDocument(); // If we are creating children under an array and a numeric index is next, then perhaps // we need padding. size_t i = idxFound; bool inArray = false; if (elemFound.getType() == mongol::Array) { size_t newIdx = 0; if (!isNumeric(prefix.getPart(idxFound), &newIdx)) { return Status(ErrorCodes::InvalidPath, "Array require numeric fields"); } status = maybePadTo(&elemFound, newIdx); if (!status.isOK()) { return status; } // If there is a next field, that would be an array element. We'd like to mark that // field because we create array elements differently than we do regular objects. if (++i < size) { inArray = true; } } // Create all the remaining parts but the last one. for (; i < size - 1; i++) { mutablebson::Element elem = doc.makeElementObject(prefix.getPart(i)); if (!elem.ok()) { return Status(ErrorCodes::InternalError, "cannot create path"); } // If this field is an array element, we wrap it in an object (because array // elements are wraped in { "N": <element> } objects. if (inArray) { // TODO pass empty StringData to makeElementObject, when that's supported. mutablebson::Element arrayObj = doc.makeElementObject("" /* it's an array */); if (!arrayObj.ok()) { return Status(ErrorCodes::InternalError, "cannot create item on array"); } status = arrayObj.pushBack(elem); if (!status.isOK()) { return status; } status = elemFound.pushBack(arrayObj); if (!status.isOK()) { return status; } inArray = false; } else { status = elemFound.pushBack(elem); if (!status.isOK()) { return status; } } elemFound = elem; } // Attach the last element. Here again, if we're in a field that is an array element, // we wrap it in an object first. if (inArray) { // TODO pass empty StringData to makeElementObject, when that's supported. mutablebson::Element arrayObj = doc.makeElementObject("" /* it's an array */); if (!arrayObj.ok()) { return Status(ErrorCodes::InternalError, "cannot create item on array"); } status = arrayObj.pushBack(newElem); if (!status.isOK()) { return status; } status = elemFound.pushBack(arrayObj); if (!status.isOK()) { return status; } } else { status = elemFound.pushBack(newElem); if (!status.isOK()) { return status; } } return Status::OK(); }