コード例 #1
0
 TEST( NamespaceStringTest, nsToDatabase1 ) {
     ASSERT_EQUALS( "foo", nsToDatabaseSubstring( "foo.bar" ) );
     ASSERT_EQUALS( "foo", nsToDatabaseSubstring( "foo" ) );
     ASSERT_EQUALS( "foo", nsToDatabase( "foo.bar" ) );
     ASSERT_EQUALS( "foo", nsToDatabase( "foo" ) );
     ASSERT_EQUALS( "foo", nsToDatabase( string("foo.bar") ) );
     ASSERT_EQUALS( "foo", nsToDatabase( string("foo") ) );
 }
コード例 #2
0
ファイル: dbclientcursor.cpp プロジェクト: mihail812/mongo
void DBClientCursor::_assembleInit(Message& toSend) {
    // If we haven't gotten a cursorId yet, we need to issue a new query or command.
    if (!cursorId) {
        // HACK:
        // Unfortunately, this code is used by the shell to run commands,
        // so we need to allow the shell to send invalid options so that we can
        // test that the server rejects them. Thus, to allow generating commands with
        // invalid options, we validate them here, and fall back to generating an OP_QUERY
        // through assembleQueryRequest if the options are invalid.

        bool hasValidNToReturnForCommand = (nToReturn == 1 || nToReturn == -1);
        bool hasValidFlagsForCommand = !(opts & mongo::QueryOption_Exhaust);

        if (_isCommand && hasValidNToReturnForCommand && hasValidFlagsForCommand) {
            toSend = assembleCommandRequest(_client, nsToDatabaseSubstring(ns), opts, query);
            return;
        }
        assembleQueryRequest(ns, query, nextBatchSize(), nToSkip, fieldsToReturn, opts, toSend);
        return;
    }
    // Assemble a legacy getMore request.
    BufBuilder b;
    b.appendNum(opts);
    b.appendStr(ns);
    b.appendNum(nToReturn);
    b.appendNum(cursorId);
    toSend.setData(dbGetMore, b.buf(), b.len());
}
コード例 #3
0
ファイル: d_concurrency.cpp プロジェクト: Robbie1977/mongo
    void Lock::DBWrite::lockDB(const string& ns) {
        fassert( 16253, !ns.empty() );

        Acquiring a(this, *_lockState);
        _locked_W=false;
        _locked_w=false; 
        _weLocked=0;

        massert(16186, "can't get a DBWrite while having a read lock", !_lockState->hasAnyReadLock());
        if (_lockState->isW())
            return;

        StringData db = nsToDatabaseSubstring( ns );
        Nestable nested = n(db);
        if( nested == admin ) { 
            // we can't nestedly lock both admin and local as implemented. so lock_W.
            qlk.lock_W(_lockState);
            _locked_W = true;
            return;
        } 
        if( !nested )
            lockOther(db);
        lockTop();
        if( nested )
            lockNestable(nested);
    }
コード例 #4
0
ファイル: d_concurrency.cpp プロジェクト: igagnidz/tokumx
    void Lock::DBWrite::lockDB(const string& ns, const string &context) {
        fassert( 16253, !ns.empty() );
        LockState& ls = lockState();
        
        Acquiring a(this,ls);
        _locked_W=false;
        _locked_w=false; 
        _weLocked=0;


        massert( 16186 , "can't get a DBWrite while having a read lock" , ! ls.hasAnyReadLock() );
        if( ls.isW() )
            return;

        if (DB_LEVEL_LOCKING_ENABLED) {
            StringData db = nsToDatabaseSubstring( ns );
            Nestable nested = n(db);
            if( nested == admin ) { 
                // we can't nestedly lock both admin and local as implemented. so lock_W.
                qlk.lock_W();
                _locked_W = true;
                return;
            } 
            if( !nested )
                lockOther(db, context);
            lockTop(ls);
            if( nested )
                lockNestable(nested, context);
        } 
        else {
            qlk.lock_W();
            _locked_w = true;
        }
    }
コード例 #5
0
ファイル: database.cpp プロジェクト: nathanielc/mongo
    CollectionTemp* Database::getCollectionTemp( const StringData& ns ) {
        StringData dbName = nsToDatabaseSubstring( ns );
        verify( dbName == _name);

        scoped_lock lk( _collectionLock );

        string myns = ns.toString();

        CollectionMap::const_iterator it = _collections.find( myns );
        if ( it != _collections.end() ) {
            if ( it->second ) {
                //DEV {
                    NamespaceDetails* details = _namespaceIndex.details( ns );
                    verify( details == it->second->_details );
                    //}
                return it->second;
            }
        }

        NamespaceDetails* details = _namespaceIndex.details( ns );
        if ( !details ) {
            return NULL;
        }

        CollectionTemp* c = new CollectionTemp( ns, details, this );
        _collections[myns] = c;
        return c;
    }
