Exemple #1
0
    void NamespaceIndex::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");
        NamespaceDetails *sysNsd = nsdetails(systemNamespacesNs);
        for (shared_ptr<Cursor> c(BasicCursor::make(sysNsd)); 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 dropCollection deletes from it.
                sysIndexesEntries.push_back(ns.toString());
            } else {
                dropCollection(ns, errmsg, result, true);
            }
        }
        if (sysNsd != NULL) {
            // The .system.namespaces collection does not include itself.
            dropCollection(systemNamespacesNs, 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.
            const string &ns = *it;
            dropCollection(ns, errmsg, result, true);
        }
        // Everything that was open should have been closed due to drop.
        verify(_namespaces.empty());

        shared_ptr<storage::Dictionary> nsdb = _nsdb;
        _nsdb.reset();
        const int r = nsdb->close();
        if (r != 0) {
            storage::handle_ydb_error(r);
        }
        storage::db_remove(_nsdbFilename);
    }
Exemple #2
0
 void deleteOplogFiles() {
     rsOplogDetails = NULL;
     rsOplogRefsDetails = NULL;
     replInfoDetails = NULL;
     
     Client::Context ctx(rsoplog, dbpath);
     // TODO: code review this for possible error cases
     // although, I don't think we care about error cases,
     // just that after we exit, oplog files don't exist
     BSONObjBuilder out;
     string errmsg;
     dropCollection(rsoplog, errmsg, out);
     dropCollection(rsOplogRefs, errmsg, out);
     dropCollection(rsReplInfo, errmsg, out);
 }
Exemple #3
0
    void Database::clearTmpCollections(OperationContext* txn) {

        txn->lockState()->assertWriteLocked( _name );

        list<string> collections;
        _dbEntry->getCollectionNamespaces( &collections );

        for ( list<string>::iterator i = collections.begin(); i != collections.end(); ++i ) {
            string ns = *i;
            invariant( NamespaceString::normal( ns ) );

            CollectionCatalogEntry* coll = _dbEntry->getCollectionCatalogEntry( txn, ns );

            CollectionOptions options = coll->getCollectionOptions( txn );
            if ( !options.temp )
                continue;

            WriteUnitOfWork wunit(txn);
            Status status = dropCollection( txn, ns );
            if ( !status.isOK() ) {
                warning() << "could not drop temp collection '" << ns << "': " << status;
                continue;
            }

            string cmdNs = _name + ".$cmd";
            repl::logOp( txn,
                         "c",
                         cmdNs.c_str(),
                         BSON( "drop" << nsToCollectionSubstring( ns ) ) );
            wunit.commit();
        }
    }
Exemple #4
0
void Database::clearTmpCollections(OperationContext* txn) {
    invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X));

    list<string> collections;
    _dbEntry->getCollectionNamespaces(&collections);

    for (list<string>::iterator i = collections.begin(); i != collections.end(); ++i) {
        string ns = *i;
        invariant(NamespaceString::normal(ns));

        CollectionCatalogEntry* coll = _dbEntry->getCollectionCatalogEntry(ns);

        CollectionOptions options = coll->getCollectionOptions(txn);
        if (!options.temp)
            continue;
        try {
            WriteUnitOfWork wunit(txn);
            Status status = dropCollection(txn, ns);
            if (!status.isOK()) {
                warning() << "could not drop temp collection '" << ns << "': " << redact(status);
                continue;
            }

            wunit.commit();
        } catch (const WriteConflictException& exp) {
            warning() << "could not drop temp collection '" << ns << "' due to "
                                                                     "WriteConflictException";
            txn->recoveryUnit()->abandonSnapshot();
        }
    }
}
Exemple #5
0
    bool ClientCursor::prepareToYield( YieldData &data ) {
        if ( ! _c->supportYields() )
            return false;

        // need to store in case 'this' gets deleted
        data._id = _cursorid;

        data._doingDeletes = _doingDeletes;
        _doingDeletes = false;

        updateLocation();

        {
            /* a quick test that our temprelease is safe.
             todo: make a YieldingCursor class
             and then make the following code part of a unit test.
             */
            const int test = 0;
            static bool inEmpty = false;
            if( test && !inEmpty ) {
                inEmpty = true;
                log() << "TEST: manipulate collection during cc:yield" << endl;
                if( test == 1 )
                    Helpers::emptyCollection(_ns.c_str());
                else if( test == 2 ) {
                    BSONObjBuilder b; string m;
                    dropCollection(_ns.c_str(), m, b);
                }
                else {
                    dropDatabase(_ns.c_str());
                }
            }
        }
        return true;
    }
