bool Helpers::getLast(const char *ns, BSONObj& result) { Client::Context ctx(ns); shared_ptr<Cursor> c = findTableScan(ns, reverseNaturalObj); if( !c->ok() ) return false; result = c->current(); return true; }
auto_ptr< Cursor > QueryPlan::newCursor( const DiskLoc &startLoc ) const { if ( !fbs_.matchPossible() ) return auto_ptr< Cursor >( new BasicCursor( DiskLoc() ) ); if ( !index_ ) return findTableScan( fbs_.ns(), order_, startLoc ); massert( "newCursor() with start location not implemented for indexed plans", startLoc.isNull() ); //TODO This constructor should really take a const ref to the index details. return auto_ptr< Cursor >( new BtreeCursor( *const_cast< IndexDetails* >( index_ ), startKey_, endKey_, direction_ >= 0 ? 1 : -1 ) ); }
shared_ptr<Cursor> QueryPlan::newReverseCursor() const { if ( willScanTable() ) { int orderSpec = _order.getIntField( "$natural" ); if ( orderSpec == INT_MIN ) orderSpec = 1; return findTableScan( _frs.ns(), BSON( "$natural" << -orderSpec ) ); } massert( 10364, "newReverseCursor() not implemented for indexed plans", false ); return shared_ptr<Cursor>(); }
auto_ptr< Cursor > QueryPlan::newReverseCursor() const { if ( !fbs_.matchPossible() ) return auto_ptr< Cursor >( new BasicCursor( DiskLoc() ) ); if ( !index_ ) { int orderSpec = order_.getIntField( "$natural" ); if ( orderSpec == INT_MIN ) orderSpec = 1; return findTableScan( fbs_.ns(), BSON( "$natural" << -orderSpec ) ); } massert( "newReverseCursor() not implemented for indexed plans", false ); return auto_ptr< Cursor >( 0 ); }
void run() { stringstream spec; spec << "{\"capped\":true,\"size\":2000,\"$nExtents\":" << nExtents() << "}"; string err; ASSERT( userCreateNS( ns(), fromjson( spec.str() ), err, false ) ); prepare(); int j = 0; for ( auto_ptr< Cursor > i = theDataFileMgr.findAll( ns() ); i->ok(); i->advance(), ++j ) ASSERT_EQUALS( j, i->current().firstElement().number() ); ASSERT_EQUALS( count(), j ); j = count() - 1; for ( auto_ptr< Cursor > i = findTableScan( ns(), fromjson( "{\"$natural\":-1}" ) ); i->ok(); i->advance(), --j ) ASSERT_EQUALS( j, i->current().firstElement().number() ); ASSERT_EQUALS( -1, j ); }
/* we reuse our existing objects so that we can keep our existing connection and cursor in effect. */ void ReplSource::loadAll(SourceVector &v) { Client::Context ctx("local.sources"); SourceVector old = v; v.clear(); if ( !cmdLine.source.empty() ) { // --source <host> specified. // check that no items are in sources other than that // add if missing shared_ptr<Cursor> c = findTableScan("local.sources", BSONObj()); int n = 0; while ( c->ok() ) { n++; ReplSource tmp(c->current()); if ( tmp.hostName != cmdLine.source ) { log() << "repl: --source " << cmdLine.source << " != " << tmp.hostName << " from local.sources collection" << endl; log() << "repl: for instructions on changing this slave's source, see:" << endl; log() << "http://dochub.mongodb.org/core/masterslave" << endl; log() << "repl: terminating mongod after 30 seconds" << endl; sleepsecs(30); dbexit( EXIT_REPLICATION_ERROR ); } if ( tmp.only != cmdLine.only ) { log() << "--only " << cmdLine.only << " != " << tmp.only << " from local.sources collection" << endl; log() << "terminating after 30 seconds" << endl; sleepsecs(30); dbexit( EXIT_REPLICATION_ERROR ); } c->advance(); } uassert( 10002 , "local.sources collection corrupt?", n<2 ); if ( n == 0 ) { // source missing. add. ReplSource s; s.hostName = cmdLine.source; s.only = cmdLine.only; s.save(); } } else { try { massert( 10384 , "--only requires use of --source", cmdLine.only.empty()); } catch ( ... ) { dbexit( EXIT_BADOPTIONS ); } } shared_ptr<Cursor> c = findTableScan("local.sources", BSONObj()); while ( c->ok() ) { ReplSource tmp(c->current()); if ( tmp.syncedTo.isNull() ) { DBDirectClient c; if ( c.exists( "local.oplog.$main" ) ) { BSONObj op = c.findOne( "local.oplog.$main", QUERY( "op" << NE << "n" ).sort( BSON( "$natural" << -1 ) ) ); if ( !op.isEmpty() ) { tmp.syncedTo = op[ "ts" ].date(); } } } addSourceToList(v, tmp, old); c->advance(); } }
void appendReplicationInfo(BSONObjBuilder& result, int level) { if ( replSet ) { if( theReplSet == 0 || theReplSet->state().shunned() ) { result.append("ismaster", false); result.append("secondary", false); result.append("info", ReplSet::startupStatusMsg.get()); result.append( "isreplicaset" , true ); } else { theReplSet->fillIsMaster(result); } return; } if ( replAllDead ) { result.append("ismaster", 0); string s = string("dead: ") + replAllDead; result.append("info", s); } else { result.appendBool("ismaster", _isMaster() ); } if ( level && replSet ) { result.append( "info" , "is replica set" ); } else if ( level ) { BSONObjBuilder sources( result.subarrayStart( "sources" ) ); int n = 0; list<BSONObj> src; { Client::ReadContext ctx("local.sources", dbpath); shared_ptr<Cursor> c = findTableScan("local.sources", BSONObj()); while ( c->ok() ) { src.push_back(c->current()); c->advance(); } } for( list<BSONObj>::const_iterator i = src.begin(); i != src.end(); i++ ) { BSONObj s = *i; BSONObjBuilder bb; bb.append( s["host"] ); string sourcename = s["source"].valuestr(); if ( sourcename != "main" ) bb.append( s["source"] ); { BSONElement e = s["syncedTo"]; BSONObjBuilder t( bb.subobjStart( "syncedTo" ) ); t.appendDate( "time" , e.timestampTime() ); t.append( "inc" , e.timestampInc() ); t.done(); } if ( level > 1 ) { wassert( !Lock::isLocked() ); // note: there is no so-style timeout on this connection; perhaps we should have one. ScopedDbConnection conn(s["host"].valuestr()); DBClientConnection *cliConn = dynamic_cast< DBClientConnection* >( &conn.conn() ); if ( cliConn && replAuthenticate(cliConn, false) ) { BSONObj first = conn->findOne( (string)"local.oplog.$" + sourcename, Query().sort( BSON( "$natural" << 1 ) ) ); BSONObj last = conn->findOne( (string)"local.oplog.$" + sourcename, Query().sort( BSON( "$natural" << -1 ) ) ); bb.appendDate( "masterFirst" , first["ts"].timestampTime() ); bb.appendDate( "masterLast" , last["ts"].timestampTime() ); double lag = (double) (last["ts"].timestampTime() - s["syncedTo"].timestampTime()); bb.append( "lagSeconds" , lag / 1000 ); } conn.done(); } sources.append( BSONObjBuilder::numStr( n++ ) , bb.obj() ); } sources.done(); } }
shared_ptr<Cursor> QueryPlan::newCursor( const DiskLoc& startLoc, bool requestIntervalCursor ) const { if ( _type ) { // hopefully safe to use original query in these contexts - don't think we can mix type // with $or clause separation yet int numWanted = 0; if ( _parsedQuery ) { // SERVER-5390 numWanted = _parsedQuery->getSkip() + _parsedQuery->getNumToReturn(); } IndexDescriptor* descriptor = CatalogHack::getDescriptor(_d, _idxNo); IndexAccessMethod* iam = CatalogHack::getIndex(descriptor); return shared_ptr<Cursor>(EmulatedCursor::make(descriptor, iam, _originalQuery, _order, numWanted, descriptor->keyPattern())); } if ( _utility == Impossible ) { // Dummy table scan cursor returning no results. Allowed in --notablescan mode. return shared_ptr<Cursor>( new BasicCursor( DiskLoc() ) ); } if ( willScanTable() ) { checkTableScanAllowed(); return findTableScan( _frs.ns(), _order, startLoc ); } massert( 10363, "newCursor() with start location not implemented for indexed plans", startLoc.isNull() ); if ( _startOrEndSpec ) { // we are sure to spec _endKeyInclusive return shared_ptr<Cursor>( BtreeCursor::make( _d, *_index, _startKey, _endKey, _endKeyInclusive, _direction >= 0 ? 1 : -1 ) ); } if ( _index->getSpec().getType() ) { return shared_ptr<Cursor>( BtreeCursor::make( _d, *_index, _frv->startKey(), _frv->endKey(), true, _direction >= 0 ? 1 : -1 ) ); } // An IntervalBtreeCursor is returned if explicitly requested AND _frv is exactly // represented by a single interval within the btree. if ( // If an interval cursor is requested and ... requestIntervalCursor && // ... equalities come before ranges (a requirement of Optimal) and ... _utility == Optimal && // ... the field range vector exactly represents a single interval ... _frv->isSingleInterval() ) { // ... and an interval cursor can be created ... shared_ptr<Cursor> ret( IntervalBtreeCursor::make( _d, *_index, _frv->startKey(), _frv->startKeyInclusive(), _frv->endKey(), _frv->endKeyInclusive() ) ); if ( ret ) { // ... then return the interval cursor. return ret; } } return shared_ptr<Cursor>( BtreeCursor::make( _d, *_index, _frv, independentRangesSingleIntervalLimit(), _direction >= 0 ? 1 : -1 ) ); }