コード例 #6
0
ファイル: dbtests.cpp プロジェクト: 3rf/mongo
 Status createIndexFromSpec(OperationContext* txn, const StringData& ns, const BSONObj& spec) {
     AutoGetOrCreateDb autoDb(txn, nsToDatabaseSubstring(ns), MODE_X);
     Collection* coll;
     {
         WriteUnitOfWork wunit(txn);
         coll = autoDb.getDb()->getOrCreateCollection(txn, ns);
         invariant(coll);
         wunit.commit();
     }
     MultiIndexBlock indexer(txn, coll);
     Status status = indexer.init(spec);
     if (status == ErrorCodes::IndexAlreadyExists) {
         return Status::OK();
     }
     if (!status.isOK()) {
         return status;
     }
     status = indexer.insertAllDocumentsInCollection();
     if (!status.isOK()) {
         return status;
     }
     WriteUnitOfWork wunit(txn);
     indexer.commit();
     wunit.commit();
     return Status::OK();
 }
コード例 #7
0
ファイル: insert.cpp プロジェクト: aberg001/mongo
    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);
    }
コード例 #8
0
void NamespaceUUIDCache::evictNamespacesInDatabase(StringData dbname) {
    for (auto&& it = _cache.begin(); it != _cache.end();) {
        auto entry = it++;
        if (entry->first.empty() || nsToDatabaseSubstring(entry->first) == dbname)
            _cache.erase(entry);
    }
}
コード例 #9
0
ファイル: lock_state.cpp プロジェクト: BotterLiu/mongo
    bool LockerImpl::isAtLeastReadLocked(const StringData& ns) const {
        if (threadState() == 'R' || threadState() == 'W') {
            return true; // global
        }
        if (!isLocked()) {
            return false;
        }

        const StringData db = nsToDatabaseSubstring(ns);
        const newlm::ResourceId resIdDb(newlm::RESOURCE_DATABASE, db);

        // S on the database means we don't need to check further down the hierarchy
        if (isLockHeldForMode(resIdDb, newlm::MODE_S)) {
            return true;
        }

        if (!isLockHeldForMode(resIdDb, newlm::MODE_IS)) {
            return false;
        }

        if (nsIsFull(ns)) {
            const newlm::ResourceId resIdColl(newlm::RESOURCE_DATABASE, ns);
            return isLockHeldForMode(resIdColl, newlm::MODE_IS);
        }

        // We're just asking about a database, so IS on the db is enough.
        return true;
    }
コード例 #10
0
AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* txn, const std::string& ns)
    : _txn(txn),
      _transaction(txn, MODE_IS),
      _db(_txn, nsToDatabaseSubstring(ns), MODE_IS),
      _collLock(_txn->lockState(), ns, MODE_IS),
      _coll(NULL) {
    _init(ns, nsToCollectionSubstring(ns));
}
コード例 #11
0
ファイル: query_stage_count.cpp プロジェクト: 3rf/mongo
        CountStageTest()
            : _txn(),
              _scopedXact(&_txn, MODE_IX),
              _dbLock(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X),
              _ctx(&_txn, ns()),
              _coll(NULL) {

        }
コード例 #12
0
ファイル: commands.cpp プロジェクト: dsavineau/mongo
 string Command::parseNsFullyQualified(const string& dbname, const BSONObj& cmdObj) const { 
     string s = cmdObj.firstElement().valuestr();
     StringData dbstr = nsToDatabaseSubstring(s);
     // these are for security, do not remove:
     massert(15962, "need to specify namespace" , !dbstr.empty() );
     massert(15966, str::stream() << "dbname not ok in Command::parseNsFullyQualified: " << dbname , dbname == dbstr || dbname == "admin" );
     return s;
 }
