StatusWith<bool> SaslSCRAMSHA1ServerConversation::step(const StringData& inputData, std::string* outputData) { std::vector<std::string> input = StringSplitter::split(inputData.toString(), ","); _step++; if (_step > 3 || _step <= 0) { return StatusWith<bool>(ErrorCodes::AuthenticationFailed, mongoutils::str::stream() << "Invalid SCRAM-SHA-1 authentication step: " << _step); } if (_step == 1) { return _firstStep(input, outputData); } if (_step == 2) { return _secondStep(input, outputData); } *outputData = ""; return StatusWith<bool>(true); }
Status MobileKVEngine::createRecordStore(OperationContext* opCtx, StringData ns, StringData ident, const CollectionOptions& options) { // TODO: eventually will support file renaming but otherwise do not use collection options. // Mobile SE doesn't support creating an oplog if (NamespaceString::oplog(ns)) { return Status(ErrorCodes::InvalidOptions, "Replication is not supported by the mobile storage engine"); } // Mobile doesn't support capped collections if (options.capped) { return Status(ErrorCodes::InvalidOptions, "Capped collections are not supported by the mobile storage engine"); } MobileRecordStore::create(opCtx, ident.toString()); return Status::OK(); }
void WiredTigerKVEngine::_checkIdentPath(StringData ident) { size_t start = 0; size_t idx; while ((idx = ident.find('/', start)) != string::npos) { StringData dir = ident.substr(0, idx); boost::filesystem::path subdir = _path; subdir /= dir.toString(); if (!boost::filesystem::exists(subdir)) { LOG(1) << "creating subdirectory: " << dir; try { boost::filesystem::create_directory(subdir); } catch (const std::exception& e) { error() << "error creating path " << subdir.string() << ' ' << e.what(); throw; } } start = idx + 1; } }
// // delete all collections, their metadata, then the database // Status BLTreeEngine::dropDatabase( OperationContext* ctx, const StringData& db ) { const string prefix = db.toString() + "."; boost::mutex::scoped_lock lk( _entryMapMutex ); vector<string> toDrop; for (EntryMap::const_iterator i = _entryMap.begin(); i != _entryMap.end(); ++i ) { const StringData& ns = i->first; if ( ns.startsWith( prefix ) ) { toDrop.push_back( ns.toString() ); } } for (vector<string>::const_iterator j = toDrop.begin(); j != toDrop.end(); ++j ) { _dropCollection_inlock( ctx, *j ); } return closeDatabase( ctx, db ); }
Status CommittedOpTimeMetadataHook::readReplyMetadata(OperationContext* opCtx, StringData replySource, const BSONObj& metadataObj) { auto lastCommittedOpTimeField = metadataObj[kLastCommittedOpTimeFieldName]; if (lastCommittedOpTimeField.eoo()) { return Status::OK(); } invariant(lastCommittedOpTimeField.type() == BSONType::bsonTimestamp); // replySource is the HostAndPort of a single server, except when this hook is triggered // through DBClientReplicaSet, when it will be a replica set connection string. The // shardRegistry stores connection strings and hosts in its lookup table, in addition to shard // ids, so replySource can be correctly passed on to ShardRegistry::getShardNoReload. auto shard = Grid::get(_service)->shardRegistry()->getShardNoReload(replySource.toString()); if (shard) { shard->updateLastCommittedOpTime(LogicalTime(lastCommittedOpTimeField.timestamp())); } return Status::OK(); }
void NamespaceIndex::kill_ns(OperationContext* txn, StringData ns) { const NamespaceString nss(ns.toString()); invariant(txn->lockState()->isDbLockedForMode(nss.db(), MODE_X)); const Namespace n(ns); _ht->kill(txn, n); if (ns.size() <= Namespace::MaxNsColletionLen) { // Larger namespace names don't have room for $extras so they can't exist. The code // below would cause an "$extra: ns too large" error and stacktrace to be printed to the // log even though everything is fine. for (int i = 0; i <= 1; i++) { try { Namespace extra(n.extraName(i)); _ht->kill(txn, extra); } catch (DBException&) { LOG(3) << "caught exception in kill_ns" << endl; } } } }
Status ModifierCurrentDate::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 (_pathReplacementPosition) { if (matchedField.empty()) { return Status(ErrorCodes::BadValue, "matched field not provided"); } _preparedState->pathReplacementString = matchedField.toString(); _updatePath.setPart(_pathReplacementPosition, _preparedState->pathReplacementString); } // 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(_updatePath, 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] = &_updatePath; return Status::OK(); }
Database::Database(OperationContext* txn, StringData name, DatabaseCatalogEntry* dbEntry) : _name(name.toString()), _dbEntry(dbEntry), _profileName(_name + ".system.profile"), _indexesName(_name + ".system.indexes"), _viewsName(_name + ".system.views"), _views(txn, this) { Status status = validateDBName(_name); if (!status.isOK()) { warning() << "tried to open invalid db: " << _name << endl; uasserted(10028, status.toString()); } _profile = serverGlobalParams.defaultProfile; list<string> collections; _dbEntry->getCollectionNamespaces(&collections); for (list<string>::const_iterator it = collections.begin(); it != collections.end(); ++it) { const string ns = *it; _collections[ns] = _getOrCreateCollectionInstance(txn, ns); } }
bool AuthzManagerExternalStateMongos::tryAcquireAuthzUpdateLock(const StringData& why) { boost::lock_guard<boost::mutex> lkLocal(_distLockGuard); if (_authzDataUpdateLock.get()) { return false; } // Temporarily put into an auto_ptr just in case there is an exception thrown during // lock acquisition. std::auto_ptr<ScopedDistributedLock> lockHolder(new ScopedDistributedLock( configServer.getConnectionString(), "authorizationData")); lockHolder->setLockMessage(why.toString()); std::string errmsg; if (!lockHolder->acquire(_authzUpdateLockAcquisitionTimeoutMillis, &errmsg)) { warning() << "Error while attempting to acquire distributed lock for user modification: " << errmsg << endl; return false; } _authzDataUpdateLock.reset(lockHolder.release()); return true; }
rpc::UniqueReply MockRemoteDBServer::runCommandWithMetadata(MockRemoteDBServer::InstanceID id, StringData database, StringData commandName, const BSONObj& metadata, const BSONObj& commandArgs) { checkIfUp(id); std::string cmdName = commandName.toString(); BSONObj reply; { scoped_spinlock lk(_lock); uassert(ErrorCodes::IllegalOperation, str::stream() << "no reply for command: " << commandName, _cmdMap.count(cmdName)); reply = _cmdMap[cmdName]->next(); } if (_delayMilliSec > 0) { mongo::sleepmillis(_delayMilliSec); } checkIfUp(id); { scoped_spinlock lk(_lock); _cmdCount++; } // We need to construct a reply message - it will always be read through a view so it // doesn't matter whether we use CommandReplBuilder or LegacyReplyBuilder auto message = rpc::CommandReplyBuilder{} .setMetadata(rpc::makeEmptyMetadata()) .setCommandReply(reply) .done(); auto replyView = stdx::make_unique<rpc::CommandReply>(message.get()); return rpc::UniqueReply(std::move(message), std::move(replyView)); }
static Status checkUniqueIndexConstraints(OperationContext* txn, const StringData& ns, const BSONObj& newIdxKey) { txn->lockState()->assertWriteLocked( ns ); if ( shardingState.enabled() ) { CollectionMetadataPtr metadata( shardingState.getCollectionMetadata( ns.toString() )); if ( metadata ) { ShardKeyPattern shardKeyPattern(metadata->getKeyPattern()); if (!shardKeyPattern.isUniqueIndexCompatible(newIdxKey)) { return Status(ErrorCodes::CannotCreateIndex, str::stream() << "cannot create unique index over " << newIdxKey << " with shard key pattern " << shardKeyPattern.toBSON()); } } } return Status::OK(); }
StatusWith<std::string> WiredTigerUtil::getMetadata(OperationContext* opCtx, StringData uri) { invariant(opCtx); WiredTigerCursor curwrap("metadata:create", WiredTigerSession::kMetadataTableId, false, opCtx); WT_CURSOR* cursor = curwrap.get(); invariant(cursor); std::string strUri = uri.toString(); cursor->set_key(cursor, strUri.c_str()); int ret = cursor->search(cursor); if (ret == WT_NOTFOUND) { return StatusWith<std::string>(ErrorCodes::NoSuchKey, str::stream() << "Unable to find metadata for " << uri); } else if (ret != 0) { return StatusWith<std::string>(wtRCToStatus(ret)); } const char* metadata = NULL; ret = cursor->get_value(cursor, &metadata); if (ret != 0) { return StatusWith<std::string>(wtRCToStatus(ret)); } invariant(metadata); return StatusWith<std::string>(metadata); }
// non public api Status RocksEngine::_createIdentPrefix(StringData ident) { uint32_t prefix = 0; { boost::mutex::scoped_lock lk(_identPrefixMapMutex); if (_identPrefixMap.find(ident) != _identPrefixMap.end()) { // already exists return Status::OK(); } prefix = ++_maxPrefix; _identPrefixMap[ident] = prefix; } BSONObjBuilder builder; builder.append("prefix", static_cast<int32_t>(prefix)); BSONObj config = builder.obj(); auto s = _db->Put(rocksdb::WriteOptions(), kMetadataPrefix + ident.toString(), rocksdb::Slice(config.objdata(), config.objsize())); return toMongoStatus(s); }
Status KVCatalog::dropCollection(OperationContext* opCtx, StringData ns) { invariant(opCtx->lockState() == NULL || opCtx->lockState()->isDbLockedForMode(nsToDatabaseSubstring(ns), MODE_X)); std::unique_ptr<Lock::ResourceLock> rLk; if (!_isRsThreadSafe && opCtx->lockState()) { rLk.reset(new Lock::ResourceLock(opCtx->lockState(), resourceIdCatalogMetadata, MODE_X)); } stdx::lock_guard<stdx::mutex> lk(_identsLock); const NSToIdentMap::iterator it = _idents.find(ns.toString()); if (it == _idents.end()) { return Status(ErrorCodes::NamespaceNotFound, "collection not found"); } opCtx->recoveryUnit()->registerChange(new RemoveIdentChange(this, ns, it->second)); LOG(1) << "deleting metadata for " << ns << " @ " << it->second.storedLoc; _rs->deleteRecord(opCtx, it->second.storedLoc); _idents.erase(it); return Status::OK(); }
std::unique_ptr<mongo::RecordStore> KVEngine::getRecordStore(OperationContext* opCtx, StringData ns, StringData ident, const CollectionOptions& options) { std::unique_ptr<mongo::RecordStore> recordStore; if (options.capped) { if (NamespaceString::oplog(ns)) _visibilityManager = std::make_unique<VisibilityManager>(); recordStore = std::make_unique<RecordStore>( ns, ident, options.capped, options.cappedSize ? options.cappedSize : kDefaultCappedSizeBytes, options.cappedMaxDocs ? options.cappedMaxDocs : -1, /*cappedCallback*/ nullptr, _visibilityManager.get()); } else { recordStore = std::make_unique<RecordStore>(ns, ident, options.capped); } _idents[ident.toString()] = true; return recordStore; }
bool RangeDeleterMockEnv::deleteRange(OperationContext* txn, const StringData& ns, const BSONObj& min, const BSONObj& max, const BSONObj& shardKeyPattern, bool secondaryThrottle, string* errMsg) { { scoped_lock sl(_pauseDeleteMutex); bool wasInitiallyPaused = _pauseDelete; if (_pauseDelete) { _pausedCount++; _pausedDeleteChangeCV.notify_one(); } while (_pauseDelete) { _pausedCV.wait(sl.boost()); } _pauseDelete = wasInitiallyPaused; } { scoped_lock sl(_deleteListMutex); DeletedRange entry; entry.ns = ns.toString(); entry.min = min.getOwned(); entry.max = max.getOwned(); entry.shardKeyPattern = shardKeyPattern.getOwned(); _deleteList.push_back(entry); } return true; }
StatusWith<std::string> WiredTigerUtil::getMetadataRaw(WT_SESSION* session, StringData uri) { WT_CURSOR* cursor; invariantWTOK(session->open_cursor(session, "metadata:create", nullptr, "", &cursor)); invariant(cursor); ON_BLOCK_EXIT([cursor] { invariantWTOK(cursor->close(cursor)); }); std::string strUri = uri.toString(); cursor->set_key(cursor, strUri.c_str()); int ret = cursor->search(cursor); if (ret == WT_NOTFOUND) { return StatusWith<std::string>(ErrorCodes::NoSuchKey, str::stream() << "Unable to find metadata for " << uri); } else if (ret != 0) { return StatusWith<std::string>(wtRCToStatus(ret)); } const char* metadata = NULL; ret = cursor->get_value(cursor, &metadata); if (ret != 0) { return StatusWith<std::string>(wtRCToStatus(ret)); } invariant(metadata); return StatusWith<std::string>(metadata); }
BSONObj KVCatalog::_findEntry(OperationContext* opCtx, StringData ns, RecordId* out) const { RecordId dl; { stdx::lock_guard<stdx::mutex> lk(_identsLock); NSToIdentMap::const_iterator it = _idents.find(ns.toString()); invariant(it != _idents.end()); dl = it->second.storedLoc; } LOG(3) << "looking up metadata for: " << ns << " @ " << dl; RecordData data; if (!_rs->findRecord(opCtx, dl, &data)) { // since the in memory meta data isn't managed with mvcc // its possible for different transactions to see slightly // different things, which is ok via the locking above. return BSONObj(); } if (out) *out = dl; return data.releaseToBson().getOwned(); }
Status parseRolePossessionManipulationCommands(const BSONObj& cmdObj, StringData cmdName, const std::string& dbname, std::string* parsedName, vector<RoleName>* parsedRoleNames) { unordered_set<std::string> validFieldNames; validFieldNames.insert(cmdName.toString()); validFieldNames.insert("roles"); Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames); if (!status.isOK()) { return status; } status = bsonExtractStringField(cmdObj, cmdName, parsedName); if (!status.isOK()) { return status; } BSONElement rolesElement; status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement); if (!status.isOK()) { return status; } status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, parsedRoleNames); if (!status.isOK()) { return status; } if (!parsedRoleNames->size()) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << cmdName << " command requires a non-empty " "\"roles\" array"); } return Status::OK(); }
std::unique_ptr<PlanExecutor> InternalPlanner::collectionScan(OperationContext* txn, StringData ns, Collection* collection, PlanExecutor::YieldPolicy yieldPolicy, const Direction direction, const RecordId startLoc) { std::unique_ptr<WorkingSet> ws = stdx::make_unique<WorkingSet>(); if (NULL == collection) { auto eof = stdx::make_unique<EOFStage>(txn); // Takes ownership of 'ws' and 'eof'. auto statusWithPlanExecutor = PlanExecutor::make(txn, std::move(ws), std::move(eof), ns.toString(), yieldPolicy); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); } invariant(ns == collection->ns().ns()); CollectionScanParams params; params.collection = collection; params.start = startLoc; if (FORWARD == direction) { params.direction = CollectionScanParams::FORWARD; } else { params.direction = CollectionScanParams::BACKWARD; } std::unique_ptr<CollectionScan> cs = stdx::make_unique<CollectionScan>(txn, params, ws.get(), nullptr); // Takes ownership of 'ws' and 'cs'. auto statusWithPlanExecutor = PlanExecutor::make(txn, std::move(ws), std::move(cs), collection, yieldPolicy); invariant(statusWithPlanExecutor.isOK()); return std::move(statusWithPlanExecutor.getValue()); }
// TODO: This is inefficient. We could create the tagged tree as part of the PredicateMap // construction. void tag(MatchExpression* node) { StringData path = node->path(); if (!path.empty()) { for (PredicateMap::const_iterator it = _pm.find(path.toString()); _pm.end() != it; ++it) { if (it->second.type == node->matchType()) { EnumeratorTag* td = new EnumeratorTag(&it->second); node->setTag(td); _taggedLeaves.push_back(node); break; } } } // XXX XXX XXX XXX // XXX Do we do this if the node is logical, or if it's array, or both? // XXX XXX XXX XXX for (size_t i = 0; i < node->numChildren(); ++i) { tag(const_cast<MatchExpression*>(node->getChild(i))); } }
void ConfigServerCatalogCacheLoader::getDatabase( StringData dbName, stdx::function<void(OperationContext*, StatusWith<DatabaseType>)> callbackFn) { _threadPool.schedule([ name = dbName.toString(), callbackFn ](auto status) noexcept { invariant(status); auto opCtx = Client::getCurrent()->makeOperationContext(); auto swDbt = [&]() -> StatusWith<DatabaseType> { try { return uassertStatusOK( Grid::get(opCtx.get()) ->catalogClient() ->getDatabase( opCtx.get(), name, repl::ReadConcernLevel::kMajorityReadConcern)) .value; } catch (const DBException& ex) { return ex.toStatus(); } }(); callbackFn(opCtx.get(), std::move(swDbt)); }); }
/** * Set a collection option flag for 'UsePowerOf2Sizes' or 'NoPadding'. Appends both the new and * old flag setting to the given 'result' builder. */ void setCollectionOptionFlag(OperationContext* opCtx, Collection* coll, BSONElement& collOptionElement, BSONObjBuilder* result) { const StringData flagName = collOptionElement.fieldNameStringData(); int flag; if (flagName == "usePowerOf2Sizes") { flag = CollectionOptions::Flag_UsePowerOf2Sizes; } else if (flagName == "noPadding") { flag = CollectionOptions::Flag_NoPadding; } else { flag = 0; } CollectionCatalogEntry* cce = coll->getCatalogEntry(); const int oldFlags = cce->getCollectionOptions(opCtx).flags; const bool oldSetting = oldFlags & flag; const bool newSetting = collOptionElement.trueValue(); result->appendBool(flagName.toString() + "_old", oldSetting); result->appendBool(flagName.toString() + "_new", newSetting); const int newFlags = newSetting ? (oldFlags | flag) // set flag : (oldFlags & ~flag); // clear flag // NOTE we do this unconditionally to ensure that we note that the user has // explicitly set flags, even if they are just setting the default. cce->updateFlags(opCtx, newFlags); const CollectionOptions newOptions = cce->getCollectionOptions(opCtx); invariant(newOptions.flags == newFlags); invariant(newOptions.flagsSet); }
AddCollectionChange(Database* db, StringData ns) : _db(db) , _ns(ns.toString()) {}
Status Database::dropCollection( OperationContext* txn, StringData fullns ) { invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X)); LOG(1) << "dropCollection: " << fullns << endl; massertNamespaceNotIndex( fullns, "dropCollection" ); Collection* collection = getCollection( fullns ); if ( !collection ) { // collection doesn't exist return Status::OK(); } { NamespaceString s( fullns ); verify( s.db() == _name ); if( s.isSystem() ) { if( s.coll() == "system.profile" ) { if ( _profile != 0 ) return Status( ErrorCodes::IllegalOperation, "turn off profiling before dropping system.profile collection" ); } else { return Status( ErrorCodes::IllegalOperation, "can't drop system ns" ); } } } BackgroundOperation::assertNoBgOpInProgForNs( fullns ); audit::logDropCollection( currentClient.get(), fullns ); Status s = collection->getIndexCatalog()->dropAllIndexes(txn, true); if ( !s.isOK() ) { warning() << "could not drop collection, trying to drop indexes" << fullns << " because of " << s.toString(); return s; } verify( collection->_details->getTotalIndexCount( txn ) == 0 ); LOG(1) << "\t dropIndexes done" << endl; Top::global.collectionDropped( fullns ); s = _dbEntry->dropCollection( txn, fullns ); _clearCollectionCache( txn, fullns ); // we want to do this always if ( !s.isOK() ) return s; DEV { // check all index collection entries are gone string nstocheck = fullns.toString() + ".$"; for ( CollectionMap::const_iterator i = _collections.begin(); i != _collections.end(); ++i ) { string temp = i->first; if ( temp.find( nstocheck ) != 0 ) continue; log() << "after drop, bad cache entries for: " << fullns << " have " << temp; verify(0); } } return Status::OK(); }
bool processObj(const BSONObj &obj) { if (obj.hasField("$err")) { log() << "error getting oplog: " << obj << endl; return false; } static const char *names[] = {"ts", "op", "ns", "o", "b"}; BSONElement fields[5]; obj.getFields(5, names, fields); BSONElement &tsElt = fields[0]; if (!tsElt.ok()) { log() << "oplog format error: " << obj << " missing 'ts' field." << endl; return false; } if (tsElt.type() != Date && tsElt.type() != Timestamp) { log() << "oplog format error: " << obj << " wrong 'ts' field type." << endl; return false; } _thisTime = OpTime(tsElt.date()); BSONElement &opElt = fields[1]; if (!opElt.ok()) { log() << "oplog format error: " << obj << " missing 'op' field." << endl; return false; } StringData op = opElt.Stringdata(); // nop if (op == "n") { return true; } // "presence of a database" if (op == "db") { return true; } if (op != "c" && op != "i" && op != "u" && op != "d") { log() << "oplog format error: " << obj << " has an invalid 'op' field of '" << op << "'." << endl; return false; } if (op != "i" && !_insertBuf.empty()) { flushInserts(); } BSONElement &nsElt = fields[2]; if (!nsElt.ok()) { log() << "oplog format error: " << obj << " missing 'ns' field." << endl; return false; } StringData ns = nsElt.Stringdata(); size_t i = ns.find('.'); if (i == string::npos) { log() << "oplog format error: invalid namespace '" << ns << "' in op " << obj << "." << endl; return false; } StringData dbname = ns.substr(0, i); StringData collname = ns.substr(i + 1); BSONElement &oElt = fields[3]; if (!oElt.ok()) { log() << "oplog format error: " << obj << " missing 'o' field." << endl; return false; } BSONObj o = obj["o"].Obj(); if (op == "c") { if (collname != "$cmd") { log() << "oplog format error: invalid namespace '" << ns << "' for command in op " << obj << "." << endl; return false; } BSONObj info; bool ok = _conn.runCommand(dbname.toString(), o, info); if (!ok) { StringData fieldName = o.firstElementFieldName(); BSONElement errmsgElt = info["errmsg"]; StringData errmsg = errmsgElt.type() == String ? errmsgElt.Stringdata() : ""; bool isDropIndexes = (fieldName == "dropIndexes" || fieldName == "deleteIndexes"); if (((fieldName == "drop" || isDropIndexes) && errmsg == "ns not found") || (isDropIndexes && (errmsg == "index not found" || errmsg.find("can't find index with key:") == 0))) { // This is actually ok. We don't mind dropping something that's not there. LOG(1) << "Tried to replay " << o << ", got " << info << ", ignoring." << endl; } else { log() << "replay of command " << o << " failed: " << info << endl; return false; } } } else { string nsstr = ns.toString(); if (op == "i") { if (collname == "system.indexes") { // Can't ensure multiple indexes in the same batch. flushInserts(); // For now, we need to strip out any background fields from // ensureIndex. Once we do hot indexing we can do something more // like what vanilla applyOperation_inlock does. if (o["background"].trueValue()) { BSONObjBuilder builder; BSONObjIterator it(o); while (it.more()) { BSONElement e = it.next(); if (strncmp(e.fieldName(), "background", sizeof("background")) != 0) { builder.append(e); } } o = builder.obj(); } // We need to warn very carefully about dropDups. if (o["dropDups"].trueValue()) { BSONObjBuilder builder; BSONObjIterator it(o); while (it.more()) { BSONElement e = it.next(); if (strncmp(e.fieldName(), "dropDups", sizeof("dropDups")) != 0) { builder.append(e); } } warning() << "Detected an ensureIndex with dropDups: true in " << o << "." << endl; warning() << "This option is not supported in TokuMX, because it deletes arbitrary data." << endl; warning() << "If it were replayed, it could result in a completely different data set than the source database." << endl; warning() << "We will attempt to replay it without dropDups, but if that fails, you must restart your migration process." << endl; _conn.insert(nsstr, o); string err = _conn.getLastError(dbname.toString(), false, false); if (!err.empty()) { log() << "replay of operation " << obj << " failed: " << err << endl; warning() << "You cannot continue processing this replication stream. You need to restart the migration process." << endl; _running = false; _logAtExit = false; return true; } } } pushInsert(nsstr, o); // Don't call GLE or update _maxOpTimeSynced yet. _thisTime = OpTime(); return true; } else if (op == "u") { BSONElement o2Elt = obj["o2"]; if (!o2Elt.ok()) { log() << "oplog format error: " << obj << " missing 'o2' field." << endl; return false; } BSONElement &bElt = fields[4]; bool upsert = bElt.booleanSafe(); BSONObj o2 = o2Elt.Obj(); _conn.update(nsstr, o2, o, upsert, false); } else if (op == "d") { BSONElement &bElt = fields[4]; bool justOne = bElt.booleanSafe(); _conn.remove(nsstr, o, justOne); } string err = _conn.getLastError(dbname.toString(), false, false); if (!err.empty()) { log() << "replay of operation " << obj << " failed: " << err << endl; return false; } } // If we got here, we completed the operation successfully. _maxOpTimeSynced = _thisTime; _thisTime = OpTime(); return true; }
void CurOp::setNS_inlock(StringData ns) { _ns = ns.toString(); }
void CurOp::setNS( const StringData& ns ) { // _ns copies the data in the null-terminated ptr it's given _ns = ns.toString().c_str(); }
Status ModifierAddToSet::prepare(mb::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 < static_cast<int32_t>(_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) return Status( ErrorCodes::BadValue, "Cannot apply $addToSet to a non-array value"); // 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, and therefore in place. if (_preparedState->elementsToAdd.empty()) { _preparedState->noOp = execInfo->noOp = true; execInfo->inPlace = true; } return Status::OK(); }
Status _parseAndValidateInput(BSONObj cmdObj, CreateUserArgs* parsedArgs) const { unordered_set<std::string> validFieldNames; validFieldNames.insert("createUser"); validFieldNames.insert("user"); validFieldNames.insert("pwd"); validFieldNames.insert("userSource"); validFieldNames.insert("roles"); validFieldNames.insert("readOnly"); validFieldNames.insert("otherDBRoles"); // Iterate through all fields in command object and make sure there are no unexpected // ones. for (BSONObjIterator iter(cmdObj); iter.more(); iter.next()) { StringData fieldName = (*iter).fieldNameStringData(); if (!validFieldNames.count(fieldName.toString())) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "\"" << fieldName << "\" is not " "a valid argument to createUser"); } } Status status = bsonExtractStringField(cmdObj, "user", &parsedArgs->userName); if (!status.isOK()) { return status; } if (cmdObj.hasField("pwd")) { parsedArgs->hasPassword = true; status = bsonExtractStringField(cmdObj, "pwd", &parsedArgs->clearTextPassword); if (!status.isOK()) { return status; } } if (cmdObj.hasField("userSource")) { parsedArgs->hasUserSource = true; status = bsonExtractStringField(cmdObj, "userSource", &parsedArgs->userSource); if (!status.isOK()) { return status; } } if (cmdObj.hasField("readOnly")) { parsedArgs->hasReadOnly = true; status = bsonExtractBooleanField(cmdObj, "readOnly", &parsedArgs->readOnly); if (!status.isOK()) { return status; } } if (cmdObj.hasField("extraData")) { parsedArgs->hasExtraData = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "extraData", Object, &element); if (!status.isOK()) { return status; } parsedArgs->extraData = element.Obj(); } if (cmdObj.hasField("roles")) { parsedArgs->hasRoles = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "roles", Array, &element); if (!status.isOK()) { return status; } parsedArgs->roles = BSONArray(element.Obj()); } if (cmdObj.hasField("otherDBRoles")) { parsedArgs->hasOtherDBRoles = true; BSONElement element; status = bsonExtractTypedField(cmdObj, "otherDBRoles", Object, &element); if (!status.isOK()) { return status; } parsedArgs->otherDBRoles = element.Obj(); } if (parsedArgs->hasPassword && parsedArgs->hasUserSource) { return Status(ErrorCodes::BadValue, "User objects can't have both 'pwd' and 'userSource'"); } if (!parsedArgs->hasPassword && !parsedArgs->hasUserSource) { return Status(ErrorCodes::BadValue, "User objects must have one of 'pwd' and 'userSource'"); } if (parsedArgs->hasRoles && parsedArgs->hasReadOnly) { return Status(ErrorCodes::BadValue, "User objects can't have both 'roles' and 'readOnly'"); } return Status::OK(); }