void insertObjects(const char *ns, const vector<BSONObj> &objs, bool keepGoing, uint64_t flags, bool logop ) { StringData _ns(ns); if (NamespaceString::isSystem(_ns)) { massert(16748, "need transaction to run insertObjects", cc().txnStackSize() > 0); uassert(10095, "attempt to insert in reserved database name 'system'", nsToDatabaseSubstring(_ns) != "system"); massert(16750, "attempted to insert multiple objects into a system namspace at once", objs.size() == 1); // Trying to insert into a system collection. Fancy side-effects go here: if (nsToCollectionSubstring(ns) == "system.indexes") { BSONObj obj = stripDropDups(objs[0]); NamespaceDetails *d = getAndMaybeCreateNS(obj["ns"].Stringdata(), logop); bool ok = d->ensureIndex(obj); if (!ok) { // Already had that index return; } // Now we have to actually insert that document into system.indexes, we may have // modified it with stripDropDups. vector<BSONObj> newObjs; newObjs.push_back(obj); _insertObjects(ns, newObjs, keepGoing, flags, logop); return; } else if (!legalClientSystemNS(ns, true)) { uasserted(16459, str::stream() << "attempt to insert in system namespace '" << ns << "'"); } } _insertObjects(ns, objs, keepGoing, flags, logop); }
static void _buildHotIndex(const char *ns, Message &m, const vector<BSONObj> objs) { uassert(16905, "Can only build one index at a time.", objs.size() == 1); DEV { // System.indexes cannot be sharded. Client::ShardedOperationScope sc; verify(!sc.handlePossibleShardedMessage(m, 0)); } LOCK_REASON(lockReason, "building hot index"); scoped_ptr<Lock::DBWrite> lk(new Lock::DBWrite(ns, lockReason)); uassert(16902, "not master", isMasterNs(ns)); const BSONObj &info = objs[0]; const StringData &coll = info["ns"].Stringdata(); scoped_ptr<Client::Transaction> transaction(new Client::Transaction(DB_SERIALIZABLE)); shared_ptr<Collection::Indexer> indexer; // Prepare the index build. Performs index validation and marks // the collection as having an index build in progress. { Client::Context ctx(ns); Collection *cl = getOrCreateCollection(coll, true); if (cl->findIndexByKeyPattern(info["key"].Obj()) >= 0) { // No error or action if the index already exists. We need to commit // the transaction in case this is an ensure index on the _id field // and the ns was created by getOrCreateCollection() transaction->commit(); return; } _insertObjects(ns, objs, false, 0, true); indexer = cl->newIndexer(info, true); indexer->prepare(); } // Perform the index build { Lock::DBWrite::Downgrade dg(lk); uassert(16906, "not master: after indexer setup but before build", isMasterNs(ns)); Client::Context ctx(ns); indexer->build(); } uassert(16907, "not master: after indexer build but before commit", isMasterNs(ns)); // Commit the index build { Client::Context ctx(ns); indexer->commit(); } transaction->commit(); }