Files
mongo/db/oplogreader.h

133 lines
4.2 KiB
C
Raw Normal View History

2010-07-18 13:41:20 -04:00
/** @file oplogreader.h */
#pragma once
#include "../client/dbclient.h"
#include "../client/constants.h"
2010-07-23 14:52:14 -04:00
#include "dbhelpers.h"
2010-07-18 13:41:20 -04:00
namespace mongo {
2011-01-04 00:40:41 -05:00
/* started abstracting out the querying of the primary/master's oplog
2010-07-18 13:41:20 -04:00
still fairly awkward but a start.
*/
class OplogReader {
shared_ptr<DBClientConnection> _conn;
shared_ptr<DBClientCursor> cursor;
2010-07-18 13:41:20 -04:00
public:
2011-01-04 00:40:41 -05:00
OplogReader() {
2010-07-30 16:21:28 -04:00
}
2011-01-04 00:40:41 -05:00
~OplogReader() {
2010-07-30 16:21:28 -04:00
}
2010-07-21 13:13:36 -04:00
void resetCursor() {
2010-07-18 13:41:20 -04:00
cursor.reset();
}
void resetConnection() {
cursor.reset();
_conn.reset();
}
DBClientConnection* conn() { return _conn.get(); }
2011-01-04 00:40:41 -05:00
BSONObj findOne(const char *ns, const Query& q) {
return conn()->findOne(ns, q, 0, QueryOption_SlaveOk);
2010-07-18 13:41:20 -04:00
}
2011-01-04 00:40:41 -05:00
BSONObj getLastOp(const char *ns) {
2010-07-23 14:52:14 -04:00
return findOne(ns, Query().sort(reverseNaturalObj));
2010-07-18 15:02:46 -04:00
}
2010-07-18 13:41:20 -04:00
/* ok to call if already connected */
bool connect(string hostname);
2011-06-09 15:05:34 -04:00
bool connect(const BSONObj& rid, const int from, const string& to);
2010-07-20 13:37:09 -04:00
void tailCheck() {
2011-01-04 00:40:41 -05:00
if( cursor.get() && cursor->isDead() ) {
2010-07-20 13:37:09 -04:00
log() << "repl: old cursor isDead, will initiate a new one" << endl;
2010-07-21 13:13:36 -04:00
resetCursor();
2010-07-18 13:41:20 -04:00
}
}
bool haveCursor() { return cursor.get() != 0; }
2011-10-10 18:10:26 -04:00
/** this is ok but commented out as when used one should consider if QueryOption_OplogReplay
is needed; if not fine, but if so, need to change.
*//*
2011-01-04 00:40:41 -05:00
void query(const char *ns, const BSONObj& query) {
assert( !haveCursor() );
2011-05-12 08:15:40 -04:00
cursor.reset( _conn->query(ns, query, 0, 0, 0, QueryOption_SlaveOk).release() );
2011-10-10 18:10:26 -04:00
}*/
2011-10-10 18:10:26 -04:00
/** this can be used; it is commented out as it does not indicate
QueryOption_OplogReplay and that is likely important. could be uncommented
just need to add that.
*/
/*
void queryGTE(const char *ns, OpTime t) {
BSONObjBuilder q;
q.appendDate("$gte", t.asDate());
BSONObjBuilder q2;
q2.append("ts", q.done());
query(ns, q2.done());
}
2011-10-10 18:10:26 -04:00
*/
void tailingQuery(const char *ns, const BSONObj& query, const BSONObj* fields=0) {
2010-07-18 13:41:20 -04:00
assert( !haveCursor() );
log(2) << "repl: " << ns << ".find(" << query.toString() << ')' << endl;
2011-05-12 08:23:12 -04:00
cursor.reset( _conn->query( ns, query, 0, 0, fields,
QueryOption_CursorTailable | QueryOption_SlaveOk | QueryOption_OplogReplay |
/* TODO: slaveOk maybe shouldn't use? */
2011-05-12 08:23:12 -04:00
QueryOption_AwaitData
).release() );
2010-07-18 13:41:20 -04:00
}
void tailingQueryGTE(const char *ns, OpTime t, const BSONObj* fields=0) {
2010-07-19 22:32:43 -04:00
BSONObjBuilder q;
q.appendDate("$gte", t.asDate());
BSONObjBuilder query;
query.append("ts", q.done());
tailingQuery(ns, query.done(), fields);
}
/* Do a tailing query, but only send the ts field back. */
void ghostQueryGTE(const char *ns, OpTime t) {
const BSONObj fields = BSON("ts" << 1 << "_id" << 0);
return tailingQueryGTE(ns, t, &fields);
2010-07-19 22:32:43 -04:00
}
2011-01-04 00:40:41 -05:00
bool more() {
uassert( 15910, "Doesn't have cursor for reading oplog", cursor.get() );
2010-07-18 13:41:20 -04:00
return cursor->more();
}
2011-01-04 00:40:41 -05:00
bool moreInCurrentBatch() {
uassert( 15911, "Doesn't have cursor for reading oplog", cursor.get() );
2010-07-20 11:05:27 -04:00
return cursor->moreInCurrentBatch();
}
2010-07-18 13:41:20 -04:00
/* old mongod's can't do the await flag... */
2011-01-04 00:40:41 -05:00
bool awaitCapable() {
2010-07-18 13:41:20 -04:00
return cursor->hasResultFlag(ResultFlag_AwaitCapable);
}
2011-01-04 00:40:41 -05:00
void peek(vector<BSONObj>& v, int n) {
2010-07-18 13:41:20 -04:00
if( cursor.get() )
cursor->peek(v,n);
}
2010-07-19 22:32:43 -04:00
BSONObj nextSafe() { return cursor->nextSafe(); }
BSONObj next() { return cursor->next(); }
2010-07-18 13:41:20 -04:00
void putBack(BSONObj op) { cursor->putBack(op); }
private:
bool commonConnect(const string& hostName);
2011-06-09 15:05:34 -04:00
bool passthroughHandshake(const BSONObj& rid, const int f);
2010-07-18 13:41:20 -04:00
};
2011-01-04 00:40:41 -05:00
2010-07-18 13:41:20 -04:00
}