Exemple #6
0
    bool Client::shutdown(){
        _shutdown = true;
        if ( inShutdown() )
            return false;
        {
            scoped_lock bl(clientsMutex);
            clients.erase(this);
        }

        bool didAnything = false;
        
        if ( _tempCollections.size() ){
            didAnything = true;
            for ( list<string>::iterator i = _tempCollections.begin(); i!=_tempCollections.end(); i++ ){
                string ns = *i;
                Top::global.collectionDropped( ns );
                    
                dblock l;
                Client::Context ctx( ns );
                if ( ! nsdetails( ns.c_str() ) )
                    continue;
                try {
                    string err;
                    BSONObjBuilder b;
                    dropCollection( ns , err , b );
                }
                catch ( ... ){
                    log() << "error dropping temp collection: " << ns << endl;
                }
            }
            _tempCollections.clear();
        }
        
        return didAnything;
    }
Exemple #7
0
 virtual ~Base() {
     if ( !nsd() )
         return;
     string s( ns() );
     string errmsg;
     BSONObjBuilder result;
     dropCollection( s, errmsg, result );
 }
 void drop() {
     Client::Context c(_ns);
     if (nsdetails(_ns.c_str()) != NULL) {
         string errmsg;
         BSONObjBuilder result;
         dropCollection( string(_ns), errmsg, result );
     }
 }
 Status AuthzManagerExternalStateMock::renameCollection(const NamespaceString& oldName,
                                                        const NamespaceString& newName,
                                                        const BSONObj& writeConcern) {
     if (_documents.count(oldName) == 0) {
         return Status(ErrorCodes::NamespaceNotFound,
                       "No collection to rename named " + oldName.ns());
     }
     std::swap(_documents[newName], _documents[oldName]);
     return dropCollection(oldName, writeConcern);
 }
        void drop() {
            Client::WriteContext c(ns());
            string errmsg;
            BSONObjBuilder result;

            if (nsdetails(ns()) == NULL) {
                return;
            }

            dropCollection( string(ns()), errmsg, result );
        }
Exemple #11
0
    bool ClientCursor::yield( int micros ) {
        // need to store on the stack in case this gets deleted
        CursorId id = cursorid;

        bool doingDeletes = _doingDeletes;
        _doingDeletes = false;

        updateLocation();

        {
            /* a quick test that our temprelease is safe. 
               todo: make a YieldingCursor class 
               and then make the following code part of a unit test.
            */
            const int test = 0;
            static bool inEmpty = false;
            if( test && !inEmpty ) { 
                inEmpty = true;
                log() << "TEST: manipulate collection during cc:yield" << endl;
                if( test == 1 ) 
                    Helpers::emptyCollection(ns.c_str());
                else if( test == 2 ) {
                    BSONObjBuilder b; string m;
                    dropCollection(ns.c_str(), m, b);
                }
                else { 
                    dropDatabase(ns.c_str());
                }
            }
        }
            
        {
            dbtempreleasecond unlock;
            if ( unlock.unlocked() ){
                if ( micros == -1 )
                    micros = Client::recommendedYieldMicros();
                if ( micros > 0 )
                    sleepmicros( micros ); 
            }
            else {
                log( LL_WARNING ) << "ClientCursor::yield can't unlock b/c of recursive lock" << endl;
            }
        }
        
        if ( ClientCursor::find( id , false ) == 0 ){
            // i was deleted
            return false;
        }

        _doingDeletes = doingDeletes;
        return true;
    }
