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); }
void run() { Client::WriteContext ctx(&_txn, ns()); Database* db = ctx.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_UNOWNED_OBJ; mockMember.loc = *locs.begin(); mockMember.obj = coll->docFor(&_txn, mockMember.loc); // Points into our DB. mockStage->pushBack(mockMember); mockMember.state = WorkingSetMember::OWNED_OBJ; mockMember.loc = DiskLoc(); mockMember.obj = BSON("foo" << 6); ASSERT_TRUE(mockMember.obj.isOwned()); mockStage->pushBack(mockMember); } auto_ptr<FetchStage> fetchStage(new FetchStage(&_txn, &ws, mockStage.release(), NULL, coll)); WorkingSetID id = WorkingSet::INVALID_ID; PlanStage::StageState state; // Don't bother doing any fetching if an obj exists already. state = fetchStage->work(&id); ASSERT_EQUALS(PlanStage::ADVANCED, state); state = fetchStage->work(&id); ASSERT_EQUALS(PlanStage::ADVANCED, state); // No more data to fetch, so, EOF. state = fetchStage->work(&id); ASSERT_EQUALS(PlanStage::IS_EOF, state); }