本文整理汇总了C++中StringData::empty方法的典型用法代码示例。如果您正苦于以下问题:C++ StringData::empty方法的具体用法?C++ StringData::empty怎么用?C++ StringData::empty使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StringData
的用法示例。
在下文中一共展示了StringData::empty方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: prepare
Status ModifierBit::prepare(mutablebson::Element root,
StringData matchedField,
ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue,
str::stream() << "The positional operator did not find the match "
"needed from the query. Unexpanded update: "
<< _fieldRef.dottedField());
}
_fieldRef.setPart(_posDollar, matchedField);
}
// Locate the field name in 'root'.
Status status = pathsupport::findLongestPrefix(
_fieldRef, root, &_preparedState->idxFound, &_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
} else if (!status.isOK()) {
return status;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
//
// in-place and no-op logic
//
// If the field path is not fully present, then this mod cannot be in place, nor is a
// noOp.
if (!_preparedState->elemFound.ok() || _preparedState->idxFound < (_fieldRef.numParts() - 1)) {
// If no target element exists, the value we will write is the result of applying
// the operation to a zero-initialized integer element.
_preparedState->newValue = apply(SafeNum(static_cast<int32_t>(0)));
return Status::OK();
}
if (!_preparedState->elemFound.isIntegral()) {
mb::Element idElem = mb::findElementNamed(root.leftChild(), "_id");
return Status(ErrorCodes::BadValue,
str::stream() << "Cannot apply $bit to a value of non-integral type."
<< idElem.toString()
<< " has the field "
<< _preparedState->elemFound.getFieldName()
<< " of non-integer type "
<< typeName(_preparedState->elemFound.getType()));
}
const SafeNum currentValue = _preparedState->elemFound.getValueSafeNum();
// Apply the op over the existing value and the mod value, and capture the result.
_preparedState->newValue = apply(currentValue);
if (!_preparedState->newValue.isValid()) {
// TODO: Include list of ops, if that is easy, at some future point.
return Status(ErrorCodes::BadValue,
str::stream() << "Failed to apply $bit operations to current value: "
<< currentValue.debugString());
}
// If the values are identical (same type, same value), then this is a no-op.
if (_preparedState->newValue.isIdentical(currentValue)) {
_preparedState->noOp = execInfo->noOp = true;
return Status::OK();
}
return Status::OK();
}
示例2: fixSpec
//.........这里部分代码省略.........
"text index with reserved fields _fts/ftsx not allowed",
!str::equals( e.fieldName(), "_fts" ) &&
!str::equals( e.fieldName(), "_ftsx" ) );
e = i.next();
} while ( !e.eoo() && INDEX_NAME == e.valuestrsafe() );
}
// extraAfterFields
while ( !e.eoo() ) {
uassert( 17290,
"compound text index key suffix fields must have value 1",
e.numberInt() == 1 && !str::equals( "_ftsx", e.fieldName() ) );
e = i.next();
}
}
}
if ( spec["weights"].type() == Object ) {
BSONObjIterator i( spec["weights"].Obj() );
while ( i.more() ) {
BSONElement e = i.next();
uassert( 17283,
"weight for text index needs numeric type",
e.isNumber() );
m[e.fieldName()] = e.numberInt();
// Verify weight refers to a valid field.
if ( str::equals( e.fieldName(), "$**" ) ) {
continue;
}
FieldRef keyField( e.fieldName() );
uassert( 17294,
"weight cannot be on an empty field",
keyField.numParts() != 0 );
for ( size_t i = 0; i < keyField.numParts(); i++ ) {
StringData part = keyField.getPart(i);
uassert( 17291, "weight cannot have empty path component", !part.empty() );
uassert( 17292,
"weight cannot have path component with $ prefix",
!part.startsWith( "$" ) );
}
}
}
else if ( spec["weights"].str() == WILDCARD ) {
m[WILDCARD] = 1;
}
else if ( !spec["weights"].eoo() ) {
uasserted( 17284, "text index option 'weights' must be an object" );
}
BSONObj weights;
{
BSONObjBuilder b;
for ( map<string,int>::iterator i = m.begin(); i != m.end(); ++i ) {
uassert( 16674, "score for word too high",
i->second > 0 && i->second < MAX_WORD_WEIGHT );
b.append( i->first, i->second );
}
weights = b.obj();
}
BSONElement default_language_elt = spec["default_language"];
string default_language( default_language_elt.str() );
if ( default_language_elt.eoo() ) {
default_language = moduleDefaultLanguage;
示例3: validateKeyPattern
Status validateKeyPattern(const BSONObj& key) {
const ErrorCodes::Error code = ErrorCodes::CannotCreateIndex;
if (key.objsize() > 2048)
return Status(code, "Index key pattern too large.");
if (key.isEmpty())
return Status(code, "Index keys cannot be empty.");
string pluginName = IndexNames::findPluginName(key);
if (pluginName.size()) {
if (!IndexNames::isKnownName(pluginName))
return Status(
code, mongoutils::str::stream() << "Unknown index plugin '" << pluginName << '\'');
}
BSONObjIterator it(key);
while (it.more()) {
BSONElement keyElement = it.next();
if (keyElement.isNumber()) {
double value = keyElement.number();
if (std::isnan(value)) {
return {code, "Values in the index key pattern cannot be NaN."};
} else if (value == 0.0) {
return {code, "Values in the index key pattern cannot be 0."};
}
} else if (keyElement.type() != String) {
return {code,
str::stream() << "Values in index key pattern cannot be of type "
<< typeName(keyElement.type())
<< ". Only numbers > 0, numbers < 0, and strings are allowed."};
}
if (keyElement.type() == String && pluginName != keyElement.str()) {
return Status(code, "Can't use more than one index plugin for a single index.");
}
// Ensure that the fields on which we are building the index are valid: a field must not
// begin with a '$' unless it is part of a DBRef or text index, and a field path cannot
// contain an empty field. If a field cannot be created or updated, it should not be
// indexable.
FieldRef keyField(keyElement.fieldName());
const size_t numParts = keyField.numParts();
if (numParts == 0) {
return Status(code, "Index keys cannot be an empty field.");
}
// "$**" is acceptable for a text index.
if (mongoutils::str::equals(keyElement.fieldName(), "$**") &&
keyElement.valuestrsafe() == IndexNames::TEXT)
continue;
if (mongoutils::str::equals(keyElement.fieldName(), "_fts") &&
keyElement.valuestrsafe() != IndexNames::TEXT) {
return Status(code, "Index key contains an illegal field name: '_fts'");
}
for (size_t i = 0; i != numParts; ++i) {
const StringData part = keyField.getPart(i);
// Check if the index key path contains an empty field.
if (part.empty()) {
return Status(code, "Index keys cannot contain an empty field.");
}
if (part[0] != '$')
continue;
// Check if the '$'-prefixed field is part of a DBRef: since we don't have the
// necessary context to validate whether this is a proper DBRef, we allow index
// creation on '$'-prefixed names that match those used in a DBRef.
const bool mightBePartOfDbRef =
(i != 0) && (part == "$db" || part == "$id" || part == "$ref");
if (!mightBePartOfDbRef) {
return Status(code,
"Index key contains an illegal field name: "
"field name starts with '$'.");
}
}
}
return Status::OK();
}
示例4: prepare
Status ModifierAddToSet::prepare(mb::Element root, StringData matchedField, ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue,
str::stream() << "The positional operator did not find the match "
"needed from the query. Unexpanded update: "
<< _fieldRef.dottedField());
}
_fieldRef.setPart(_posDollar, matchedField);
}
// Locate the field name in 'root'.
Status status = pathsupport::findLongestPrefix(
_fieldRef, root, &_preparedState->idxFound, &_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
} else if (!status.isOK()) {
return status;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
//
// in-place and no-op logic
//
// If the field path is not fully present, then this mod cannot be in place, nor is a
// noOp.
if (!_preparedState->elemFound.ok() || _preparedState->idxFound < (_fieldRef.numParts() - 1)) {
// If no target element exists, we will simply be creating a new array.
_preparedState->addAll = true;
return Status::OK();
}
// This operation only applies to arrays
if (_preparedState->elemFound.getType() != mongo::Array) {
mb::Element idElem = mb::findElementNamed(root.leftChild(), "_id");
return Status(ErrorCodes::BadValue,
str::stream()
<< "Cannot apply $addToSet to a non-array field. Field named '"
<< _preparedState->elemFound.getFieldName() << "' has a non-array type "
<< typeName(_preparedState->elemFound.getType()) << " in the document "
<< idElem.toString());
}
// If the array is empty, then we don't need to check anything: all of the values are
// going to be added.
if (!_preparedState->elemFound.hasChildren()) {
_preparedState->addAll = true;
return Status::OK();
}
// For each value in the $each clause, compare it against the values in the array. If
// the element is not present, record it as one to add.
mb::Element eachIter = _val.leftChild();
while (eachIter.ok()) {
mb::Element where =
mb::findElement(_preparedState->elemFound.leftChild(), mb::woEqualTo(eachIter, false));
if (!where.ok()) {
// The element was not found. Record the element from $each as one to be added.
_preparedState->elementsToAdd.push_back(eachIter);
}
eachIter = eachIter.rightSibling();
}
// If we didn't find any elements to add, then this is a no-op.
if (_preparedState->elementsToAdd.empty()) {
_preparedState->noOp = execInfo->noOp = true;
}
return Status::OK();
}
示例5: prepare
Status ModifierSet::prepare(mutablebson::Element root,
const StringData& matchedField,
ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(&root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue, "matched field not provided");
}
_preparedState->boundDollar = matchedField.toString();
_fieldRef.setPart(_posDollar, _preparedState->boundDollar);
}
// Locate the field name in 'root'. Note that we may not have all the parts in the path
// in the doc -- which is fine. Our goal now is merely to reason about whether this mod
// apply is a noOp or whether is can be in place. The remainin path, if missing, will
// be created during the apply.
Status status = pathsupport::findLongestPrefix(_fieldRef,
root,
&_preparedState->idxFound,
&_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
}
else if (_modOptions.fromReplication && status.code() == ErrorCodes::PathNotViable) {
// If we are coming from replication and it is an invalid path,
// then push on indicating that we had a blocking element, which we stopped at
_preparedState->elemIsBlocking = true;
}
else if (!status.isOK()) {
return status;
}
if (_setMode == SET_ON_INSERT) {
execInfo->context = ModifierInterface::ExecInfo::INSERT_CONTEXT;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
//
// in-place and no-op logic
//
// If the field path is not fully present, then this mod cannot be in place, nor is a
// noOp.
if (!_preparedState->elemFound.ok() ||
_preparedState->idxFound < (_fieldRef.numParts()-1)) {
return Status::OK();
}
// If the value being $set is the same as the one already in the doc, than this is a
// noOp.
if (_preparedState->elemFound.ok() &&
_preparedState->idxFound == (_fieldRef.numParts()-1) &&
_preparedState->elemFound.compareWithBSONElement(_val, false /*ignore field*/) == 0) {
execInfo->noOp = _preparedState->noOp = true;
}
return Status::OK();
}
示例6: validateIndexSpec
StatusWith<BSONObj> validateIndexSpec(
const BSONObj& indexSpec,
const NamespaceString& expectedNamespace,
const ServerGlobalParams::FeatureCompatibility& featureCompatibility) {
bool hasKeyPatternField = false;
bool hasNamespaceField = false;
bool hasVersionField = false;
bool hasCollationField = false;
auto fieldNamesValidStatus = validateIndexSpecFieldNames(indexSpec);
if (!fieldNamesValidStatus.isOK()) {
return fieldNamesValidStatus;
}
boost::optional<IndexVersion> resolvedIndexVersion;
for (auto&& indexSpecElem : indexSpec) {
auto indexSpecElemFieldName = indexSpecElem.fieldNameStringData();
if (IndexDescriptor::kKeyPatternFieldName == indexSpecElemFieldName) {
if (indexSpecElem.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << IndexDescriptor::kKeyPatternFieldName
<< "' must be an object, but got "
<< typeName(indexSpecElem.type())};
}
std::vector<StringData> keys;
for (auto&& keyElem : indexSpecElem.Obj()) {
auto keyElemFieldName = keyElem.fieldNameStringData();
if (std::find(keys.begin(), keys.end(), keyElemFieldName) != keys.end()) {
return {ErrorCodes::BadValue,
str::stream() << "The field '" << keyElemFieldName
<< "' appears multiple times in the index key pattern "
<< indexSpecElem.Obj()};
}
keys.push_back(keyElemFieldName);
}
hasKeyPatternField = true;
} else if (IndexDescriptor::kNamespaceFieldName == indexSpecElemFieldName) {
if (indexSpecElem.type() != BSONType::String) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << IndexDescriptor::kNamespaceFieldName
<< "' must be a string, but got "
<< typeName(indexSpecElem.type())};
}
StringData ns = indexSpecElem.valueStringData();
if (ns.empty()) {
return {ErrorCodes::BadValue,
str::stream() << "The field '" << IndexDescriptor::kNamespaceFieldName
<< "' cannot be an empty string"};
}
if (ns != expectedNamespace.ns()) {
return {ErrorCodes::BadValue,
str::stream() << "The value of the field '"
<< IndexDescriptor::kNamespaceFieldName
<< "' ("
<< ns
<< ") doesn't match the namespace '"
<< expectedNamespace.ns()
<< "'"};
}
hasNamespaceField = true;
} else if (IndexDescriptor::kIndexVersionFieldName == indexSpecElemFieldName) {
if (!indexSpecElem.isNumber()) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << IndexDescriptor::kIndexVersionFieldName
<< "' must be a number, but got "
<< typeName(indexSpecElem.type())};
}
auto requestedIndexVersionAsInt = representAs<int>(indexSpecElem.number());
if (!requestedIndexVersionAsInt) {
return {ErrorCodes::BadValue,
str::stream()
<< "Index version must be representable as a 32-bit integer, but got "
<< indexSpecElem.toString(false, false)};
}
const IndexVersion requestedIndexVersion =
static_cast<IndexVersion>(*requestedIndexVersionAsInt);
auto creationAllowedStatus = IndexDescriptor::isIndexVersionAllowedForCreation(
requestedIndexVersion, featureCompatibility, indexSpec);
if (!creationAllowedStatus.isOK()) {
return creationAllowedStatus;
}
hasVersionField = true;
resolvedIndexVersion = requestedIndexVersion;
} else if (IndexDescriptor::kCollationFieldName == indexSpecElemFieldName) {
if (indexSpecElem.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << IndexDescriptor::kNamespaceFieldName
<< "' must be an object, but got "
<< typeName(indexSpecElem.type())};
}
//.........这里部分代码省略.........
示例7: prepare
Status ModifierPull::prepare(mb::Element root, StringData matchedField, ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue,
str::stream() << "The positional operator did not find the match "
"needed from the query. Unexpanded update: "
<< _fieldRef.dottedField());
}
_fieldRef.setPart(_posDollar, matchedField);
}
// Locate the field name in 'root'.
Status status = pathsupport::findLongestPrefix(
_fieldRef, root, &_preparedState->idxFound, &_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
} else if (!status.isOK()) {
return status;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
if (!_preparedState->elemFound.ok() || _preparedState->idxFound < (_fieldRef.numParts() - 1)) {
// If no target element exists, then there is nothing to do here.
_preparedState->noOp = execInfo->noOp = true;
return Status::OK();
}
// This operation only applies to arrays
if (_preparedState->elemFound.getType() != mongo::Array)
return Status(ErrorCodes::BadValue, "Cannot apply $pull to a non-array value");
// If the array is empty, there is nothing to pull, so this is a noop.
if (!_preparedState->elemFound.hasChildren()) {
_preparedState->noOp = execInfo->noOp = true;
return Status::OK();
}
// Walk the values in the array
mb::Element cursor = _preparedState->elemFound.leftChild();
while (cursor.ok()) {
if (isMatch(cursor))
_preparedState->elementsToRemove.push_back(cursor);
cursor = cursor.rightSibling();
}
// If we didn't find any elements to add, then this is a no-op, and therefore in place.
if (_preparedState->elementsToRemove.empty()) {
_preparedState->noOp = execInfo->noOp = true;
}
return Status::OK();
}
示例8: dcmlNorm
void BSONComparatorInterfaceBase<T>::hashCombineBSONElement(
size_t& hash,
BSONElement elemToHash,
ComparisonRulesSet rules,
const StringData::ComparatorInterface* stringComparator) {
boost::hash_combine(hash, elemToHash.canonicalType());
const StringData fieldName = elemToHash.fieldNameStringData();
if ((rules & ComparisonRules::kConsiderFieldName) && !fieldName.empty()) {
SimpleStringDataComparator::kInstance.hash_combine(hash, fieldName);
}
switch (elemToHash.type()) {
case mongo::EOO:
case mongo::Undefined:
case mongo::jstNULL:
case mongo::MaxKey:
case mongo::MinKey:
// These are valueless types
break;
case mongo::Bool:
boost::hash_combine(hash, elemToHash.boolean());
break;
case mongo::bsonTimestamp:
boost::hash_combine(hash, elemToHash.timestamp().asULL());
break;
case mongo::Date:
boost::hash_combine(hash, elemToHash.date().asInt64());
break;
case mongo::NumberDecimal: {
const Decimal128 dcml = elemToHash.numberDecimal();
if (dcml.toAbs().isGreater(Decimal128(std::numeric_limits<double>::max(),
Decimal128::kRoundTo34Digits,
Decimal128::kRoundTowardZero)) &&
!dcml.isInfinite() && !dcml.isNaN()) {
// Normalize our decimal to force equivalent decimals
// in the same cohort to hash to the same value
Decimal128 dcmlNorm(dcml.normalize());
boost::hash_combine(hash, dcmlNorm.getValue().low64);
boost::hash_combine(hash, dcmlNorm.getValue().high64);
break;
}
// Else, fall through and convert the decimal to a double and hash.
// At this point the decimal fits into the range of doubles, is infinity, or is NaN,
// which doubles have a cheaper representation for.
}
case mongo::NumberDouble:
case mongo::NumberLong:
case mongo::NumberInt: {
// This converts all numbers to doubles, which ignores the low-order bits of
// NumberLongs > 2**53 and precise decimal numbers without double representations,
// but that is ok since the hash will still be the same for equal numbers and is
// still likely to be different for different numbers. (Note: this issue only
// applies for decimals when they are outside of the valid double range. See
// the above case.)
// SERVER-16851
const double dbl = elemToHash.numberDouble();
if (std::isnan(dbl)) {
boost::hash_combine(hash, std::numeric_limits<double>::quiet_NaN());
} else {
boost::hash_combine(hash, dbl);
}
break;
}
case mongo::jstOID:
elemToHash.__oid().hash_combine(hash);
break;
case mongo::String: {
if (stringComparator) {
stringComparator->hash_combine(hash, elemToHash.valueStringData());
} else {
SimpleStringDataComparator::kInstance.hash_combine(hash,
elemToHash.valueStringData());
}
break;
}
case mongo::Code:
case mongo::Symbol:
SimpleStringDataComparator::kInstance.hash_combine(hash, elemToHash.valueStringData());
break;
case mongo::Object:
case mongo::Array:
hashCombineBSONObj(hash,
elemToHash.embeddedObject(),
rules | ComparisonRules::kConsiderFieldName,
stringComparator);
break;
case mongo::DBRef:
case mongo::BinData:
// All bytes of the value are required to be identical.
SimpleStringDataComparator::kInstance.hash_combine(
//.........这里部分代码省略.........
示例9: run
bool run(OperationContext* txn,
const string& dbname,
BSONObj& cmdObj,
int,
string& errmsg,
BSONObjBuilder& result) {
BSONElement first = cmdObj.firstElement();
uassert(28528,
str::stream() << "Argument to listIndexes must be of type String, not "
<< typeName(first.type()),
first.type() == String);
StringData collectionName = first.valueStringData();
uassert(28529,
str::stream() << "Argument to listIndexes must be a collection name, "
<< "not the empty string",
!collectionName.empty());
const NamespaceString ns(dbname, collectionName);
const long long defaultBatchSize = std::numeric_limits<long long>::max();
long long batchSize;
Status parseCursorStatus = parseCommandCursorOptions(cmdObj, defaultBatchSize, &batchSize);
if (!parseCursorStatus.isOK()) {
return appendCommandStatus(result, parseCursorStatus);
}
AutoGetCollectionForRead autoColl(txn, ns);
if (!autoColl.getDb()) {
return appendCommandStatus(result,
Status(ErrorCodes::NamespaceNotFound, "no database"));
}
const Collection* collection = autoColl.getCollection();
if (!collection) {
return appendCommandStatus(result,
Status(ErrorCodes::NamespaceNotFound, "no collection"));
}
const CollectionCatalogEntry* cce = collection->getCatalogEntry();
invariant(cce);
vector<string> indexNames;
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
indexNames.clear();
cce->getAllIndexes(txn, &indexNames);
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "listIndexes", ns.ns());
auto ws = make_unique<WorkingSet>();
auto root = make_unique<QueuedDataStage>(txn, ws.get());
for (size_t i = 0; i < indexNames.size(); i++) {
BSONObj indexSpec;
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
indexSpec = cce->getIndexSpec(txn, indexNames[i]);
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "listIndexes", ns.ns());
WorkingSetID id = ws->allocate();
WorkingSetMember* member = ws->get(id);
member->keyData.clear();
member->loc = RecordId();
member->obj = Snapshotted<BSONObj>(SnapshotId(), indexSpec.getOwned());
member->transitionToOwnedObj();
root->pushBack(id);
}
std::string cursorNamespace = str::stream() << dbname << ".$cmd." << name << "."
<< ns.coll();
dassert(NamespaceString(cursorNamespace).isValid());
dassert(NamespaceString(cursorNamespace).isListIndexesCursorNS());
dassert(ns == NamespaceString(cursorNamespace).getTargetNSForListIndexes());
auto statusWithPlanExecutor = PlanExecutor::make(
txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL);
if (!statusWithPlanExecutor.isOK()) {
return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
}
unique_ptr<PlanExecutor> exec = std::move(statusWithPlanExecutor.getValue());
BSONArrayBuilder firstBatch;
const int byteLimit = FindCommon::kMaxBytesToReturnToClientAtOnce;
for (long long objCount = 0; objCount < batchSize && firstBatch.len() < byteLimit;
objCount++) {
BSONObj next;
PlanExecutor::ExecState state = exec->getNext(&next, NULL);
if (state == PlanExecutor::IS_EOF) {
break;
}
invariant(state == PlanExecutor::ADVANCED);
firstBatch.append(next);
}
CursorId cursorId = 0LL;
if (!exec->isEOF()) {
exec->saveState();
exec->detachFromOperationContext();
ClientCursor* cursor =
new ClientCursor(CursorManager::getGlobalCursorManager(),
exec.release(),
//.........这里部分代码省略.........
示例10: prepare
Status ModifierRename::prepare(mutablebson::Element root,
const StringData& matchedField,
ExecInfo* execInfo) {
// Rename doesn't work with positional fields ($)
dassert(matchedField.empty());
_preparedState.reset(new PreparedState(root));
// Locate the to field name in 'root', which must exist.
size_t fromIdxFound;
Status status = pathsupport::findLongestPrefix(_fromFieldRef,
root,
&fromIdxFound,
&_preparedState->fromElemFound);
const bool sourceExists = (_preparedState->fromElemFound.ok() &&
fromIdxFound == (_fromFieldRef.numParts() - 1));
// If we can't find the full element in the from field then we can't do anything.
if (!status.isOK() || !sourceExists) {
execInfo->noOp = true;
_preparedState->fromElemFound = root.getDocument().end();
// TODO: remove this special case from existing behavior
if (status.code() == ErrorCodes::PathNotViable) {
return status;
}
return Status::OK();
}
// Ensure no array in ancestry if what we found is not at the root
mutablebson::Element curr = _preparedState->fromElemFound.parent();
if (curr != curr.getDocument().root())
while (curr.ok() && (curr != curr.getDocument().root())) {
if (curr.getType() == Array)
return Status(ErrorCodes::BadValue,
str::stream() << "The source field cannot be an array element, '"
<< _fromFieldRef.dottedField() << "' in doc with "
<< findElementNamed(root.leftChild(), "_id").toString()
<< " has an array field called '" << curr.getFieldName() << "'");
curr = curr.parent();
}
// "To" side validation below
status = pathsupport::findLongestPrefix(_toFieldRef,
root,
&_preparedState->toIdxFound,
&_preparedState->toElemFound);
// FindLongestPrefix may return not viable or any other error and then we cannot proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
// Not an error condition as we will create the "to" path as needed.
} else if (!status.isOK()) {
return status;
}
const bool destExists = _preparedState->toElemFound.ok() &&
(_preparedState->toIdxFound == (_toFieldRef.numParts()-1));
// Ensure no array in ancestry of "to" Element
// Set to either parent, or node depending on if the full path element was found
curr = (destExists ? _preparedState->toElemFound.parent() : _preparedState->toElemFound);
if (curr != curr.getDocument().root()) {
while (curr.ok()) {
if (curr.getType() == Array)
return Status(ErrorCodes::BadValue,
str::stream()
<< "The destination field cannot be an array element, '"
<< _fromFieldRef.dottedField() << "' in doc with "
<< findElementNamed(root.leftChild(), "_id").toString()
<< " has an array field called '" << curr.getFieldName() << "'");
curr = curr.parent();
}
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fromFieldRef;
execInfo->fieldRef[1] = &_toFieldRef;
execInfo->noOp = false;
return Status::OK();
}
示例11: validateIndexSpec
StatusWith<BSONObj> validateIndexSpec(const BSONObj& indexSpec,
const NamespaceString& expectedNamespace) {
bool hasKeyPatternField = false;
bool hasNamespaceField = false;
for (auto&& indexSpecElem : indexSpec) {
auto indexSpecElemFieldName = indexSpecElem.fieldNameStringData();
if (kKeyPatternFieldName == indexSpecElemFieldName) {
if (indexSpecElem.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << kKeyPatternFieldName
<< "' must be an object, but got "
<< typeName(indexSpecElem.type())};
}
std::vector<StringData> keys;
for (auto&& keyElem : indexSpecElem.Obj()) {
auto keyElemFieldName = keyElem.fieldNameStringData();
if (std::find(keys.begin(), keys.end(), keyElemFieldName) != keys.end()) {
return {ErrorCodes::BadValue,
str::stream() << "The field '" << keyElemFieldName
<< "' appears multiple times in the index key pattern "
<< indexSpecElem.Obj()};
}
keys.push_back(keyElemFieldName);
}
hasKeyPatternField = true;
} else if (kNamespaceFieldName == indexSpecElemFieldName) {
if (indexSpecElem.type() != BSONType::String) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << kNamespaceFieldName
<< "' must be a string, but got "
<< typeName(indexSpecElem.type())};
}
StringData ns = indexSpecElem.valueStringData();
if (ns.empty()) {
return {ErrorCodes::BadValue,
str::stream() << "The field '" << kNamespaceFieldName
<< "' cannot be an empty string"};
}
if (ns != expectedNamespace.ns()) {
return {ErrorCodes::BadValue,
str::stream() << "The value of the field '" << kNamespaceFieldName << "' ("
<< ns
<< ") doesn't match the namespace '"
<< expectedNamespace.ns()
<< "'"};
}
hasNamespaceField = true;
} else if (kVersionFieldName == indexSpecElemFieldName) {
if (!indexSpecElem.isNumber()) {
return {ErrorCodes::TypeMismatch,
str::stream() << "The field '" << kVersionFieldName
<< "' must be a number, but got "
<< typeName(indexSpecElem.type())};
}
if (kIndexVersionV0 == indexSpecElem.numberInt()) {
return {ErrorCodes::CannotCreateIndex,
str::stream() << "Invalid index specification " << indexSpec
<< "; cannot create an index with "
<< kVersionFieldName
<< "="
<< kIndexVersionV0};
}
} else {
// TODO SERVER-769: Validate index options specified in the "createIndexes" command.
continue;
}
}
if (!hasKeyPatternField) {
return {ErrorCodes::FailedToParse,
str::stream() << "The '" << kKeyPatternFieldName
<< "' field is a required property of an index specification"};
}
if (!hasNamespaceField) {
// We create a new index specification with the 'ns' field set as 'expectedNamespace' if the
// field was omitted.
BSONObjBuilder bob;
bob.append(kNamespaceFieldName, expectedNamespace.ns());
bob.appendElements(indexSpec);
return bob.obj();
}
return indexSpec;
}
示例12: prepare
Status ModifierPullAll::prepare(mutablebson::Element root,
StringData matchedField,
ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(&root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_positionalPathIndex) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue,
str::stream() << "The positional operator did not find the match "
"needed from the query. Unexpanded update: "
<< _fieldRef.dottedField());
}
_fieldRef.setPart(_positionalPathIndex, matchedField);
}
// Locate the field name in 'root'. Note that if we don't have the full path in the
// doc, there isn't anything to unset, really.
Status status = pathsupport::findLongestPrefix(
_fieldRef, root, &_preparedState->pathFoundIndex, &_preparedState->pathFoundElement);
// Check if we didn't find the full path
if (status.isOK()) {
const bool destExists = (_preparedState->pathFoundIndex == (_fieldRef.numParts() - 1));
if (!destExists) {
execInfo->noOp = true;
} else {
// If the path exists, we require the target field to be already an
// array.
if (_preparedState->pathFoundElement.getType() != Array) {
mb::Element idElem = mb::findElementNamed(root.leftChild(), "_id");
return Status(
ErrorCodes::BadValue,
str::stream() << "Can only apply $pullAll to an array. " << idElem.toString()
<< " has the field "
<< _preparedState->pathFoundElement.getFieldName()
<< " of non-array type "
<< typeName(_preparedState->pathFoundElement.getType()));
}
// No children, nothing to do -- not an error state
if (!_preparedState->pathFoundElement.hasChildren()) {
execInfo->noOp = true;
} else {
mutablebson::Element elem = _preparedState->pathFoundElement.leftChild();
while (elem.ok()) {
if (std::find_if(_elementsToFind.begin(),
_elementsToFind.end(),
mutableElementEqualsBSONElement(elem, _collator)) !=
_elementsToFind.end()) {
_preparedState->elementsToRemove.push_back(elem);
}
elem = elem.rightSibling();
}
// Nothing to remove so it is a noOp.
if (_preparedState->elementsToRemove.empty())
execInfo->noOp = true;
}
}
} else {
// Let the caller know we can't do anything given the mod, _fieldRef, and doc.
execInfo->noOp = true;
// okay if path not found
if (status.code() == ErrorCodes::NonExistentPath)
status = Status::OK();
}
// Let the caller know what field we care about
execInfo->fieldRef[0] = &_fieldRef;
return status;
}
示例13: prepare
Status ModifierBit::prepare(mutablebson::Element root,
const StringData& matchedField,
ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue, "matched field not provided");
}
_preparedState->boundDollar = matchedField.toString();
_fieldRef.setPart(_posDollar, _preparedState->boundDollar);
}
// Locate the field name in 'root'.
Status status = pathsupport::findLongestPrefix(_fieldRef,
root,
&_preparedState->idxFound,
&_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
}
else if (!status.isOK()) {
return status;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
//
// in-place and no-op logic
//
// If the field path is not fully present, then this mod cannot be in place, nor is a
// noOp.
if (!_preparedState->elemFound.ok() ||
_preparedState->idxFound < (_fieldRef.numParts() - 1)) {
// If no target element exists, the value we will write is the result of applying
// the operation to a zero-initialized integer element.
_preparedState->newValue = apply(SafeNum(static_cast<int>(0)));
return Status::OK();
}
if (!_preparedState->elemFound.isIntegral())
return Status(
ErrorCodes::BadValue,
"Cannot apply $bit to a value of non-integral type");
const SafeNum currentValue = _preparedState->elemFound.getValueSafeNum();
// Apply the op over the existing value and the mod value, and capture the result.
_preparedState->newValue = apply(currentValue);
if (!_preparedState->newValue.isValid())
return Status(ErrorCodes::BadValue,
"Failed to apply $bit to current value");
// If the values are identical (same type, same value), then this is a no-op.
if (_preparedState->newValue.isIdentical(currentValue)) {
_preparedState->noOp = execInfo->noOp = true;
return Status::OK();
}
return Status::OK();
}
示例14: prepare
Status ModifierInc::prepare(mutablebson::Element root,
StringData matchedField,
ExecInfo* execInfo) {
_preparedState.reset(new PreparedState(root.getDocument()));
// If we have a $-positional field, it is time to bind it to an actual field part.
if (_posDollar) {
if (matchedField.empty()) {
return Status(ErrorCodes::BadValue,
str::stream() << "The positional operator did not find the match "
"needed from the query. Unexpanded update: "
<< _fieldRef.dottedField());
}
_fieldRef.setPart(_posDollar, matchedField);
}
// Locate the field name in 'root'. Note that we may not have all the parts in the path
// in the doc -- which is fine. Our goal now is merely to reason about whether this mod
// apply is a noOp or whether is can be in place. The remaining path, if missing, will
// be created during the apply.
Status status = pathsupport::findLongestPrefix(
_fieldRef, root, &_preparedState->idxFound, &_preparedState->elemFound);
// FindLongestPrefix may say the path does not exist at all, which is fine here, or
// that the path was not viable or otherwise wrong, in which case, the mod cannot
// proceed.
if (status.code() == ErrorCodes::NonExistentPath) {
_preparedState->elemFound = root.getDocument().end();
} else if (!status.isOK()) {
return status;
}
// We register interest in the field name. The driver needs this info to sort out if
// there is any conflict among mods.
execInfo->fieldRef[0] = &_fieldRef;
// Capture the value we are going to write. At this point, there may not be a value
// against which to operate, so the result will be simply _val.
_preparedState->newValue = _val;
//
// in-place and no-op logic
//
// If the field path is not fully present, then this mod cannot be in place, nor is a
// noOp.
if (!_preparedState->elemFound.ok() || _preparedState->idxFound < (_fieldRef.numParts() - 1)) {
// For multiplication, we treat ops against missing as yielding zero. We take
// advantage here of the promotion rules for SafeNum; the expression below will
// always yield a zero of the same type of operand that the user provided
// (e.g. double).
if (_mode == MODE_MUL)
_preparedState->newValue *= SafeNum(static_cast<int>(0));
return Status::OK();
}
// If the value being $inc'ed is the same as the one already in the doc, than this is a
// noOp.
if (!_preparedState->elemFound.isNumeric()) {
mb::Element idElem = mb::findFirstChildNamed(root, "_id");
return Status(ErrorCodes::TypeMismatch,
str::stream() << "Cannot apply " << (_mode == MODE_INC ? "$inc" : "$mul")
<< " to a value of non-numeric type. {" << idElem.toString()
<< "} has the field '"
<< _preparedState->elemFound.getFieldName()
<< "' of non-numeric type "
<< typeName(_preparedState->elemFound.getType()));
}
const SafeNum currentValue = _preparedState->elemFound.getValueSafeNum();
// Update newValue w.r.t to the current value of the found element.
if (_mode == MODE_INC)
_preparedState->newValue += currentValue;
else
_preparedState->newValue *= currentValue;
// If the result of the addition is invalid, we must return an error.
if (!_preparedState->newValue.isValid()) {
mb::Element idElem = mb::findFirstChildNamed(root, "_id");
return Status(ErrorCodes::BadValue,
str::stream() << "Failed to apply $inc operations to current value ("
<< currentValue.debugString() << ") for document {"
<< idElem.toString() << "}");
}
// If the values are identical (same type, same value), then this is a no-op.
if (_preparedState->newValue.isIdentical(currentValue)) {
_preparedState->noOp = execInfo->noOp = true;
return Status::OK();
}
return Status::OK();
}
示例15: initialize
Status HostAndPort::initialize(StringData s) {
size_t colonPos = s.rfind(':');
StringData hostPart = s.substr(0, colonPos);
// handle ipv6 hostPart (which we require to be wrapped in []s)
const size_t openBracketPos = s.find('[');
const size_t closeBracketPos = s.find(']');
if (openBracketPos != std::string::npos) {
if (openBracketPos != 0) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "'[' present, but not first character in "
<< s.toString());
}
if (closeBracketPos == std::string::npos) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "ipv6 address is missing closing ']' in hostname in "
<< s.toString());
}
hostPart = s.substr(openBracketPos + 1, closeBracketPos - openBracketPos - 1);
// prevent accidental assignment of port to the value of the final portion of hostPart
if (colonPos < closeBracketPos) {
colonPos = std::string::npos;
} else if (colonPos != closeBracketPos + 1) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "Extraneous characters between ']' and pre-port ':'"
<< " in "
<< s.toString());
}
} else if (closeBracketPos != std::string::npos) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "']' present without '[' in " << s.toString());
} else if (s.find(':') != colonPos) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "More than one ':' detected. If this is an ipv6 address,"
<< " it needs to be surrounded by '[' and ']'; "
<< s.toString());
}
if (hostPart.empty()) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "Empty host component parsing HostAndPort from \""
<< escape(s.toString())
<< "\"");
}
int port;
if (colonPos != std::string::npos) {
const StringData portPart = s.substr(colonPos + 1);
Status status = parseNumberFromStringWithBase(portPart, 10, &port);
if (!status.isOK()) {
return status;
}
if (port <= 0) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "Port number " << port
<< " out of range parsing HostAndPort from \""
<< escape(s.toString())
<< "\"");
}
} else {
port = -1;
}
_host = hostPart.toString();
_port = port;
return Status::OK();
}