TEST_F(KVCatalogTest, Coll1) {
    unique_ptr<KVHarnessHelper> helper(KVHarnessHelper::create());
    KVEngine* engine = helper->getEngine();

    unique_ptr<RecordStore> rs;
    unique_ptr<KVCatalog> catalog;
    {
        MyOperationContext opCtx(engine);
        WriteUnitOfWork uow(&opCtx);
        ASSERT_OK(engine->createRecordStore(&opCtx, "catalog", "catalog", CollectionOptions()));
        rs = engine->getRecordStore(&opCtx, "catalog", "catalog", CollectionOptions());
        catalog.reset(new KVCatalog(rs.get(), false, false, nullptr));
        uow.commit();
    }

    {
        MyOperationContext opCtx(engine);
        WriteUnitOfWork uow(&opCtx);
        ASSERT_OK(newCollection(&opCtx,
                                NamespaceString("a.b"),
                                CollectionOptions(),
                                KVPrefix::kNotPrefixed,
                                catalog.get()));
        ASSERT_NOT_EQUALS("a.b", catalog->getCollectionIdent("a.b"));
        uow.commit();
    }

    string ident = catalog->getCollectionIdent("a.b");
    {
        MyOperationContext opCtx(engine);
        WriteUnitOfWork uow(&opCtx);
        catalog.reset(new KVCatalog(rs.get(), false, false, nullptr));
        catalog->init(&opCtx);
        uow.commit();
    }
    ASSERT_EQUALS(ident, catalog->getCollectionIdent("a.b"));

    {
        MyOperationContext opCtx(engine);
        WriteUnitOfWork uow(&opCtx);
        dropCollection(&opCtx, "a.b", catalog.get()).transitional_ignore();
        newCollection(&opCtx,
                      NamespaceString("a.b"),
                      CollectionOptions(),
                      KVPrefix::kNotPrefixed,
                      catalog.get())
            .transitional_ignore();
        uow.commit();
    }
    ASSERT_NOT_EQUALS(ident, catalog->getCollectionIdent("a.b"));
}
Exemple #13
0
 DbSet::~DbSet() {
     if ( name_.empty() )
         return;
     try {
         Client::Context c( name_.c_str() );
         if ( nsdetails( name_.c_str() ) ) {
             string errmsg;
             BSONObjBuilder result;
             dropCollection( name_, errmsg, result );
         }
     } catch ( ... ) {
         problem() << "exception cleaning up DbSet" << endl;
     }
 }
