static void printField (fieldType i) { unsigned char letter = fieldDescs[i].spec->letter; const char *name; const char *language; if (letter == FIELD_LETTER_NO_USE) letter = '-'; if (! fieldDescs[i].spec->name) name = "NONE"; else name = getFieldName (i); if (fieldDescs[i].language == LANG_IGNORE) language = "NONE"; else language = getLanguageName (fieldDescs[i].language); printf((Option.machinable? "%c\t%s\t%s\t%s\t%s\t%s\n": MAKE_FIELD_FMT(c)), letter, name, isFieldEnabled (i)? "on": "off", language, getFieldDesc (i)->spec->renderEscaped? "TRUE": "FALSE", fieldDescs[i].spec->description? fieldDescs[i].spec->description: "NONE"); }
std::ostream& PVStructure::dumpValue(std::ostream& o) const { o << format::indent() << getStructure()->getID() << ' ' << getFieldName(); String extendsName = getExtendsStructureName(); if(extendsName.length()>0) { o << " extends " << extendsName; } o << std::endl; { format::indent_scope s(o); PVFieldPtrArray const & fieldsData = getPVFields(); if (fieldsData.size() != 0) { size_t length = getStructure()->getNumberFields(); for(size_t i=0; i<length; i++) { PVFieldPtr fieldField = fieldsData[i]; Type type = fieldField->getField()->getType(); if (type == scalar || type == scalarArray) o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl; else o << *(fieldField.get()); } } } return o; }
std::string Element::toString() const { if (!ok()) return "INVALID-MUTABLE-ELEMENT"; if (hasValue()) return getValue().toString(); const BSONType type = getType(); // The only types that sometimes don't have a value are Object and Array nodes. dassert((type == mongo::Object) || (type == mongo::Array)); if (type == mongo::Object) { BSONObjBuilder builder; writeTo(&builder); BSONObj obj = builder.obj(); return obj.firstElement().toString(); } else { // It must be an array. BSONObjBuilder builder; BSONArrayBuilder arrayBuilder(builder.subarrayStart(getFieldName())); writeArrayTo(&arrayBuilder); arrayBuilder.done(); BSONObj obj = builder.obj(); return obj.firstElement().toString(); } }
bool GuiInspectorDynamicField::onAdd() { if( !Parent::onAdd() ) return false; //pushObjectToBack(mEdit); // Create our renaming field mRenameCtrl = new GuiTextEditCtrl(); mRenameCtrl->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorDynamicFieldProfile" ); char szName[512]; dSprintf( szName, 512, "IE_%s_%d_%s_Rename", mRenameCtrl->getClassName(), mInspector->getInspectObject()->getId(), getFieldName() ); mRenameCtrl->registerObject( szName ); // Our command will evaluate to : // // if( (editCtrl).getText() !$= "" ) // (field).renameField((editCtrl).getText()); // char szBuffer[1024]; dSprintf( szBuffer, sizeof( szBuffer ), "if( %d.getText() !$= \"\" ) %d.renameField(%d.getText());", mRenameCtrl->getId(), getId(), mRenameCtrl->getId() ); mRenameCtrl->setText( getFieldName() ); mRenameCtrl->setField("Validate", szBuffer ); addObject( mRenameCtrl ); // Resize the name control to fit in our caption rect mRenameCtrl->resize( mCaptionRect.point, mCaptionRect.extent ); // Resize the value control to leave space for the delete button mEdit->resize( mValueRect.point, mValueRect.extent); // Clear out any caption set from Parent::onAdd // since we are rendering the fieldname with our 'rename' control. mCaption = StringTable->insert( "" ); // Create delete button control mDeleteButton = new GuiBitmapButtonCtrl(); SimObject* profilePtr = Sim::findObject("InspectorDynamicFieldButton"); if( profilePtr != NULL ) mDeleteButton->setControlProfile( dynamic_cast<GuiControlProfile*>(profilePtr) ); dSprintf( szBuffer, sizeof( szBuffer ), "%d.apply(\"\");%d.schedule(1,\"inspectGroup\");", getId(), mParent->getId() ); // FIXME Hardcoded image mDeleteButton->setField( "Bitmap", "tools/gui/images/iconDelete" ); mDeleteButton->setField( "Text", "X" ); mDeleteButton->setField( "Command", szBuffer ); mDeleteButton->setSizing( horizResizeLeft, vertResizeCenter ); mDeleteButton->resize(Point2I(getWidth() - 20,2), Point2I(16, 16)); mDeleteButton->registerObject(); addObject(mDeleteButton); return true; }
int csimClass::setFieldById(char *o, int id, double *v) { if ( id < 0 || id >= getClassInfo()->nRegFields ) { TheCsimError.add("csimClass::setFieldById: invalid field Id (%i) for class %s\n",id,className()); return -1; } csimFieldInfo *fi=getClassInfo()->regFields[id]; if ( fi->access != READWRITE ) { TheCsimError.add("csimClass::setFieldById: field %s is READONLY!\n",getFieldName(id)); return -1; } int i; // printf("%i %i %i\n",fi->ff,fi->df,fi->intf); switch ( fi->fieldType ) { case FLOATFIELD: *((float *)(o+(fi->offset))) = (float)(*v); break; case DOUBLEFIELD: *((double *)(o+(fi->offset))) = (double)(*v); break; case INTFIELD: *((int *)(o+(fi->offset))) = (int)(*v); break; case FLOATARRAY: for(i=0; i<fi->m; i++) { (*(*((float **)(o+(fi->offset)))+i)) = (float)v[i]; } break; case DOUBLEARRAY: memcpy(*((double **)(o+(fi->offset))),v,fi->m*sizeof(double)); break; case INTARRAY: for(i=0; i<fi->m; i++) { (*(*((int **)(o+(fi->offset)))+i)) = (int)v[i]; } break; default: { TheCsimError.add("csimClass::setFieldById: internal error this should not happen!!\n"); return -1; } } dirty = 1; return 0; }
static void printField (fieldType i) { printf("%c\t%s\t%s\t%s\t%s\n", fieldDescs[i].letter, (fieldDescs[i].name? getFieldName (i): "NONE"), fieldDescs[i].description? fieldDescs[i].description: "NONE", getFieldDesc (i)->renderEscaped? "format-char": "NONE", getFieldDesc (i)->enabled? "on": "off"); }
void AddFieldDlg::accept() { if (getFieldName().isEmpty()) { QMessageBox::critical(this, windowTitle(), "Please enter a valid field name!"); return; } QDialog::accept(); }
TITANIUM_FUNCTION(ResultSet, getFieldName) { ENSURE_UINT_AT_INDEX(index, 0); const std::string result = getFieldName(index); if (result == nullptr) { return get_context().CreateNull(); } return get_context().CreateString(result); }
// Find field with name fieldName in object // NULL if field not found GvField* GvFieldData::getField(const GvNode *object,const char * fieldName) const { for (int i = 0; i < fields.getLength(); i++) { if (getFieldName(i) == fieldName) { return(getField(object,i)); } } return(NULL); }
// Find field with name fieldName in object, Result -1 if not found int GvFieldData::getFieldIndex(const char * fieldName) const { for (int i = 0; i < fields.getLength(); i++) { if (getFieldName(i) == fieldName) { return(i); } } return(-1); }
void ParsedExclusionProjection::parse(const boost::intrusive_ptr<ExpressionContext>& expCtx, const BSONObj& spec, ExclusionNode* node, size_t depth) { for (auto elem : spec) { const auto fieldName = elem.fieldNameStringData().toString(); // A $ should have been detected in ParsedAggregationProjection's parsing before we get // here. invariant(fieldName[0] != '$'); switch (elem.type()) { case BSONType::Bool: case BSONType::NumberInt: case BSONType::NumberLong: case BSONType::NumberDouble: case BSONType::NumberDecimal: { // We have already verified this is an exclusion projection. invariant(!elem.trueValue()); node->excludePath(FieldPath(fieldName)); break; } case BSONType::Object: { // This object represents a nested projection specification, like the sub-object in // {a: {b: 0, c: 0}} or {"a.b": {c: 0}}. ExclusionNode* child; if (elem.fieldNameStringData().find('.') == std::string::npos) { child = node->addOrGetChild(fieldName); } else { // A dotted field is not allowed in a sub-object, and should have been detected // in ParsedAggregationProjection's parsing before we get here. invariant(depth == 0); // We need to keep adding children to our tree until we create a child that // represents this dotted path. child = node; auto fullPath = FieldPath(fieldName); while (fullPath.getPathLength() > 1) { child = child->addOrGetChild(fullPath.getFieldName(0)); fullPath = fullPath.tail(); } // It is illegal to construct an empty FieldPath, so the above loop ends one // iteration too soon. Add the last path here. child = child->addOrGetChild(fullPath.fullPath()); } parse(expCtx, elem.Obj(), child, depth + 1); break; } default: { MONGO_UNREACHABLE; } } } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int QualityMetricFilter::filter() { int err = 0; if (m_Output.get() == NULL) { m_Output = DataArray<bool>::CreateArray(0, getFieldName()); } m_Output->Resize(m_NumValues); m_Output->initializeWithZeros(); if (m_DataType == Ebsd::Int8) { FILTER_DATA(int8_t); } if (m_DataType == Ebsd::UInt8) { FILTER_DATA(uint8_t); } if (m_DataType == Ebsd::Int16) { FILTER_DATA(int16_t); } if (m_DataType == Ebsd::UInt16) { FILTER_DATA(uint16_t); } if (m_DataType == Ebsd::Int32) { FILTER_DATA(int32_t); } if (m_DataType == Ebsd::UInt32) { FILTER_DATA(uint32_t); } if (m_DataType == Ebsd::Int64) { FILTER_DATA(int64_t); } if (m_DataType == Ebsd::UInt64) { FILTER_DATA(uint64_t); } if (m_DataType == Ebsd::Float) { FILTER_DATA(float); } if (m_DataType == Ebsd::Double) { FILTER_DATA(double); } return err; }
void Logger::writeMetaData () { //_fileStream << getNumberOfFields() << " "; for (unsigned int i=0; i < getNumberOfFields(); i++) { _fileStream << getFieldName(i) << " "; _fileStream << getFieldDataType(i) << " "; } _fileStream << "\n"; }
GvName GvFieldData::getEventInName(int index) const { const GvName &n = getFieldName(index); GvFieldEntry *fieldEntry = getFieldEntry(index); if (fieldEntry->type /* getType()*/ <= GV_EXPOSED_FIELD) { GvString s("set_"); s+=n.getString(); return(GvName(s)); } else return n; }
//************************************************************************************************* // PlanetNoiseParameter //************************************************************************************************* void PlanetNoiseParameter::print(bool toLog /*= false*/) { if(toLog) { DREngineLog.writeToLog("----- PlanetNoiseParameter Begin ----"); for(int i = 0; i < 21; i++) { DREngineLog.writeToLog("%s: %.4f", getFieldName(static_cast<PlanetNoiseParameterNames>(i)), values[i]); } DREngineLog.writeToLog("----- PlanetNoiseParameter Ende ----"); } else { printf("----- PlanetNoiseParameter Begin ----"); for(int i = 0; i < 21; i++) { printf("%s: %.4f", getFieldName(static_cast<PlanetNoiseParameterNames>(i)), values[i]); } printf("----- PlanetNoiseParameter Ende ----"); } }
std::string Logger::getMetaData () { //_fileStream << getNumberOfFields() << " "; std::stringstream ss; for (unsigned int i=0; i < getNumberOfFields(); i++) { ss << getFieldName(i) << " "; ss << getFieldDataType(i) << " "; } ss << "\n"; return ss.str(); }
GvName GvFieldData::getEventOutName(int index) const { const GvName &n = getFieldName(index); GvFieldEntry *fieldEntry = getFieldEntry(index); if (fieldEntry->type /*getType()*/ <= GV_EXPOSED_FIELD) { GvString s(n.getString()); s+="_changed"; return(GvName(s)); } else return(n); }
std::ostream& PVUnionArray::dumpValue(std::ostream& o) const { o << format::indent() << getUnionArray()->getID() << ' ' << getFieldName() << std::endl; size_t length = getLength(); if (length > 0) { format::indent_scope s(o); for (size_t i = 0; i < length; i++) dumpValue(o, i); } return o; }
static void addParserFields (json_t *response, const tagEntryInfo *const tag) { unsigned int i; unsigned int ftype; for (i = 0; i < tag->usedParserFields; i++) { ftype = tag->parserFields [i].ftype; if (! isFieldEnabled (ftype)) continue; json_object_set_new (response, getFieldName (ftype), json_string (tag->parserFields [i].value)); } }
void GuiInspectorField::setInspectorField( AbstractClassRep::Field *field, StringTableEntry caption, const char*arrayIndex ) { mField = field; if ( arrayIndex != NULL ) mFieldArrayIndex = StringTable->insert( arrayIndex ); if ( !caption || !caption[0] ) mCaption = getFieldName(); else mCaption = caption; _setFieldDocs( mField->pFieldDocs ); }
osg::Real32 FieldAnimationAdvancer::getValue(void) const { if(getFieldId() == 0) { //Check if the Field Container is defined if(getContainer() == osg::NullFC) { SWARNING << "There is no Field Container defined to get Field Advancer" << std::endl; return 0.0f; } //Check if the field in this container is defined FieldDescription * f = getContainer()->getType().findFieldDescription(getFieldName().c_str()); if( f == NULL ) { SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName() << std::endl; return 0.0f; } //Found the Field so set my Field Id beginEditCP(FieldAnimationAdvancerPtr(this), FieldIdFieldMask); const_cast<SFUInt32*>(&_sfFieldId)->setValue(f->getFieldId()); endEditCP(FieldAnimationAdvancerPtr(this), FieldIdFieldMask); //The Field was not found if(getFieldId() == 0) { SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName() << std::endl; return 0.0f; } //Check if the field is a Real32 if(getContainer()->getField( getFieldId() )->getType() != SFReal32::getClassType()) { SWARNING << "Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName() << "Is not a SFReal32 Field." << std::endl; return 0.0f; } } return static_cast<SFReal32*>(getContainer()->getField( getFieldId() ))->getValue(); }
void FieldDefinition::fromByteArray(char *source, int buffSize) { if(buffSize < 62) return; memcpy(&fieldType, source, 4); memcpy(&fieldSize, &source[4], 4); memcpy(&is_Key, &source[8], 4); memcpy(name, &source[12], 50); cout << "\nF-Type: " << fieldType; cout << "\nF-Size: " << fieldSize; cout << "\nF-Key: " << is_Key; cout << "\nF-name: " << getFieldName(); }
/** * Equivalent to MOItem::toXmlData() but here, we do not save * index field. Because if index changed (e.g. order is changed between two versions), * there would be misunderstanding to keep index. Name is the field used to refer. * @sa MOItem::toXmlData() */ QDomElement MOParameter::toXmlData(QDomDocument & doc) { QDomElement cItem = doc.createElement(this->getClassName()); QString fieldName; QString fieldValue; for(int iF=0;iF<getNbFields();iF++) { // if(iF!=MOParameter::INDEX) // { fieldName = getFieldName(iF,Qt::UserRole); fieldName.replace(" ",XMLTools::space()); fieldValue = getFieldValue(iF).toString(); fieldValue.replace(" ",XMLTools::space()); cItem.setAttribute(fieldName,fieldValue); // } } return cItem; }
/*! *\~english * function check property name, id, header and width. * If have incorrect field name or id, then print message and all. * If have less or more items in DefHeaders or ColWidth, then set them normal. *\~russian * Функция проверяет свойства name, id, DefHeaders и ColWidth. * Если находит ошибки в свойствах name или id, она выводит сообщение об этом, но не исправляет ошибки. * Если находит ошибки в свойствах DefHeaders или ColWidth, то исправляет. *\~ */ void wDBTable::checkFields() { QStringList fl,hl,cl,il; unsigned int i; QString str; //t = getFields(property("tableInd").toInt(),true); //get list fields id fl = property("DefFields").toStringList(); il = property("DefIdList").toStringList(); cl = property("ColWidth").toStringList(); hl = property("DefHeaders").toStringList(); // proverka na nalichie field in metadata for(i=0; i<il.count(); i++) { str = getFieldName(il[i].toInt()); if(i<fl.count()) { if(str!=fl[i]) { aLog::print(aLog::Debug, QString("wDBTable unknown field name `%1' or (and) id `%1'\n").arg(str).arg(il[i])); } } else il.remove(il.at(i--)); if(i>=hl.count()) hl << str; if(i>=cl.count()) cl << property("DefaultColWidth").toString(); } while(i<hl.count()) { hl.remove(hl.at(i)); } while(i<cl.count()) { cl.remove(cl.at(i)); } setProperty("DefFields", fl ); setProperty("DefHeaders", hl ); setProperty("ColWidth", cl ); setProperty("DefIdList", il ); }
static void renderExtensionFieldMaybe (int xftype, const tagEntryInfo *const tag, json_t *response) { const char *fname = getFieldName (xftype); if (fname && isFieldRenderable (xftype) && isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag)) { switch (xftype) { case FIELD_LINE_NUMBER: json_object_set_new (response, fname, json_integer (tag->lineNumber)); break; case FIELD_FILE_SCOPE: json_object_set_new (response, fname, json_boolean(1)); break; default: json_object_set_new (response, fname, escapeFieldValue (tag, xftype, false)); } } }
void PVStructure::fixParentStructure() { PVStructure *parent = getParent(); if(parent==NULL) return; StructureConstPtr parentStructure = parent->structurePtr; String fieldName = getFieldName(); size_t index = parentStructure->getFieldIndex(fieldName); StringArray const &fieldNames = parentStructure->getFieldNames(); size_t num = fieldNames.size(); FieldConstPtrArray fields(num); FieldConstPtrArray const & oldFields = parentStructure->getFields(); for(size_t i=0; i< num; i++) { if(i==index) { fields[i] = structurePtr; } else { fields[i] = oldFields[i]; } } FieldConstPtr field = getFieldCreate()->createStructure( parentStructure->getID(),fieldNames,fields); parent->replaceField(field); parent->fixParentStructure(); }
void storageValid(const mutablebson::Document& doc) { auto currElem = doc.root().leftChild(); while (currElem.ok()) { if (currElem.getFieldName() == idFieldName) { switch (currElem.getType()) { case BSONType::RegEx: case BSONType::Array: case BSONType::Undefined: uasserted(ErrorCodes::InvalidIdField, str::stream() << "The '_id' value cannot be of type " << typeName(currElem.getType())); default: break; } } // Validate this child element. const auto deep = true; const uint32_t recursionLevel = 1; storageValid(currElem, deep, recursionLevel); currElem = currElem.rightSibling(); } }
bool XBSQLExprList::setTypeNames ( XBSQLQuerySet &querySet ) { if (expr != 0) { /* Get the type that the expression will return, and */ /* store this in the query set. */ XBSQL::VType vtype ; int length ; xbString eName ; if (!expr->getExprType (vtype )) return false ; if (!expr->getExprLength (length)) return false ; querySet.setFieldInfo (index, vtype, length, getFieldName (eName)) ; } /* If this is the last list element then return true, otherwise */ /* continue down the list. */ return next == 0 ? true : next->setTypeNames (querySet) ; }
UpdateNode::ApplyResult UpdateArrayNode::apply(ApplyParams applyParams) const { if (!applyParams.pathToCreate->empty()) { for (size_t i = 0; i < applyParams.pathToCreate->numParts(); ++i) { applyParams.pathTaken->appendPart(applyParams.pathToCreate->getPart(i)); } uasserted(ErrorCodes::BadValue, str::stream() << "The path '" << applyParams.pathTaken->dottedField() << "' must exist in the document in order to apply array updates."); } uassert(ErrorCodes::BadValue, str::stream() << "Cannot apply array updates to non-array element " << applyParams.element.toString(), applyParams.element.getType() == BSONType::Array); // Construct a map from the array index to the set of updates that should be applied to the // array element at that index. We do not apply the updates yet because we need to know how many // array elements will be updated in order to know whether to pass 'logBuilder' on to the // UpdateNode children. std::map<size_t, std::vector<UpdateNode*>> matchingElements; size_t i = 0; for (auto childElement = applyParams.element.leftChild(); childElement.ok(); childElement = childElement.rightSibling()) { // 'childElement' will always be serialized because no updates have been performed on the // array yet, and when we populate an upserted document with equality fields from the query, // arrays can only be added in entirety. invariant(childElement.hasValue()); auto arrayElement = childElement.getValue(); for (const auto& update : _children) { if (update.first.empty()) { // If the identifier is the empty string (e.g. came from 'a.$[].b'), the update // should be applied to all array elements. matchingElements[i].push_back(update.second.get()); } else { auto filter = _arrayFilters.find(update.first); invariant(filter != _arrayFilters.end()); if (filter->second->matchesBSONElement(arrayElement)) { matchingElements[i].push_back(update.second.get()); } } } ++i; } // If at most one array element will be updated, pass 'logBuilder' to the UpdateNode child when // applying it to that element. const bool childrenShouldLogThemselves = matchingElements.size() <= 1; // Keep track of which array elements were actually modified (non-noop updates) for logging // purposes. We only need to keep track of one element, since if more than one element is // modified, we log the whole array. boost::optional<mutablebson::Element> modifiedElement; size_t nModified = 0; // Update array elements. auto applyResult = ApplyResult::noopResult(); i = 0; for (auto childElement = applyParams.element.leftChild(); childElement.ok(); childElement = childElement.rightSibling()) { auto updates = matchingElements.find(i); if (updates != matchingElements.end()) { // Merge all of the updates for this array element. invariant(updates->second.size() > 0); auto mergedChild = updates->second[0]; FieldRefTempAppend tempAppend(*(applyParams.pathTaken), childElement.getFieldName()); for (size_t j = 1; j < updates->second.size(); ++j) { // Use the cached merge result, if it is available. const auto& cachedResult = _mergedChildrenCache[mergedChild][updates->second[j]]; if (cachedResult.get()) { mergedChild = cachedResult.get(); continue; } // The cached merge result is not available, so perform the merge and cache the // result. _mergedChildrenCache[mergedChild][updates->second[j]] = UpdateNode::createUpdateNodeByMerging( *mergedChild, *updates->second[j], applyParams.pathTaken.get()); mergedChild = _mergedChildrenCache[mergedChild][updates->second[j]].get(); } auto childApplyParams = applyParams; childApplyParams.element = childElement; if (!childrenShouldLogThemselves) { childApplyParams.logBuilder = nullptr; } auto childApplyResult = mergedChild->apply(childApplyParams); applyResult.indexesAffected = applyResult.indexesAffected || childApplyResult.indexesAffected; applyResult.noop = applyResult.noop && childApplyResult.noop; if (!childApplyResult.noop) { modifiedElement = childElement; ++nModified; } } ++i; } // If no elements match the array filter, report the path to the array itself as modified. if (applyParams.modifiedPaths && matchingElements.size() == 0) { applyParams.modifiedPaths->keepShortest(*applyParams.pathTaken); } // If the child updates have not been logged, log the updated array elements. if (!childrenShouldLogThemselves && applyParams.logBuilder) { if (nModified > 1) { // Log the entire array. auto logElement = applyParams.logBuilder->getDocument().makeElementWithNewFieldName( applyParams.pathTaken->dottedField(), applyParams.element); invariant(logElement.ok()); uassertStatusOK(applyParams.logBuilder->addToSets(logElement)); } else if (nModified == 1) { // Log the modified array element. invariant(modifiedElement); FieldRefTempAppend tempAppend(*(applyParams.pathTaken), modifiedElement->getFieldName()); auto logElement = applyParams.logBuilder->getDocument().makeElementWithNewFieldName( applyParams.pathTaken->dottedField(), *modifiedElement); invariant(logElement.ok()); uassertStatusOK(applyParams.logBuilder->addToSets(logElement)); } } return applyResult; }
UpdateNode::ApplyResult RenameNode::apply(ApplyParams applyParams) const { // It would make sense to store fromFieldRef and toFieldRef as members during // RenameNode::init(), but FieldRef is not copyable. auto fromFieldRef = std::make_shared<FieldRef>(_val.fieldName()); FieldRef toFieldRef(_val.valueStringData()); mutablebson::Document& document = applyParams.element.getDocument(); size_t fromIdxFound; mutablebson::Element fromElement(document.end()); auto status = pathsupport::findLongestPrefix(*fromFieldRef, document.root(), &fromIdxFound, &fromElement); if (!status.isOK() || !fromElement.ok() || fromIdxFound != (fromFieldRef->numParts() - 1)) { // We could safely remove this restriction (thereby treating a rename with a non-viable // source path as a no-op), but most updates fail on an attempt to update a non-viable path, // so we throw an error for consistency. if (status == ErrorCodes::PathNotViable) { uassertStatusOK(status); MONGO_UNREACHABLE; // The previous uassertStatusOK should always throw. } // The element we want to rename does not exist. When that happens, we treat the operation // as a no-op. The attempted from/to paths are still considered modified. if (applyParams.modifiedPaths) { applyParams.modifiedPaths->keepShortest(*fromFieldRef); applyParams.modifiedPaths->keepShortest(toFieldRef); } return ApplyResult::noopResult(); } // Renaming through an array is prohibited. Check that our source path does not contain an // array. (The element being renamed may be an array, however.) for (auto currentElement = fromElement.parent(); currentElement != document.root(); currentElement = currentElement.parent()) { invariant(currentElement.ok()); if (BSONType::Array == currentElement.getType()) { auto idElem = mutablebson::findFirstChildNamed(document.root(), "_id"); uasserted(ErrorCodes::BadValue, str::stream() << "The source field cannot be an array element, '" << fromFieldRef->dottedField() << "' in doc with " << (idElem.ok() ? idElem.toString() : "no id") << " has an array field called '" << currentElement.getFieldName() << "'"); } } // Check that our destination path does not contain an array. (If the rename will overwrite an // existing element, that element may be an array. Iff pathToCreate is empty, "element" // represents an element that we are going to overwrite.) for (auto currentElement = applyParams.pathToCreate->empty() ? applyParams.element.parent() : applyParams.element; currentElement != document.root(); currentElement = currentElement.parent()) { invariant(currentElement.ok()); if (BSONType::Array == currentElement.getType()) { auto idElem = mutablebson::findFirstChildNamed(document.root(), "_id"); uasserted(ErrorCodes::BadValue, str::stream() << "The destination field cannot be an array element, '" << toFieldRef.dottedField() << "' in doc with " << (idElem.ok() ? idElem.toString() : "no id") << " has an array field called '" << currentElement.getFieldName() << "'"); } } // Once we've determined that the rename is valid and found the source element, the actual work // gets broken out into a $set operation and an $unset operation. Note that, generally, we // should call the init() method of a ModifierNode before calling its apply() method, but the // init() methods of SetElementNode and UnsetNode don't do anything, so we can skip them. SetElementNode setElement(fromElement); auto setElementApplyResult = setElement.apply(applyParams); ApplyParams unsetParams(applyParams); unsetParams.element = fromElement; unsetParams.pathToCreate = std::make_shared<FieldRef>(); unsetParams.pathTaken = fromFieldRef; UnsetNode unsetElement; auto unsetElementApplyResult = unsetElement.apply(unsetParams); // Determine the final result based on the results of the $set and $unset. ApplyResult applyResult; applyResult.indexesAffected = setElementApplyResult.indexesAffected || unsetElementApplyResult.indexesAffected; // The $unset would only be a no-op if the source element did not exist, in which case we would // have exited early with a no-op result. invariant(!unsetElementApplyResult.noop); return applyResult; }