コード例 #13
0
ファイル: collection_map.cpp プロジェクト: 7segments/mongo
    void CollectionMap::drop() {
        Lock::assertWriteLocked(_database);
        init();
        if (!allocated()) {
            return;
        }

        string errmsg;
        BSONObjBuilder result;

        // This implementation is inefficient and slightly messy, but it was easy.
        // Feel free to improve it as necessary:
        // - The getCursor call will grab a table lock on .system.namespaces.
        // - We'll look at the entire system.namespaces collection just for one database.
        // - Code is duplicated to handle dropping system system collections in stages.
        vector<string> sysIndexesEntries;
        const string systemNamespacesNs = getSisterNS(_database, "system.namespaces");
        Collection *sysCl = getCollection(systemNamespacesNs);
        for (shared_ptr<Cursor> c(Cursor::make(sysCl)); c->ok(); c->advance()) {
            const BSONObj nsObj = c->current();
            const StringData ns = nsObj["name"].Stringdata();
            if (nsToDatabaseSubstring(ns) != _database) {
                // Not part of this database, skip.
                continue;
            }
            if (nsToCollectionSubstring(ns) == "system.indexes") {
                // Save .system.indexes collection for last, because drop() deletes from it.
                sysIndexesEntries.push_back(ns.toString());
            } else {
                Collection *cl = getCollection(ns);
                if (cl != NULL) {
                    cl->drop(errmsg, result, true);
                }
            }
        }
        if (sysCl != NULL) {
            // The .system.namespaces collection does not include itself.
            sysCl->drop(errmsg, result, true);
        }
        // Now drop the system.indexes entries.
        for (vector<string>::const_iterator it = sysIndexesEntries.begin(); it != sysIndexesEntries.end(); it++) {
            // Need to close any existing handle before drop.
            Collection *cl = getCollection(*it);
            if (cl != NULL) {
                cl->drop(errmsg, result, true);
            }
        }
        // Everything that was open should have been closed due to drop.
        verify(_collections.empty());

        shared_ptr<storage::Dictionary> metadb = _metadb;
        _metadb.reset();
        const int r = metadb->close();
        if (r != 0) {
            storage::handle_ydb_error(r);
        }
        storage::db_remove(_metadname);
    }
コード例 #14
0
ファイル: query_stage_fetch.cpp プロジェクト: CodeHub2/mongo
        void run() {
            ScopedTransaction transaction(&_txn, MODE_IX);
            Lock::DBLock lk(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X);
            Client::Context ctx(&_txn, ns());
            Database* db = ctx.db();
            Collection* coll = db->getCollection(&_txn, ns());
            if (!coll) {
                WriteUnitOfWork wuow(&_txn);
                coll = db->createCollection(&_txn, ns());
                wuow.commit();
            }

            WorkingSet ws;

            // Add an object to the DB.
            insert(BSON("foo" << 5));
            set<DiskLoc> locs;
            getLocs(&locs, coll);
            ASSERT_EQUALS(size_t(1), locs.size());

            // Create a mock stage that returns the WSM.
            auto_ptr<MockStage> mockStage(new MockStage(&ws));

            // Mock data.
            {
                WorkingSetMember mockMember;
                mockMember.state = WorkingSetMember::LOC_AND_IDX;
                mockMember.loc = *locs.begin();

                // State is loc and index, shouldn't be able to get the foo data inside.
                BSONElement elt;
                ASSERT_FALSE(mockMember.getFieldDotted("foo", &elt));
                mockStage->pushBack(mockMember);
            }

            // Make the filter.
            BSONObj filterObj = BSON("foo" << 6);
            StatusWithMatchExpression swme = MatchExpressionParser::parse(filterObj);
            verify(swme.isOK());
            auto_ptr<MatchExpression> filterExpr(swme.getValue());

            // Matcher requires that foo==6 but we only have data with foo==5.
            auto_ptr<FetchStage> fetchStage(
                     new FetchStage(&_txn, &ws, mockStage.release(), filterExpr.get(), coll));

            // First call should return a fetch request as it's not in memory.
            WorkingSetID id = WorkingSet::INVALID_ID;
            PlanStage::StageState state;

            // Normally we'd return the object but we have a filter that prevents it.
            state = fetchStage->work(&id);
            ASSERT_EQUALS(PlanStage::NEED_TIME, state);

            // No more data to fetch, so, EOF.
            state = fetchStage->work(&id);
            ASSERT_EQUALS(PlanStage::IS_EOF, state);
        }
コード例 #15
0
ファイル: database.cpp プロジェクト: maxkeller/mongo
    Collection* Database::getCollection( StringData ns ) const {
        invariant( _name == nsToDatabaseSubstring( ns ) );
        CollectionMap::const_iterator it = _collections.find( ns );
        if ( it != _collections.end() && it->second ) {
            return it->second;
        }

        return NULL;
    }