Collection* RollbackTest::_createCollection(OperationContext* opCtx,
                                            const NamespaceString& nss,
                                            const CollectionOptions& options) {
    Lock::DBLock dbLock(opCtx, nss.db(), MODE_X);
    mongo::WriteUnitOfWork wuow(opCtx);
    auto databaseHolder = DatabaseHolder::get(opCtx);
    auto db = databaseHolder->openDb(opCtx, nss.db());
    ASSERT_TRUE(db);
    db->dropCollection(opCtx, nss.ns()).transitional_ignore();
    auto coll = db->createCollection(opCtx, nss.ns(), options);
    ASSERT_TRUE(coll);
    wuow.commit();
    return coll;
}
    QueryStageCachedPlanBase() {
        // If collection exists already, we need to drop it.
        dropCollection();

        // Add indices.
        addIndex(BSON("a" << 1));
        addIndex(BSON("b" << 1));

        OldClientWriteContext ctx(&_txn, nss.ns());
        Collection* collection = ctx.getCollection();
        ASSERT(collection);

        // Add data.
        for (int i = 0; i < 10; i++) {
            insertDocument(collection, BSON("_id" << i << "a" << i << "b" << 1));
        }
    }
    void setUp() {
        // If collection exists already, we need to drop it.
        dropCollection();

        // Add indices.
        addIndex(BSON("a" << 1));
        addIndex(BSON("b" << 1));

        dbtests::WriteContextForTests ctx(&_opCtx, nss.ns());
        Collection* collection = ctx.getCollection();
        ASSERT(collection);

        // Add data.
        for (int i = 0; i < 10; i++) {
            insertDocument(collection, BSON("_id" << i << "a" << i << "b" << 1));
        }
    }
        void run() {
            Client::WriteContext ctx(&_txn, ns());
            insert(BSON("_id" << 1));
            insert(BSON("_id" << 2));

            BSONObj filterObj = fromjson("{_id: {$gt: 0}}");
            scoped_ptr<SingleSolutionRunner> ssr(makeCollScanRunner(ctx.ctx(),filterObj));
            registerRunner(ssr.get());

            BSONObj objOut;
            ASSERT_EQUALS(Runner::RUNNER_ADVANCED, ssr->getNext(&objOut, NULL));
            ASSERT_EQUALS(1, objOut["_id"].numberInt());

            // After dropping the collection, the runner
            // should be dead.
            dropCollection();
            ASSERT_EQUALS(Runner::RUNNER_DEAD, ssr->getNext(&objOut, NULL));

            deregisterRunner(ssr.get());
        }
Exemple #18
0
    void run() {
        NamespaceString nss("unittests.rollback_create_drop_collection");
        const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
        OperationContext& opCtx = *opCtxPtr;
        dropDatabase(&opCtx, nss);

        Lock::DBLock dbXLock(&opCtx, nss.db(), MODE_X);
        OldClientContext ctx(&opCtx, nss.ns());

        BSONObj doc = BSON("_id"
                           << "example string");

        ASSERT(!collectionExists(&ctx, nss.ns()));
        {
            WriteUnitOfWork uow(&opCtx);

            ASSERT_OK(userCreateNS(&opCtx,
                                   ctx.db(),
                                   nss.ns(),
                                   BSONObj(),
                                   CollectionOptions::parseForCommand,
                                   defaultIndexes));
            ASSERT(collectionExists(&ctx, nss.ns()));
            insertRecord(&opCtx, nss, doc);
            assertOnlyRecord(&opCtx, nss, doc);

            BSONObjBuilder result;
            ASSERT_OK(
                dropCollection(&opCtx,
                               nss,
                               result,
                               {},
                               DropCollectionSystemCollectionMode::kDisallowSystemCollectionDrops));
            ASSERT(!collectionExists(&ctx, nss.ns()));

            if (!rollback) {
                uow.commit();
            }
        }
        ASSERT(!collectionExists(&ctx, nss.ns()));
    }
Exemple #19
0
    void Database::clearTmpCollections() {

        Lock::assertWriteLocked( _name );
        Client::Context ctx( _name );

        string systemNamespaces =  _name + ".system.namespaces";

        // Note: we build up a toDelete vector rather than dropping the collection inside the loop
        // to avoid modifying the system.namespaces collection while iterating over it since that
        // would corrupt the cursor.
        vector<string> toDelete;
        auto_ptr<Runner> runner(InternalPlanner::collectionScan(systemNamespaces));
        BSONObj nsObj;
        Runner::RunnerState state;
        while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&nsObj, NULL))) {
            BSONElement e = nsObj.getFieldDotted( "options.temp" );
            if ( !e.trueValue() )
                continue;

            string ns = nsObj["name"].String();

            // Do not attempt to drop indexes
            if ( !NamespaceString::normal(ns.c_str()) )
                continue;

            toDelete.push_back(ns);
        }

        if (Runner::RUNNER_EOF != state) {
            warning() << "Internal error while reading collection " << systemNamespaces << endl;
        }

        for (size_t i=0; i < toDelete.size(); i++) {
            Status s = dropCollection( toDelete[i] );
            if ( !s.isOK() )
                warning() << "could not drop temp collection: " << toDelete[i]
                          << " because of " << s << endl;
        }
    }
        void run() {
            Client::WriteContext ctx(&_txn, ns());
            insert(BSON("_id" << 1 << "a" << 6));
            insert(BSON("_id" << 2 << "a" << 7));
            insert(BSON("_id" << 3 << "a" << 8));
            BSONObj indexSpec = BSON("a" << 1);
            addIndex(indexSpec);

            scoped_ptr<SingleSolutionRunner> ssr(makeIndexScanRunner(ctx.ctx(), indexSpec, 7, 10));
            registerRunner(ssr.get());

            BSONObj objOut;
            ASSERT_EQUALS(Runner::RUNNER_ADVANCED, ssr->getNext(&objOut, NULL));
            ASSERT_EQUALS(7, objOut["a"].numberInt());

            // After dropping the collection, the runner
            // should be dead.
            dropCollection();
            ASSERT_EQUALS(Runner::RUNNER_DEAD, ssr->getNext(&objOut, NULL));

            deregisterRunner(ssr.get());
        }
Exemple #21
0
    void Client::dropTempCollectionsInDB( const string db ) {
	list<string>::iterator i = _tempCollections.begin();
	while ( i!=_tempCollections.end() ) {
	    string ns = *i;
	    dblock l;
	    Client::Context ctx( ns );
	    if ( nsdetails( ns.c_str() ) &&
		 ns.compare( 0, db.length(), db ) == 0 ) {
		try {
		    string err;
		    BSONObjBuilder b;
		    dropCollection( ns, err, b );
		    i = _tempCollections.erase(i);
		    ++i;
		}
		catch ( ... ){
		    log() << "error dropping temp collection: " << ns << endl;
		}
	    } else {
		++i;
	    }
	}
    }
Exemple #22
0
    void Database::clearTmpCollections(OperationContext* txn) {
        invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X));

        list<string> collections;
        _dbEntry->getCollectionNamespaces( &collections );

        for ( list<string>::iterator i = collections.begin(); i != collections.end(); ++i ) {
            string ns = *i;
            invariant( NamespaceString::normal( ns ) );

            CollectionCatalogEntry* coll = _dbEntry->getCollectionCatalogEntry( ns );

            CollectionOptions options = coll->getCollectionOptions( txn );
            if ( !options.temp )
                continue;
            try {
                WriteUnitOfWork wunit(txn);
                Status status = dropCollection( txn, ns );
                if ( !status.isOK() ) {
                    warning() << "could not drop temp collection '" << ns << "': " << status;
                    continue;
                }

                string cmdNs = _name + ".$cmd";
                repl::logOp( txn,
                             "c",
                             cmdNs.c_str(),
                             BSON( "drop" << nsToCollectionSubstring( ns ) ) );
                wunit.commit();
            }
            catch (const WriteConflictException& exp) {
                warning() << "could not drop temp collection '" << ns << "' due to "
                    "WriteConflictException";
                txn->recoveryUnit()->commitAndRestart();
            }
        }
    }