コード例 #16
0
ファイル: database.cpp プロジェクト: kevleyski/mongo
void Database::_clearCollectionCache_inlock( const StringData& fullns ) {
    verify( _name == nsToDatabaseSubstring( fullns ) );
    CollectionMap::iterator it = _collections.find( fullns.toString() );
    if ( it == _collections.end() )
        return;

    delete it->second;
    _collections.erase( it );
}
コード例 #17
0
ファイル: extent_manager.cpp プロジェクト: Axv2/mongo
 bool fileIndexExceedsQuota( const char *ns, int fileIndex ) {
     return
         cmdLine.quota &&
         fileIndex >= cmdLine.quotaFiles &&
         // we don't enforce the quota on "special" namespaces as that could lead to problems -- e.g.
         // rejecting an index insert after inserting the main record.
         !NamespaceString::special( ns ) &&
         nsToDatabaseSubstring( ns ) != "local";
 }
コード例 #18
0
ファイル: indexcatalogtests.cpp プロジェクト: Karl-Wu/mongo
        ~IndexIteratorTests() {
            OperationContextImpl txn;
            Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(_ns), MODE_X);
            Client::Context ctx(&txn, _ns);
            WriteUnitOfWork wuow(&txn);

            _db->dropCollection(&txn, _ns);
            wuow.commit();
        }
コード例 #19
0
ファイル: lock_state.cpp プロジェクト: chianhla/mongo
    bool LockerImpl<IsForMMAPV1>::isWriteLocked(const StringData& ns) const {
        if (isWriteLocked()) {
            return true;
        }

        const StringData db = nsToDatabaseSubstring(ns);
        const ResourceId resIdNs(RESOURCE_DATABASE, db);

        return isLockHeldForMode(resIdNs, MODE_X);
    }
コード例 #20
0
    bool LockerImpl::isAtLeastReadLocked(const StringData& ns) const {
        if (threadState() == 'R' || threadState() == 'W')
            return true; // global
        if (!isLocked())
            return false;

        const StringData db = nsToDatabaseSubstring(ns);
        const newlm::ResourceId resIdNs(newlm::RESOURCE_DATABASE, db);

        return isLockHeldForMode(resIdNs, newlm::MODE_S);
    }
コード例 #21
0
ファイル: indexcatalogtests.cpp プロジェクト: Karl-Wu/mongo
        IndexIteratorTests() {
            OperationContextImpl txn;
            Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(_ns), MODE_X);
            Client::Context ctx(&txn, _ns);
            WriteUnitOfWork wuow(&txn);

            _db = ctx.db();
            _coll = _db->createCollection(&txn, _ns);
            _catalog = _coll->getIndexCatalog();
            wuow.commit();
        }
コード例 #22
0
ファイル: database.cpp プロジェクト: maxkeller/mongo
    void Database::_clearCollectionCache(OperationContext* txn, StringData fullns ) {
        verify( _name == nsToDatabaseSubstring( fullns ) );
        CollectionMap::const_iterator it = _collections.find( fullns.toString() );
        if ( it == _collections.end() )
            return;

        // Takes ownership of the collection
        txn->recoveryUnit()->registerChange(new RemoveCollectionChange(this, it->second));

        it->second->_cursorManager.invalidateAll(false);
        _collections.erase( it );
    }
コード例 #23
0
ファイル: d_concurrency.cpp プロジェクト: CeperaCPP/mongo
Lock::CollectionLock::CollectionLock(Locker* lockState, StringData ns, LockMode mode)
    : _id(RESOURCE_COLLECTION, ns), _lockState(lockState) {
    massert(28538, "need a non-empty collection name", nsIsFull(ns));

    dassert(_lockState->isDbLockedForMode(nsToDatabaseSubstring(ns),
                                          isSharedLockMode(mode) ? MODE_IS : MODE_IX));
    if (supportsDocLocking()) {
        _lockState->lock(_id, mode);
    } else {
        _lockState->lock(_id, isSharedLockMode(mode) ? MODE_S : MODE_X);
    }
}
コード例 #24
0
ファイル: legacy_request.cpp プロジェクト: Andiry/mongo
LegacyRequest::LegacyRequest(const Message* message)
    : _message(std::move(message)), _dbMessage(*message), _queryMessage(_dbMessage) {
    _database = nsToDatabaseSubstring(_queryMessage.ns);

    uassert(ErrorCodes::InvalidNamespace,
            str::stream() << "Invalid database name: '" << _database << "'",
            NamespaceString::validDBName(_database));

    std::tie(_upconvertedCommandArgs, _upconvertedMetadata) =
        uassertStatusOK(rpc::upconvertRequestMetadata(std::move(_queryMessage.query),
                                                      std::move(_queryMessage.queryOptions)));
}
コード例 #25
0
ファイル: d_concurrency.cpp プロジェクト: 3rf/mongo
 Lock::CollectionLock::CollectionLock(Locker* lockState,
                                      const StringData& ns,
                                      LockMode mode)
     : _id(RESOURCE_COLLECTION, ns),
       _lockState(lockState) {
     const bool isRead = (mode == MODE_S || mode == MODE_IS);
     massert(28538, "need a non-empty collection name", nsIsFull(ns));
     dassert(_lockState->isDbLockedForMode(nsToDatabaseSubstring(ns),
                                           isRead ? MODE_IS : MODE_IX));
     if (supportsDocLocking()) {
         _lockState->lock(_id, mode);
     } else if (enableCollectionLocking) {
         _lockState->lock(_id, isRead ? MODE_S : MODE_X);
     }
 }
コード例 #26
0
ファイル: d_concurrency.cpp プロジェクト: asya999/mongo
Lock::CollectionLock::CollectionLock(Locker* lockState,
                                     StringData ns,
                                     LockMode mode,
                                     Date_t deadline)
    : _id(RESOURCE_COLLECTION, ns), _result(LOCK_INVALID), _lockState(lockState) {
    massert(28538, "need a non-empty collection name", nsIsFull(ns));

    dassert(_lockState->isDbLockedForMode(nsToDatabaseSubstring(ns),
                                          isSharedLockMode(mode) ? MODE_IS : MODE_IX));
    LockMode actualLockMode = mode;
    if (!supportsDocLocking()) {
        actualLockMode = isSharedLockMode(mode) ? MODE_S : MODE_X;
    }

    _result = _lockState->lock(_id, actualLockMode, deadline);
    invariant(_result == LOCK_OK || deadline != Date_t::max());
}
コード例 #27
0
void OldClientContext::_finishInit() {
    _db = dbHolder().get(_txn, _ns);
    if (_db) {
        _justCreated = false;
    } else {
        invariant(_txn->lockState()->isDbLockedForMode(nsToDatabaseSubstring(_ns), MODE_X));
        _db = dbHolder().openDb(_txn, _ns, &_justCreated);
        invariant(_db);
    }

    if (_doVersion) {
        _checkNotStale();
    }

    stdx::lock_guard<Client> lk(*_txn->getClient());
    CurOp::get(_txn)->enter_inlock(_ns.c_str(), _db->getProfilingLevel());
}
コード例 #28
0
ファイル: d_concurrency.cpp プロジェクト: linsenhu/mongo
    void Lock::DBRead::unlockDB() {

        if (supportsDocLocking()) {
            if (nsIsFull(_ns)) {
                const newlm::ResourceId resIdCollection(newlm::RESOURCE_COLLECTION, _ns);
                _lockState->unlock(resIdCollection);
            }
        }

        const StringData db = nsToDatabaseSubstring(_ns);
        const newlm::ResourceId resIdDb(newlm::RESOURCE_DATABASE, db);
        _lockState->unlock(resIdDb);

        // The last release reports time the lock was held
        if (_lockState->unlockGlobal()) {
            recordTime();
        }
    }
コード例 #29
0
ファイル: d_concurrency.cpp プロジェクト: Robbie1977/mongo
    void Lock::DBRead::lockDB(const string& ns) {
        fassert( 16254, !ns.empty() );

        Acquiring a(this, *_lockState);
        _locked_r=false; 
        _weLocked=0; 

        if (_lockState->isRW())
            return;

        StringData db = nsToDatabaseSubstring(ns);
        Nestable nested = n(db);
        if( !nested )
            lockOther(db);
        lockTop();
        if( nested )
            lockNestable(nested);
    }
コード例 #30
0
ファイル: d_concurrency.cpp プロジェクト: ANTco/mongo
 Lock::CollectionLock::CollectionLock(Locker* lockState,
                                      const StringData& ns,
                                      newlm::LockMode mode)
     : _id(newlm::RESOURCE_COLLECTION, ns),
       _lockState(lockState) {
     const bool isRead = (mode == newlm::MODE_S || mode == newlm::MODE_IS);
     dassert(!ns.empty());
     dassert(nsIsFull(ns));
     dassert(_lockState->isLockHeldForMode(newlm::ResourceId(newlm::RESOURCE_DATABASE,
                                                             nsToDatabaseSubstring(ns)),
                                           isRead ? newlm::MODE_IS : newlm::MODE_IX));
     if (supportsDocLocking()) {
         _lockState->lock(_id, mode);
     }
     else {
         _lockState->lock(_id, isRead ? newlm::MODE_S : newlm::MODE_X);
     }
 }