Exemple #23
0
        virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            string source = cmdObj.getStringField( name.c_str() );
            string target = cmdObj.getStringField( "to" );
            if ( source.empty() || target.empty() ) {
                errmsg = "invalid command syntax";
                return false;
            }
            
            setClient( source.c_str() );
            NamespaceDetails *nsd = nsdetails( source.c_str() );
            uassert( "source namespace does not exist", nsd );
            bool capped = nsd->capped;
            long long size = 0;
            if ( capped )
                for( DiskLoc i = nsd->firstExtent; !i.isNull(); i = i.ext()->xnext )
                    size += i.ext()->length;
            
            setClient( target.c_str() );
            uassert( "target namespace exists", !nsdetails( target.c_str() ) );

            {
                char from[256];
                nsToClient( source.c_str(), from );
                char to[256];
                nsToClient( target.c_str(), to );
                if ( strcmp( from, to ) == 0 ) {
                    renameNamespace( source.c_str(), target.c_str() );
                    return true;
                }
            }

            BSONObjBuilder spec;
            if ( capped ) {
                spec.appendBool( "capped", true );
                spec.append( "size", double( size ) );
            }
            if ( !userCreateNS( target.c_str(), spec.done(), errmsg, false ) )
                return false;
            
            auto_ptr< DBClientCursor > c;
            DBDirectClient bridge;

            {
                c = bridge.query( source, BSONObj() );
            }
            while( 1 ) {
                {
                    if ( !c->more() )
                        break;
                }
                BSONObj o = c->next();
                theDataFileMgr.insert( target.c_str(), o );
            }
            
            char cl[256];
            nsToClient( source.c_str(), cl );
            string sourceIndexes = string( cl ) + ".system.indexes";
            nsToClient( target.c_str(), cl );
            string targetIndexes = string( cl ) + ".system.indexes";
            {
                c = bridge.query( sourceIndexes, QUERY( "ns" << source ) );
            }
            while( 1 ) {
                {
                    if ( !c->more() )
                        break;
                }
                BSONObj o = c->next();
                BSONObjBuilder b;
                BSONObjIterator i( o );
                while( i.moreWithEOO() ) {
                    BSONElement e = i.next();
                    if ( e.eoo() )
                        break;
                    if ( strcmp( e.fieldName(), "ns" ) == 0 ) {
                        b.append( "ns", target );
                    } else {
                        b.append( e );
                    }
                }
                BSONObj n = b.done();
                theDataFileMgr.insert( targetIndexes.c_str(), n );
            }

            setClient( source.c_str() );
            dropCollection( source, errmsg, result );
            return true;
        }
Exemple #24
0
Status renameCollectionForApplyOps(OperationContext* opCtx,
                                   const std::string& dbName,
                                   const BSONElement& ui,
                                   const BSONObj& cmd) {

    const auto sourceNsElt = cmd.firstElement();
    const auto targetNsElt = cmd["to"];
    const auto dropSourceElt = cmd["dropSource"];
    uassert(ErrorCodes::TypeMismatch,
            "'renameCollection' must be of type String",
            sourceNsElt.type() == BSONType::String);
    uassert(ErrorCodes::TypeMismatch,
            "'to' must be of type String",
            targetNsElt.type() == BSONType::String);

    NamespaceString sourceNss(sourceNsElt.valueStringData());
    NamespaceString targetNss(targetNsElt.valueStringData());
    NamespaceString uiNss(getNamespaceFromUUID(opCtx, ui));
    NamespaceString dropSourceNss(getNamespaceFromUUID(opCtx, dropSourceElt));

    // If the UUID we're targeting already exists, rename from there no matter what.
    // When dropSource is specified, the rename is accross databases. In that case, ui indicates
    // the UUID of the new target collection and the dropSourceNss specifies the sourceNss.
    if (!uiNss.isEmpty()) {
        sourceNss = uiNss;
        // The cross-database rename was already done and just needs a local rename, but we may
        // still need to actually remove the source collection.
        auto dropSourceNss = getNamespaceFromUUID(opCtx, dropSourceElt);
        if (!dropSourceNss.isEmpty()) {
            BSONObjBuilder unusedBuilder;
            dropCollection(opCtx,
                           dropSourceNss,
                           unusedBuilder,
                           repl::OpTime(),
                           DropCollectionSystemCollectionMode::kAllowSystemCollectionDrops)
                .ignore();
        }
    } else if (!dropSourceNss.isEmpty()) {
        sourceNss = dropSourceNss;
    } else {
        // When replaying cross-database renames, both source and target collections may no longer
        // exist. Attempting a rename anyway could result in removing a newer collection of the
        // same name.
        uassert(ErrorCodes::NamespaceNotFound,
                str::stream() << "source collection (UUID "
                              << uassertStatusOK(UUID::parse(dropSourceElt))
                              << ") for rename to "
                              << targetNss.ns()
                              << " no longer exists",
                !dropSourceElt);
    }

    OptionalCollectionUUID targetUUID;
    if (!ui.eoo())
        targetUUID = uassertStatusOK(UUID::parse(ui));

    return renameCollectionCommon(opCtx,
                                  sourceNss,
                                  targetNss,
                                  targetUUID,
                                  cmd["dropTarget"].trueValue(),
                                  cmd["stayTemp"].trueValue());
}
Exemple #25
0
    void run() {
        NamespaceString source("unittests.rollback_rename_droptarget_collection_src");
        NamespaceString target("unittests.rollback_rename_droptarget_collection_dest");
        const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
        OperationContext& opCtx = *opCtxPtr;

        dropDatabase(&opCtx, source);
        dropDatabase(&opCtx, target);

        Lock::GlobalWrite globalWriteLock(&opCtx);
        OldClientContext ctx(&opCtx, source.ns());

        BSONObj sourceDoc = BSON("_id"
                                 << "source");
        BSONObj targetDoc = BSON("_id"
                                 << "target");

        {
            WriteUnitOfWork uow(&opCtx);
            ASSERT(!collectionExists(&ctx, source.ns()));
            ASSERT(!collectionExists(&ctx, target.ns()));
            auto options = capped ? BSON("capped" << true << "size" << 1000) : BSONObj();
            ASSERT_OK(userCreateNS(&opCtx,
                                   ctx.db(),
                                   source.ns(),
                                   options,
                                   CollectionOptions::parseForCommand,
                                   defaultIndexes));
            ASSERT_OK(userCreateNS(&opCtx,
                                   ctx.db(),
                                   target.ns(),
                                   options,
                                   CollectionOptions::parseForCommand,
                                   defaultIndexes));

            insertRecord(&opCtx, source, sourceDoc);
            insertRecord(&opCtx, target, targetDoc);

            uow.commit();
        }
        ASSERT(collectionExists(&ctx, source.ns()));
        ASSERT(collectionExists(&ctx, target.ns()));
        assertOnlyRecord(&opCtx, source, sourceDoc);
        assertOnlyRecord(&opCtx, target, targetDoc);

        // END OF SETUP / START OF TEST

        {
            WriteUnitOfWork uow(&opCtx);
            BSONObjBuilder result;
            ASSERT_OK(
                dropCollection(&opCtx,
                               target,
                               result,
                               {},
                               DropCollectionSystemCollectionMode::kDisallowSystemCollectionDrops));
            ASSERT_OK(renameCollection(&opCtx, source, target));
            ASSERT(!collectionExists(&ctx, source.ns()));
            ASSERT(collectionExists(&ctx, target.ns()));
            assertOnlyRecord(&opCtx, target, sourceDoc);
            if (!rollback) {
                uow.commit();
            }
        }
        if (rollback) {
            ASSERT(collectionExists(&ctx, source.ns()));
            ASSERT(collectionExists(&ctx, target.ns()));
            assertOnlyRecord(&opCtx, source, sourceDoc);
            assertOnlyRecord(&opCtx, target, targetDoc);
        } else {
            ASSERT(!collectionExists(&ctx, source.ns()));
            ASSERT(collectionExists(&ctx, target.ns()));
            assertOnlyRecord(&opCtx, target, sourceDoc);
        }
    }
Exemple #26
0
 void drop() {
     string s( _ns );
     string errmsg;
     BSONObjBuilder result;
     dropCollection( s, errmsg, result );
 }