summaryrefslogtreecommitdiff
path: root/src/mongo/client/dbclientinterface.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client/dbclientinterface.h')
-rw-r--r--src/mongo/client/dbclientinterface.h2193
1 files changed, 1164 insertions, 1029 deletions
diff --git a/src/mongo/client/dbclientinterface.h b/src/mongo/client/dbclientinterface.h
index 853cae2d898..a612777b603 100644
--- a/src/mongo/client/dbclientinterface.h
+++ b/src/mongo/client/dbclientinterface.h
@@ -44,1134 +44,1269 @@
namespace mongo {
- /** the query field 'options' can have these bits set: */
- enum QueryOptions {
- /** Tailable means cursor is not closed when the last data is retrieved. rather, the cursor marks
- the final object's position. you can resume using the cursor later, from where it was located,
- if more data were received. Set on dbQuery and dbGetMore.
-
- like any "latent cursor", the cursor may become invalid at some point -- for example if that
- final object it references were deleted. Thus, you should be prepared to requery if you get back
- ResultFlag_CursorNotFound.
- */
- QueryOption_CursorTailable = 1 << 1,
-
- /** allow query of replica slave. normally these return an error except for namespace "local".
- */
- QueryOption_SlaveOk = 1 << 2,
-
- // findingStart mode is used to find the first operation of interest when
- // we are scanning through a repl log. For efficiency in the common case,
- // where the first operation of interest is closer to the tail than the head,
- // we start from the tail of the log and work backwards until we find the
- // first operation of interest. Then we scan forward from that first operation,
- // actually returning results to the client. During the findingStart phase,
- // we release the db mutex occasionally to avoid blocking the db process for
- // an extended period of time.
- QueryOption_OplogReplay = 1 << 3,
-
- /** The server normally times out idle cursors after an inactivity period to prevent excess memory uses
- Set this option to prevent that.
- */
- QueryOption_NoCursorTimeout = 1 << 4,
-
- /** Use with QueryOption_CursorTailable. If we are at the end of the data, block for a while rather
- than returning no data. After a timeout period, we do return as normal.
- */
- QueryOption_AwaitData = 1 << 5,
-
- /** Stream the data down full blast in multiple "more" packages, on the assumption that the client
- will fully read all data queried. Faster when you are pulling a lot of data and know you want to
- pull it all down. Note: it is not allowed to not read all the data unless you close the connection.
-
- Use the query( stdx::function<void(const BSONObj&)> f, ... ) version of the connection's query()
- method, and it will take care of all the details for you.
- */
- QueryOption_Exhaust = 1 << 6,
-
- /** When sharded, this means its ok to return partial results
- Usually we will fail a query if all required shards aren't up
- If this is set, it'll be a partial result set
- */
- QueryOption_PartialResults = 1 << 7 ,
-
- QueryOption_AllSupported = QueryOption_CursorTailable |
- QueryOption_SlaveOk |
- QueryOption_OplogReplay |
- QueryOption_NoCursorTimeout |
- QueryOption_AwaitData |
- QueryOption_Exhaust |
- QueryOption_PartialResults,
-
- QueryOption_AllSupportedForSharding = QueryOption_CursorTailable |
- QueryOption_SlaveOk |
- QueryOption_OplogReplay |
- QueryOption_NoCursorTimeout |
- QueryOption_AwaitData |
- QueryOption_PartialResults,
- };
-
- enum UpdateOptions {
- /** Upsert - that is, insert the item if no matching item is found. */
- UpdateOption_Upsert = 1 << 0,
-
- /** Update multiple documents (if multiple documents match query expression).
- (Default is update a single document and stop.) */
- UpdateOption_Multi = 1 << 1,
-
- /** flag from mongo saying this update went everywhere */
- UpdateOption_Broadcast = 1 << 2
- };
-
- enum RemoveOptions {
- /** only delete one option */
- RemoveOption_JustOne = 1 << 0,
-
- /** flag from mongo saying this update went everywhere */
- RemoveOption_Broadcast = 1 << 1
- };
-
- enum InsertOptions {
- /** With muli-insert keep processing inserts if one fails */
- InsertOption_ContinueOnError = 1 << 0
- };
+/** the query field 'options' can have these bits set: */
+enum QueryOptions {
+ /** Tailable means cursor is not closed when the last data is retrieved. rather, the cursor marks
+ the final object's position. you can resume using the cursor later, from where it was located,
+ if more data were received. Set on dbQuery and dbGetMore.
+
+ like any "latent cursor", the cursor may become invalid at some point -- for example if that
+ final object it references were deleted. Thus, you should be prepared to requery if you get back
+ ResultFlag_CursorNotFound.
+ */
+ QueryOption_CursorTailable = 1 << 1,
+
+ /** allow query of replica slave. normally these return an error except for namespace "local".
+ */
+ QueryOption_SlaveOk = 1 << 2,
+
+ // findingStart mode is used to find the first operation of interest when
+ // we are scanning through a repl log. For efficiency in the common case,
+ // where the first operation of interest is closer to the tail than the head,
+ // we start from the tail of the log and work backwards until we find the
+ // first operation of interest. Then we scan forward from that first operation,
+ // actually returning results to the client. During the findingStart phase,
+ // we release the db mutex occasionally to avoid blocking the db process for
+ // an extended period of time.
+ QueryOption_OplogReplay = 1 << 3,
+
+ /** The server normally times out idle cursors after an inactivity period to prevent excess memory uses
+ Set this option to prevent that.
+ */
+ QueryOption_NoCursorTimeout = 1 << 4,
+
+ /** Use with QueryOption_CursorTailable. If we are at the end of the data, block for a while rather
+ than returning no data. After a timeout period, we do return as normal.
+ */
+ QueryOption_AwaitData = 1 << 5,
+
+ /** Stream the data down full blast in multiple "more" packages, on the assumption that the client
+ will fully read all data queried. Faster when you are pulling a lot of data and know you want to
+ pull it all down. Note: it is not allowed to not read all the data unless you close the connection.
+
+ Use the query( stdx::function<void(const BSONObj&)> f, ... ) version of the connection's query()
+ method, and it will take care of all the details for you.
+ */
+ QueryOption_Exhaust = 1 << 6,
+
+ /** When sharded, this means its ok to return partial results
+ Usually we will fail a query if all required shards aren't up
+ If this is set, it'll be a partial result set
+ */
+ QueryOption_PartialResults = 1 << 7,
+
+ QueryOption_AllSupported = QueryOption_CursorTailable | QueryOption_SlaveOk |
+ QueryOption_OplogReplay | QueryOption_NoCursorTimeout | QueryOption_AwaitData |
+ QueryOption_Exhaust | QueryOption_PartialResults,
+
+ QueryOption_AllSupportedForSharding = QueryOption_CursorTailable | QueryOption_SlaveOk |
+ QueryOption_OplogReplay | QueryOption_NoCursorTimeout | QueryOption_AwaitData |
+ QueryOption_PartialResults,
+};
+
+enum UpdateOptions {
+ /** Upsert - that is, insert the item if no matching item is found. */
+ UpdateOption_Upsert = 1 << 0,
+
+ /** Update multiple documents (if multiple documents match query expression).
+ (Default is update a single document and stop.) */
+ UpdateOption_Multi = 1 << 1,
+
+ /** flag from mongo saying this update went everywhere */
+ UpdateOption_Broadcast = 1 << 2
+};
+
+enum RemoveOptions {
+ /** only delete one option */
+ RemoveOption_JustOne = 1 << 0,
+ /** flag from mongo saying this update went everywhere */
+ RemoveOption_Broadcast = 1 << 1
+};
+
+enum InsertOptions {
+ /** With muli-insert keep processing inserts if one fails */
+ InsertOption_ContinueOnError = 1 << 0
+};
+
+/**
+ * Start from *top* of bits, these are generic write options that apply to all
+ */
+enum WriteOptions {
+ /** logical writeback option */
+ WriteOption_FromWriteback = 1 << 31
+};
+
+//
+// For legacy reasons, the reserved field pre-namespace of certain types of messages is used
+// to store options as opposed to the flags after the namespace. This should be transparent to
+// the api user, but we need these constants to disassemble/reassemble the messages correctly.
+//
+
+enum ReservedOptions {
+ Reserved_InsertOption_ContinueOnError = 1 << 0,
+ Reserved_FromWriteback = 1 << 1
+};
+
+class DBClientCursor;
+class DBClientCursorBatchIterator;
+
+/** Represents a Mongo query expression. Typically one uses the QUERY(...) macro to construct a Query object.
+ Examples:
+ QUERY( "age" << 33 << "school" << "UCLA" ).sort("name")
+ QUERY( "age" << GT << 30 << LT << 50 )
+*/
+class Query {
+public:
+ static const BSONField<BSONObj> ReadPrefField;
+ static const BSONField<std::string> ReadPrefModeField;
+ static const BSONField<BSONArray> ReadPrefTagsField;
+
+ BSONObj obj;
+ Query() : obj(BSONObj()) {}
+ Query(const BSONObj& b) : obj(b) {}
+ Query(const std::string& json);
+ Query(const char* json);
+
+ /** Add a sort (ORDER BY) criteria to the query expression.
+ @param sortPattern the sort order template. For example to order by name ascending, time descending:
+ { name : 1, ts : -1 }
+ i.e.
+ BSON( "name" << 1 << "ts" << -1 )
+ or
+ fromjson(" name : 1, ts : -1 ")
+ */
+ Query& sort(const BSONObj& sortPattern);
+
+ /** Add a sort (ORDER BY) criteria to the query expression.
+ This version of sort() assumes you want to sort on a single field.
+ @param asc = 1 for ascending order
+ asc = -1 for descending order
+ */
+ Query& sort(const std::string& field, int asc = 1) {
+ sort(BSON(field << asc));
+ return *this;
+ }
+
+ /** Provide a hint to the query.
+ @param keyPattern Key pattern for the index to use.
+ Example:
+ hint("{ts:1}")
+ */
+ Query& hint(BSONObj keyPattern);
+ Query& hint(const std::string& jsonKeyPatt);
+
+ /** Provide min and/or max index limits for the query.
+ min <= x < max
+ */
+ Query& minKey(const BSONObj& val);
/**
- * Start from *top* of bits, these are generic write options that apply to all
+ max is exclusive
*/
- enum WriteOptions {
- /** logical writeback option */
- WriteOption_FromWriteback = 1 << 31
- };
-
- //
- // For legacy reasons, the reserved field pre-namespace of certain types of messages is used
- // to store options as opposed to the flags after the namespace. This should be transparent to
- // the api user, but we need these constants to disassemble/reassemble the messages correctly.
- //
-
- enum ReservedOptions {
- Reserved_InsertOption_ContinueOnError = 1 << 0 ,
- Reserved_FromWriteback = 1 << 1
- };
-
- class DBClientCursor;
- class DBClientCursorBatchIterator;
-
- /** Represents a Mongo query expression. Typically one uses the QUERY(...) macro to construct a Query object.
+ Query& maxKey(const BSONObj& val);
+
+ /** Return explain information about execution of this query instead of the actual query results.
+ Normally it is easier to use the mongo shell to run db.find(...).explain().
+ */
+ Query& explain();
+
+ /** Use snapshot mode for the query. Snapshot mode assures no duplicates are returned, or objects missed, which were
+ present at both the start and end of the query's execution (if an object is new during the query, or deleted during
+ the query, it may or may not be returned, even with snapshot mode).
+
+ Note that short query responses (less than 1MB) are always effectively snapshotted.
+
+ Currently, snapshot mode may not be used with sorting or explicit hints.
+ */
+ Query& snapshot();
+
+ /** Queries to the Mongo database support a $where parameter option which contains
+ a javascript function that is evaluated to see whether objects being queried match
+ its criteria. Use this helper to append such a function to a query object.
+ Your query may also contain other traditional Mongo query terms.
+
+ @param jscode The javascript function to evaluate against each potential object
+ match. The function must return true for matched objects. Use the this
+ variable to inspect the current object.
+ @param scope SavedContext for the javascript object. List in a BSON object any
+ variables you would like defined when the jscode executes. One can think
+ of these as "bind variables".
+
Examples:
- QUERY( "age" << 33 << "school" << "UCLA" ).sort("name")
- QUERY( "age" << GT << 30 << LT << 50 )
+ conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 || this.c == 3"));
+ Query badBalance = Query().where("this.debits - this.credits < 0");
*/
- class Query {
- public:
- static const BSONField<BSONObj> ReadPrefField;
- static const BSONField<std::string> ReadPrefModeField;
- static const BSONField<BSONArray> ReadPrefTagsField;
-
- BSONObj obj;
- Query() : obj(BSONObj()) { }
- Query(const BSONObj& b) : obj(b) { }
- Query(const std::string &json);
- Query(const char * json);
-
- /** Add a sort (ORDER BY) criteria to the query expression.
- @param sortPattern the sort order template. For example to order by name ascending, time descending:
- { name : 1, ts : -1 }
- i.e.
- BSON( "name" << 1 << "ts" << -1 )
- or
- fromjson(" name : 1, ts : -1 ")
- */
- Query& sort(const BSONObj& sortPattern);
-
- /** Add a sort (ORDER BY) criteria to the query expression.
- This version of sort() assumes you want to sort on a single field.
- @param asc = 1 for ascending order
- asc = -1 for descending order
- */
- Query& sort(const std::string &field, int asc = 1) { sort( BSON( field << asc ) ); return *this; }
-
- /** Provide a hint to the query.
- @param keyPattern Key pattern for the index to use.
- Example:
- hint("{ts:1}")
- */
- Query& hint(BSONObj keyPattern);
- Query& hint(const std::string &jsonKeyPatt);
-
- /** Provide min and/or max index limits for the query.
- min <= x < max
- */
- Query& minKey(const BSONObj &val);
- /**
- max is exclusive
- */
- Query& maxKey(const BSONObj &val);
-
- /** Return explain information about execution of this query instead of the actual query results.
- Normally it is easier to use the mongo shell to run db.find(...).explain().
- */
- Query& explain();
-
- /** Use snapshot mode for the query. Snapshot mode assures no duplicates are returned, or objects missed, which were
- present at both the start and end of the query's execution (if an object is new during the query, or deleted during
- the query, it may or may not be returned, even with snapshot mode).
-
- Note that short query responses (less than 1MB) are always effectively snapshotted.
-
- Currently, snapshot mode may not be used with sorting or explicit hints.
- */
- Query& snapshot();
-
- /** Queries to the Mongo database support a $where parameter option which contains
- a javascript function that is evaluated to see whether objects being queried match
- its criteria. Use this helper to append such a function to a query object.
- Your query may also contain other traditional Mongo query terms.
-
- @param jscode The javascript function to evaluate against each potential object
- match. The function must return true for matched objects. Use the this
- variable to inspect the current object.
- @param scope SavedContext for the javascript object. List in a BSON object any
- variables you would like defined when the jscode executes. One can think
- of these as "bind variables".
-
- Examples:
- conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 || this.c == 3"));
- Query badBalance = Query().where("this.debits - this.credits < 0");
- */
- Query& where(const std::string &jscode, BSONObj scope);
- Query& where(const std::string &jscode) { return where(jscode, BSONObj()); }
-
- /**
- * Sets the read preference for this query.
- *
- * @param pref the read preference mode for this query.
- * @param tags the set of tags to use for this query.
- */
- Query& readPref(ReadPreference pref, const BSONArray& tags);
-
- /**
- * @return true if this query has an orderby, hint, or some other field
- */
- bool isComplex( bool * hasDollar = 0 ) const;
- static bool isComplex(const BSONObj& obj, bool* hasDollar = 0);
-
- BSONObj getFilter() const;
- BSONObj getSort() const;
- BSONObj getHint() const;
- bool isExplain() const;
-
- /**
- * @return true if the query object contains a read preference specification object.
- */
- static bool hasReadPreference(const BSONObj& queryObj);
-
- std::string toString() const;
- operator std::string() const { return toString(); }
- private:
- void makeComplex();
- template< class T >
- void appendComplex( const char *fieldName, const T& val ) {
- makeComplex();
- BSONObjBuilder b;
- b.appendElements(obj);
- b.append(fieldName, val);
- obj = b.obj();
- }
- };
+ Query& where(const std::string& jscode, BSONObj scope);
+ Query& where(const std::string& jscode) {
+ return where(jscode, BSONObj());
+ }
/**
- * Represents a full query description, including all options required for the query to be passed on
- * to other hosts
+ * Sets the read preference for this query.
+ *
+ * @param pref the read preference mode for this query.
+ * @param tags the set of tags to use for this query.
*/
- class QuerySpec {
-
- std::string _ns;
- int _ntoskip;
- int _ntoreturn;
- int _options;
- BSONObj _query;
- BSONObj _fields;
- Query _queryObj;
-
- public:
-
- QuerySpec( const std::string& ns,
- const BSONObj& query, const BSONObj& fields,
- int ntoskip, int ntoreturn, int options )
- : _ns( ns ), _ntoskip( ntoskip ), _ntoreturn( ntoreturn ), _options( options ),
- _query( query.getOwned() ), _fields( fields.getOwned() ) , _queryObj( _query ) {
- }
+ Query& readPref(ReadPreference pref, const BSONArray& tags);
- QuerySpec() {}
+ /**
+ * @return true if this query has an orderby, hint, or some other field
+ */
+ bool isComplex(bool* hasDollar = 0) const;
+ static bool isComplex(const BSONObj& obj, bool* hasDollar = 0);
- bool isEmpty() const { return _ns.size() == 0; }
+ BSONObj getFilter() const;
+ BSONObj getSort() const;
+ BSONObj getHint() const;
+ bool isExplain() const;
+
+ /**
+ * @return true if the query object contains a read preference specification object.
+ */
+ static bool hasReadPreference(const BSONObj& queryObj);
- bool isExplain() const { return _queryObj.isExplain(); }
- BSONObj filter() const { return _queryObj.getFilter(); }
+ std::string toString() const;
+ operator std::string() const {
+ return toString();
+ }
- BSONObj hint() const { return _queryObj.getHint(); }
- BSONObj sort() const { return _queryObj.getSort(); }
- BSONObj query() const { return _query; }
- BSONObj fields() const { return _fields; }
- BSONObj* fieldsData() { return &_fields; }
+private:
+ void makeComplex();
+ template <class T>
+ void appendComplex(const char* fieldName, const T& val) {
+ makeComplex();
+ BSONObjBuilder b;
+ b.appendElements(obj);
+ b.append(fieldName, val);
+ obj = b.obj();
+ }
+};
- // don't love this, but needed downstrem
- const BSONObj* fieldsPtr() const { return &_fields; }
+/**
+ * Represents a full query description, including all options required for the query to be passed on
+ * to other hosts
+ */
+class QuerySpec {
+ std::string _ns;
+ int _ntoskip;
+ int _ntoreturn;
+ int _options;
+ BSONObj _query;
+ BSONObj _fields;
+ Query _queryObj;
+
+public:
+ QuerySpec(const std::string& ns,
+ const BSONObj& query,
+ const BSONObj& fields,
+ int ntoskip,
+ int ntoreturn,
+ int options)
+ : _ns(ns),
+ _ntoskip(ntoskip),
+ _ntoreturn(ntoreturn),
+ _options(options),
+ _query(query.getOwned()),
+ _fields(fields.getOwned()),
+ _queryObj(_query) {}
+
+ QuerySpec() {}
+
+ bool isEmpty() const {
+ return _ns.size() == 0;
+ }
- std::string ns() const { return _ns; }
- int ntoskip() const { return _ntoskip; }
- int ntoreturn() const { return _ntoreturn; }
- int options() const { return _options; }
+ bool isExplain() const {
+ return _queryObj.isExplain();
+ }
+ BSONObj filter() const {
+ return _queryObj.getFilter();
+ }
- void setFields( BSONObj& o ) { _fields = o.getOwned(); }
+ BSONObj hint() const {
+ return _queryObj.getHint();
+ }
+ BSONObj sort() const {
+ return _queryObj.getSort();
+ }
+ BSONObj query() const {
+ return _query;
+ }
+ BSONObj fields() const {
+ return _fields;
+ }
+ BSONObj* fieldsData() {
+ return &_fields;
+ }
- std::string toString() const {
- return str::stream() << "QSpec " <<
- BSON( "ns" << _ns << "n2skip" << _ntoskip << "n2return" << _ntoreturn << "options" << _options
- << "query" << _query << "fields" << _fields );
- }
+ // don't love this, but needed downstrem
+ const BSONObj* fieldsPtr() const {
+ return &_fields;
+ }
- };
+ std::string ns() const {
+ return _ns;
+ }
+ int ntoskip() const {
+ return _ntoskip;
+ }
+ int ntoreturn() const {
+ return _ntoreturn;
+ }
+ int options() const {
+ return _options;
+ }
+ void setFields(BSONObj& o) {
+ _fields = o.getOwned();
+ }
- /** Typically one uses the QUERY(...) macro to construct a Query object.
- Example: QUERY( "age" << 33 << "school" << "UCLA" )
+ std::string toString() const {
+ return str::stream() << "QSpec " << BSON("ns" << _ns << "n2skip" << _ntoskip << "n2return"
+ << _ntoreturn << "options" << _options
+ << "query" << _query << "fields" << _fields);
+ }
+};
+
+
+/** Typically one uses the QUERY(...) macro to construct a Query object.
+ Example: QUERY( "age" << 33 << "school" << "UCLA" )
+*/
+#define QUERY(x) ::mongo::Query(BSON(x))
+
+// Useful utilities for namespaces
+/** @return the database name portion of an ns std::string */
+std::string nsGetDB(const std::string& ns);
+
+/** @return the collection name portion of an ns std::string */
+std::string nsGetCollection(const std::string& ns);
+
+/**
+ interface that handles communication with the db
+ */
+class DBConnector {
+public:
+ virtual ~DBConnector() {}
+ /** actualServer is set to the actual server where they call went if there was a choice (SlaveOk) */
+ virtual bool call(Message& toSend,
+ Message& response,
+ bool assertOk = true,
+ std::string* actualServer = 0) = 0;
+ virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0) = 0;
+ virtual void sayPiggyBack(Message& toSend) = 0;
+ /* used by QueryOption_Exhaust. To use that your subclass must implement this. */
+ virtual bool recv(Message& m) {
+ verify(false);
+ return false;
+ }
+ // In general, for lazy queries, we'll need to say, recv, then checkResponse
+ virtual void checkResponse(const char* data,
+ int nReturned,
+ bool* retry = NULL,
+ std::string* targetHost = NULL) {
+ if (retry)
+ *retry = false;
+ if (targetHost)
+ *targetHost = "";
+ }
+ virtual bool lazySupported() const = 0;
+};
+
+/**
+ The interface that any db connection should implement
+ */
+class DBClientInterface {
+ MONGO_DISALLOW_COPYING(DBClientInterface);
+
+public:
+ virtual std::unique_ptr<DBClientCursor> query(const std::string& ns,
+ Query query,
+ int nToReturn = 0,
+ int nToSkip = 0,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0,
+ int batchSize = 0) = 0;
+
+ virtual void insert(const std::string& ns, BSONObj obj, int flags = 0) = 0;
+
+ virtual void insert(const std::string& ns, const std::vector<BSONObj>& v, int flags = 0) = 0;
+
+ virtual void remove(const std::string& ns, Query query, bool justOne = 0) = 0;
+
+ virtual void remove(const std::string& ns, Query query, int flags) = 0;
+
+ virtual void update(const std::string& ns,
+ Query query,
+ BSONObj obj,
+ bool upsert = false,
+ bool multi = false) = 0;
+
+ virtual void update(const std::string& ns, Query query, BSONObj obj, int flags) = 0;
+
+ virtual ~DBClientInterface() {}
+
+ /**
+ @return a single object that matches the query. if none do, then the object is empty
+ @throws AssertionException
+ */
+ virtual BSONObj findOne(const std::string& ns,
+ const Query& query,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0);
+
+ /** query N objects from the database into an array. makes sense mostly when you want a small number of results. if a huge number, use
+ query() and iterate the cursor.
*/
-#define QUERY(x) ::mongo::Query( BSON(x) )
+ void findN(std::vector<BSONObj>& out,
+ const std::string& ns,
+ Query query,
+ int nToReturn,
+ int nToSkip = 0,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0);
+
+ virtual std::string getServerAddress() const = 0;
+
+ /** don't use this - called automatically by DBClientCursor for you */
+ virtual std::unique_ptr<DBClientCursor> getMore(const std::string& ns,
+ long long cursorId,
+ int nToReturn = 0,
+ int options = 0) = 0;
+
+protected:
+ DBClientInterface() = default;
+};
+
+/**
+ DB "commands"
+ Basically just invocations of connection.$cmd.findOne({...});
+*/
+class DBClientWithCommands : public DBClientInterface, public DBConnector {
+public:
+ /** controls how chatty the client is about network errors & such. See log.h */
+ logger::LogSeverity _logLevel;
+
+ DBClientWithCommands()
+ : _logLevel(logger::LogSeverity::Log()),
+ _cachedAvailableOptions((enum QueryOptions)0),
+ _haveCachedAvailableOptions(false) {}
+
+ /** helper function. run a simple command where the command expression is simply
+ { command : 1 }
+ @param info -- where to put result object. may be null if caller doesn't need that info
+ @param command -- command name
+ @return true if the command returned "ok".
+ */
+ bool simpleCommand(const std::string& dbname, BSONObj* info, const std::string& command);
- // Useful utilities for namespaces
- /** @return the database name portion of an ns std::string */
- std::string nsGetDB( const std::string &ns );
+ rpc::ProtocolSet getClientRPCProtocols() const;
+ rpc::ProtocolSet getServerRPCProtocols() const;
- /** @return the collection name portion of an ns std::string */
- std::string nsGetCollection( const std::string &ns );
+ void setClientRPCProtocols(rpc::ProtocolSet clientProtocols);
/**
- interface that handles communication with the db
+ * Sets a RequestMetadataWriter on this connection.
+ *
+ * TODO: support multiple metadata writers.
*/
- class DBConnector {
- public:
- virtual ~DBConnector() {}
- /** actualServer is set to the actual server where they call went if there was a choice (SlaveOk) */
- virtual bool call( Message &toSend, Message &response, bool assertOk=true , std::string * actualServer = 0 ) = 0;
- virtual void say( Message &toSend, bool isRetry = false , std::string * actualServer = 0 ) = 0;
- virtual void sayPiggyBack( Message &toSend ) = 0;
- /* used by QueryOption_Exhaust. To use that your subclass must implement this. */
- virtual bool recv( Message& m ) { verify(false); return false; }
- // In general, for lazy queries, we'll need to say, recv, then checkResponse
- virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, std::string* targetHost = NULL ) {
- if( retry ) *retry = false; if( targetHost ) *targetHost = "";
- }
- virtual bool lazySupported() const = 0;
- };
+ virtual void setRequestMetadataWriter(rpc::RequestMetadataWriter writer);
+
+ /**
+ * Gets the RequestMetadataWriter that is set on this connection. This may
+ * be an uninitialized stdx::function, so it should be checked for validity
+ * with operator bool() first.
+ */
+ const rpc::RequestMetadataWriter& getRequestMetadataWriter();
/**
- The interface that any db connection should implement
+ * Sets a ReplyMetadataReader on this connection.
+ *
+ * TODO: support multiple metadata readers.
*/
- class DBClientInterface {
- MONGO_DISALLOW_COPYING(DBClientInterface);
- public:
- virtual std::unique_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
- const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 ) = 0;
+ virtual void setReplyMetadataReader(rpc::ReplyMetadataReader reader);
- virtual void insert( const std::string &ns, BSONObj obj , int flags=0) = 0;
+ /**
+ * Gets the ReplyMetadataReader that is set on this connection. This may
+ * be an uninitialized stdx::function, so it should be checked for validity
+ * with operator bool() first.
+ */
+ const rpc::ReplyMetadataReader& getReplyMetadataReader();
+
+ /**
+ * Runs a database command. This variant allows the caller to manually specify the metadata
+ * for the request, and receive it for the reply.
+ *
+ * TODO: rename this to runCommand, and change the old one to runCommandLegacy.
+ */
+ virtual rpc::UniqueReply runCommandWithMetadata(StringData database,
+ StringData command,
+ const BSONObj& metadata,
+ const BSONObj& commandArgs);
+
+ /** Run a database command. Database commands are represented as BSON objects. Common database
+ commands have prebuilt helper functions -- see below. If a helper is not available you can
+ directly call runCommand.
+
+ @param dbname database name. Use "admin" for global administrative commands.
+ @param cmd the command object to execute. For example, { ismaster : 1 }
+ @param info the result object the database returns. Typically has { ok : ..., errmsg : ... } fields
+ set.
+ @param options see enum QueryOptions - normally not needed to run a command
+ @param auth if set, the BSONObj representation will be appended to the command object sent
+
+ @return true if the command returned "ok".
+ */
+ virtual bool runCommand(const std::string& dbname,
+ const BSONObj& cmd,
+ BSONObj& info,
+ int options = 0);
+
+ /**
+ * Authenticate a user.
+ *
+ * The "params" BSONObj should be initialized with some of the fields below. Which fields
+ * are required depends on the mechanism, which is mandatory.
+ *
+ * "mechanism": The std::string name of the sasl mechanism to use. Mandatory.
+ * "user": The std::string name of the user to authenticate. Mandatory.
+ * "db": The database target of the auth command, which identifies the location
+ * of the credential information for the user. May be "$external" if
+ * credential information is stored outside of the mongo cluster. Mandatory.
+ * "pwd": The password data.
+ * "digestPassword": Boolean, set to true if the "pwd" is undigested (default).
+ * "serviceName": The GSSAPI service name to use. Defaults to "mongodb".
+ * "serviceHostname": The GSSAPI hostname to use. Defaults to the name of the remote
+ * host.
+ *
+ * Other fields in "params" are silently ignored.
+ *
+ * Returns normally on success, and throws on error. Throws a DBException with getCode() ==
+ * ErrorCodes::AuthenticationFailed if authentication is rejected. All other exceptions are
+ * tantamount to authentication failure, but may also indicate more serious problems.
+ */
+ void auth(const BSONObj& params);
+
+ /** Authorize access to a particular database.
+ Authentication is separate for each database on the server -- you may authenticate for any
+ number of databases on a single connection.
+ The "admin" database is special and once authenticated provides access to all databases on the
+ server.
+ @param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
+ @param[out] authLevel level of authentication for the given user
+ @return true if successful
+ */
+ bool auth(const std::string& dbname,
+ const std::string& username,
+ const std::string& pwd,
+ std::string& errmsg,
+ bool digestPassword = true);
- virtual void insert( const std::string &ns, const std::vector< BSONObj >& v , int flags=0) = 0;
+ /**
+ * Logs out the connection for the given database.
+ *
+ * @param dbname the database to logout from.
+ * @param info the result object for the logout command (provided for backwards
+ * compatibility with mongo shell)
+ */
+ virtual void logout(const std::string& dbname, BSONObj& info);
- virtual void remove( const std::string &ns , Query query, bool justOne = 0 ) = 0;
+ /** count number of objects in collection ns that match the query criteria specified
+ throws UserAssertion if database returns an error
+ */
+ virtual unsigned long long count(const std::string& ns,
+ const BSONObj& query = BSONObj(),
+ int options = 0,
+ int limit = 0,
+ int skip = 0);
- virtual void remove( const std::string &ns , Query query, int flags ) = 0;
+ static std::string createPasswordDigest(const std::string& username,
+ const std::string& clearTextPassword);
- virtual void update( const std::string &ns,
- Query query,
- BSONObj obj,
- bool upsert = false, bool multi = false ) = 0;
+ /** returns true in isMaster parm if this db is the current master
+ of a replica pair.
- virtual void update( const std::string &ns, Query query, BSONObj obj, int flags ) = 0;
+ pass in info for more details e.g.:
+ { "ismaster" : 1.0 , "msg" : "not paired" , "ok" : 1.0 }
- virtual ~DBClientInterface() { }
+ returns true if command invoked successfully.
+ */
+ virtual bool isMaster(bool& isMaster, BSONObj* info = 0);
- /**
- @return a single object that matches the query. if none do, then the object is empty
- @throws AssertionException
- */
- virtual BSONObj findOne(const std::string &ns, const Query& query, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
+ /**
+ Create a new collection in the database. Normally, collection creation is automatic. You would
+ use this function if you wish to specify special options on creation.
- /** query N objects from the database into an array. makes sense mostly when you want a small number of results. if a huge number, use
- query() and iterate the cursor.
- */
- void findN(std::vector<BSONObj>& out, const std::string &ns, Query query, int nToReturn, int nToSkip = 0, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
+ If the collection already exists, no action occurs.
- virtual std::string getServerAddress() const = 0;
+ @param ns fully qualified collection name
+ @param size desired initial extent size for the collection.
+ Must be <= 1000000000 for normal collections.
+ For fixed size (capped) collections, this size is the total/max size of the
+ collection.
+ @param capped if true, this is a fixed size collection (where old data rolls out).
+ @param max maximum number of objects if capped (optional).
- /** don't use this - called automatically by DBClientCursor for you */
- virtual std::unique_ptr<DBClientCursor> getMore( const std::string &ns, long long cursorId, int nToReturn = 0, int options = 0 ) = 0;
+ returns true if successful.
+ */
+ bool createCollection(const std::string& ns,
+ long long size = 0,
+ bool capped = false,
+ int max = 0,
+ BSONObj* info = 0);
+
+ /** Get error result from the last write operation (insert/update/delete) on this connection.
+ db doesn't change the command's behavior - it is just for auth checks.
+ @return error message text, or empty std::string if no error.
+ */
+ std::string getLastError(
+ const std::string& db, bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
+ /**
+ * Same as the form of getLastError that takes a dbname, but just uses the admin DB.
+ */
+ std::string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
- protected:
- DBClientInterface() = default;
- };
+ /** Get error result from the last write operation (insert/update/delete) on this connection.
+ db doesn't change the command's behavior - it is just for auth checks.
+ @return full error object.
+ If "w" is -1, wait for propagation to majority of nodes.
+ If "wtimeout" is 0, the operation will block indefinitely if needed.
+ */
+ virtual BSONObj getLastErrorDetailed(
+ const std::string& db, bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
/**
- DB "commands"
- Basically just invocations of connection.$cmd.findOne({...});
+ * Same as the form of getLastErrorDetailed that takes a dbname, but just uses the admin DB.
+ */
+ virtual BSONObj getLastErrorDetailed(bool fsync = false,
+ bool j = false,
+ int w = 0,
+ int wtimeout = 0);
+
+ /** Can be called with the returned value from getLastErrorDetailed to extract an error string.
+ If all you need is the string, just call getLastError() instead.
*/
- class DBClientWithCommands : public DBClientInterface, public DBConnector {
- public:
- /** controls how chatty the client is about network errors & such. See log.h */
- logger::LogSeverity _logLevel;
-
- DBClientWithCommands() : _logLevel(logger::LogSeverity::Log()),
- _cachedAvailableOptions( (enum QueryOptions)0 ),
- _haveCachedAvailableOptions(false) { }
-
- /** helper function. run a simple command where the command expression is simply
- { command : 1 }
- @param info -- where to put result object. may be null if caller doesn't need that info
- @param command -- command name
- @return true if the command returned "ok".
- */
- bool simpleCommand(const std::string &dbname, BSONObj *info, const std::string &command);
-
- rpc::ProtocolSet getClientRPCProtocols() const;
- rpc::ProtocolSet getServerRPCProtocols() const;
-
- void setClientRPCProtocols(rpc::ProtocolSet clientProtocols);
-
- /**
- * Sets a RequestMetadataWriter on this connection.
- *
- * TODO: support multiple metadata writers.
- */
- virtual void setRequestMetadataWriter(rpc::RequestMetadataWriter writer);
-
- /**
- * Gets the RequestMetadataWriter that is set on this connection. This may
- * be an uninitialized stdx::function, so it should be checked for validity
- * with operator bool() first.
- */
- const rpc::RequestMetadataWriter& getRequestMetadataWriter();
-
- /**
- * Sets a ReplyMetadataReader on this connection.
- *
- * TODO: support multiple metadata readers.
- */
- virtual void setReplyMetadataReader(rpc::ReplyMetadataReader reader);
-
- /**
- * Gets the ReplyMetadataReader that is set on this connection. This may
- * be an uninitialized stdx::function, so it should be checked for validity
- * with operator bool() first.
- */
- const rpc::ReplyMetadataReader& getReplyMetadataReader();
-
- /**
- * Runs a database command. This variant allows the caller to manually specify the metadata
- * for the request, and receive it for the reply.
- *
- * TODO: rename this to runCommand, and change the old one to runCommandLegacy.
- */
- virtual rpc::UniqueReply runCommandWithMetadata(StringData database,
- StringData command,
- const BSONObj& metadata,
- const BSONObj& commandArgs);
-
- /** Run a database command. Database commands are represented as BSON objects. Common database
- commands have prebuilt helper functions -- see below. If a helper is not available you can
- directly call runCommand.
-
- @param dbname database name. Use "admin" for global administrative commands.
- @param cmd the command object to execute. For example, { ismaster : 1 }
- @param info the result object the database returns. Typically has { ok : ..., errmsg : ... } fields
- set.
- @param options see enum QueryOptions - normally not needed to run a command
- @param auth if set, the BSONObj representation will be appended to the command object sent
-
- @return true if the command returned "ok".
- */
- virtual bool runCommand(const std::string &dbname, const BSONObj& cmd, BSONObj &info,
- int options=0);
-
- /**
- * Authenticate a user.
- *
- * The "params" BSONObj should be initialized with some of the fields below. Which fields
- * are required depends on the mechanism, which is mandatory.
- *
- * "mechanism": The std::string name of the sasl mechanism to use. Mandatory.
- * "user": The std::string name of the user to authenticate. Mandatory.
- * "db": The database target of the auth command, which identifies the location
- * of the credential information for the user. May be "$external" if
- * credential information is stored outside of the mongo cluster. Mandatory.
- * "pwd": The password data.
- * "digestPassword": Boolean, set to true if the "pwd" is undigested (default).
- * "serviceName": The GSSAPI service name to use. Defaults to "mongodb".
- * "serviceHostname": The GSSAPI hostname to use. Defaults to the name of the remote
- * host.
- *
- * Other fields in "params" are silently ignored.
- *
- * Returns normally on success, and throws on error. Throws a DBException with getCode() ==
- * ErrorCodes::AuthenticationFailed if authentication is rejected. All other exceptions are
- * tantamount to authentication failure, but may also indicate more serious problems.
- */
- void auth(const BSONObj& params);
-
- /** Authorize access to a particular database.
- Authentication is separate for each database on the server -- you may authenticate for any
- number of databases on a single connection.
- The "admin" database is special and once authenticated provides access to all databases on the
- server.
- @param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
- @param[out] authLevel level of authentication for the given user
- @return true if successful
- */
- bool auth(const std::string &dbname, const std::string &username, const std::string &pwd, std::string& errmsg, bool digestPassword = true);
-
- /**
- * Logs out the connection for the given database.
- *
- * @param dbname the database to logout from.
- * @param info the result object for the logout command (provided for backwards
- * compatibility with mongo shell)
- */
- virtual void logout(const std::string& dbname, BSONObj& info);
-
- /** count number of objects in collection ns that match the query criteria specified
- throws UserAssertion if database returns an error
- */
- virtual unsigned long long count(const std::string &ns, const BSONObj& query = BSONObj(), int options=0, int limit=0, int skip=0 );
-
- static std::string createPasswordDigest(const std::string &username, const std::string &clearTextPassword);
-
- /** returns true in isMaster parm if this db is the current master
- of a replica pair.
-
- pass in info for more details e.g.:
- { "ismaster" : 1.0 , "msg" : "not paired" , "ok" : 1.0 }
-
- returns true if command invoked successfully.
- */
- virtual bool isMaster(bool& isMaster, BSONObj *info=0);
-
- /**
- Create a new collection in the database. Normally, collection creation is automatic. You would
- use this function if you wish to specify special options on creation.
-
- If the collection already exists, no action occurs.
-
- @param ns fully qualified collection name
- @param size desired initial extent size for the collection.
- Must be <= 1000000000 for normal collections.
- For fixed size (capped) collections, this size is the total/max size of the
- collection.
- @param capped if true, this is a fixed size collection (where old data rolls out).
- @param max maximum number of objects if capped (optional).
-
- returns true if successful.
- */
- bool createCollection(const std::string &ns, long long size = 0, bool capped = false, int max = 0, BSONObj *info = 0);
-
- /** Get error result from the last write operation (insert/update/delete) on this connection.
- db doesn't change the command's behavior - it is just for auth checks.
- @return error message text, or empty std::string if no error.
- */
- std::string getLastError(const std::string& db,
- bool fsync = false,
- bool j = false,
- int w = 0,
- int wtimeout = 0);
- /**
- * Same as the form of getLastError that takes a dbname, but just uses the admin DB.
- */
- std::string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
-
- /** Get error result from the last write operation (insert/update/delete) on this connection.
- db doesn't change the command's behavior - it is just for auth checks.
- @return full error object.
-
- If "w" is -1, wait for propagation to majority of nodes.
- If "wtimeout" is 0, the operation will block indefinitely if needed.
- */
- virtual BSONObj getLastErrorDetailed(const std::string& db,
- bool fsync = false,
- bool j = false,
- int w = 0,
- int wtimeout = 0);
- /**
- * Same as the form of getLastErrorDetailed that takes a dbname, but just uses the admin DB.
- */
- virtual BSONObj getLastErrorDetailed(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
-
- /** Can be called with the returned value from getLastErrorDetailed to extract an error string.
- If all you need is the string, just call getLastError() instead.
- */
- static std::string getLastErrorString( const BSONObj& res );
-
- /** Return the last error which has occurred, even if not the very last operation.
-
- @return { err : <error message>, nPrev : <how_many_ops_back_occurred>, ok : 1 }
-
- result.err will be null if no error has occurred.
- */
- BSONObj getPrevError();
-
- /** Reset the previous error state for this connection (accessed via getLastError and
- getPrevError). Useful when performing several operations at once and then checking
- for an error after attempting all operations.
- */
- bool resetError() { return simpleCommand("admin", 0, "reseterror"); }
-
- /** Delete the specified collection.
- * @param info An optional output parameter that receives the result object the database
- * returns from the drop command. May be null if the caller doesn't need that info.
- */
- virtual bool dropCollection( const std::string &ns, BSONObj* info = NULL ) {
- std::string db = nsGetDB( ns );
- std::string coll = nsGetCollection( ns );
- uassert( 10011 , "no collection name", coll.size() );
-
- BSONObj temp;
- if ( info == NULL ) {
- info = &temp;
- }
-
- bool res = runCommand( db.c_str() , BSON( "drop" << coll ) , *info );
- return res;
- }
+ static std::string getLastErrorString(const BSONObj& res);
- /** Perform a repair and compaction of the specified database. May take a long time to run. Disk space
- must be available equal to the size of the database while repairing.
- */
- bool repairDatabase(const std::string &dbname, BSONObj *info = 0) {
- return simpleCommand(dbname, info, "repairDatabase");
- }
+ /** Return the last error which has occurred, even if not the very last operation.
- /** Copy database from one server or name to another server or name.
-
- Generally, you should dropDatabase() first as otherwise the copied information will MERGE
- into whatever data is already present in this database.
-
- For security reasons this function only works when you are authorized to access the "admin" db. However,
- if you have access to said db, you can copy any database from one place to another.
- TODO: this needs enhancement to be more flexible in terms of security.
-
- This method provides a way to "rename" a database by copying it to a new db name and
- location. The copy is "repaired" and compacted.
-
- fromdb database name from which to copy.
- todb database name to copy to.
- fromhost hostname of the database (and optionally, ":port") from which to
- copy the data. copies from self if "".
-
- returns true if successful
- */
- bool copyDatabase(const std::string &fromdb, const std::string &todb, const std::string &fromhost = "", BSONObj *info = 0);
-
- /** Run javascript code on the database server.
- dbname database SavedContext in which the code runs. The javascript variable 'db' will be assigned
- to this database when the function is invoked.
- jscode source code for a javascript function.
- info the command object which contains any information on the invocation result including
- the return value and other information. If an error occurs running the jscode, error
- information will be in info. (try "log() << info.toString()")
- retValue return value from the jscode function.
- args args to pass to the jscode function. when invoked, the 'args' variable will be defined
- for use by the jscode.
-
- returns true if runs ok.
-
- See testDbEval() in dbclient.cpp for an example of usage.
- */
- bool eval(const std::string &dbname, const std::string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0);
-
- /** validate a collection, checking for errors and reporting back statistics.
- this operation is slow and blocking.
- */
- bool validate( const std::string &ns , bool scandata=true ) {
- BSONObj cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
- BSONObj info;
- return runCommand( nsGetDB( ns ).c_str() , cmd , info );
- }
+ @return { err : <error message>, nPrev : <how_many_ops_back_occurred>, ok : 1 }
- /* The following helpers are simply more convenient forms of eval() for certain common cases */
-
- /* invocation with no return value of interest -- with or without one simple parameter */
- bool eval(const std::string &dbname, const std::string &jscode);
- template< class T >
- bool eval(const std::string &dbname, const std::string &jscode, T parm1) {
- BSONObj info;
- BSONElement retValue;
- BSONObjBuilder b;
- b.append("0", parm1);
- BSONObj args = b.done();
- return eval(dbname, jscode, info, retValue, &args);
- }
+ result.err will be null if no error has occurred.
+ */
+ BSONObj getPrevError();
- /** eval invocation with one parm to server and one numeric field (either int or double) returned */
- template< class T, class NumType >
- bool eval(const std::string &dbname, const std::string &jscode, T parm1, NumType& ret) {
- BSONObj info;
- BSONElement retValue;
- BSONObjBuilder b;
- b.append("0", parm1);
- BSONObj args = b.done();
- if ( !eval(dbname, jscode, info, retValue, &args) )
- return false;
- ret = (NumType) retValue.number();
- return true;
- }
+ /** Reset the previous error state for this connection (accessed via getLastError and
+ getPrevError). Useful when performing several operations at once and then checking
+ for an error after attempting all operations.
+ */
+ bool resetError() {
+ return simpleCommand("admin", 0, "reseterror");
+ }
- /**
- get a list of all the current databases
- uses the { listDatabases : 1 } command.
- throws on error
- */
- std::list<std::string> getDatabaseNames();
-
- /**
- * Get a list of all the current collections in db.
- * Returns fully qualified names.
- */
- std::list<std::string> getCollectionNames( const std::string& db );
-
- /**
- * { name : "<short collection name>",
- * options : { }
- * }
- */
- std::list<BSONObj> getCollectionInfos( const std::string& db,
- const BSONObj& filter = BSONObj() );
-
- bool exists( const std::string& ns );
-
- /** Create an index if it does not already exist.
- @param ns collection to be indexed
- @param keys the "key pattern" for the index. e.g., { name : 1 }
- @param unique if true, indicates that key uniqueness should be enforced for this index
- @param name if not specified, it will be created from the keys automatically (which is recommended)
- @param background build index in the background (see mongodb docs for details)
- @param v index version. leave at default value. (unit tests set this parameter.)
- @param ttl. The value of how many seconds before data should be removed from a collection.
- */
- virtual void ensureIndex( const std::string &ns,
- BSONObj keys,
- bool unique = false,
- const std::string &name = "",
- bool background = false,
- int v = -1,
- int ttl = 0 );
-
- virtual std::list<BSONObj> getIndexSpecs( const std::string &ns, int options = 0 );
-
- virtual void dropIndex( const std::string& ns , BSONObj keys );
- virtual void dropIndex( const std::string& ns , const std::string& indexName );
-
- /**
- drops all indexes for the collection
- */
- virtual void dropIndexes( const std::string& ns );
-
- virtual void reIndex( const std::string& ns );
-
- static std::string genIndexName( const BSONObj& keys );
-
- /** Erase / drop an entire database */
- virtual bool dropDatabase(const std::string &dbname, BSONObj *info = 0) {
- return simpleCommand(dbname, info, "dropDatabase");
+ /** Delete the specified collection.
+ * @param info An optional output parameter that receives the result object the database
+ * returns from the drop command. May be null if the caller doesn't need that info.
+ */
+ virtual bool dropCollection(const std::string& ns, BSONObj* info = NULL) {
+ std::string db = nsGetDB(ns);
+ std::string coll = nsGetCollection(ns);
+ uassert(10011, "no collection name", coll.size());
+
+ BSONObj temp;
+ if (info == NULL) {
+ info = &temp;
}
- virtual std::string toString() const = 0;
-
- /**
- * Run a pseudo-command such as sys.inprog/currentOp, sys.killop/killOp
- * or sys.unlock/fsyncUnlock
- *
- * The real command will be tried first, and if the remote server does not
- * implement the command, it will fall back to the pseudoCommand.
- *
- * The cmdArgs parameter should NOT include {<commandName>: 1}.
- *
- * TODO: remove after MongoDB 3.2 is released and replace all callers with
- * a call to plain runCommand
- */
- virtual bool runPseudoCommand(StringData db,
- StringData realCommandName,
- StringData pseudoCommandCol,
- const BSONObj& cmdArgs,
- BSONObj& info,
- int options=0);
-
- protected:
- /** if the result of a command is ok*/
- bool isOk(const BSONObj&);
-
- /** if the element contains a not master error */
- bool isNotMasterErrorString( const BSONElement& e );
-
- BSONObj _countCmd(const std::string &ns, const BSONObj& query, int options, int limit, int skip );
-
- /**
- * Look up the options available on this client. Caches the answer from
- * _lookupAvailableOptions(), below.
- */
- QueryOptions availableOptions();
-
- virtual QueryOptions _lookupAvailableOptions();
-
- virtual void _auth(const BSONObj& params);
-
- /**
- * Use the MONGODB-CR protocol to authenticate as "username" against the database "dbname",
- * with the given password. If digestPassword is false, the password is assumed to be
- * pre-digested. Returns false on failure, and sets "errmsg".
- */
- bool _authMongoCR(const std::string &dbname,
- const std::string &username,
- const std::string &pwd,
- BSONObj *info,
- bool digestPassword);
-
- /**
- * Use the MONGODB-X509 protocol to authenticate as "username. The certificate details
- * has already been communicated automatically as part of the connect call.
- * Returns false on failure and set "errmsg".
- */
- bool _authX509(const std::string &dbname,
- const std::string &username,
- BSONObj *info);
-
- // should be set by subclasses during connection.
- void _setServerRPCProtocols(rpc::ProtocolSet serverProtocols);
-
- private:
-
- /**
- * The rpc protocols this client supports.
- *
- * TODO: Change to rpc::supports::kAll once OP_COMMAND is implemented in
- * mongos (SERVER-18292).
- */
- rpc::ProtocolSet _clientRPCProtocols{rpc::supports::kOpQueryOnly};
-
- /**
- * The rpc protocol the remote server(s) support.
- *
- * TODO: implement proper detection of RPC protocol support when OP_COMMAND
- * is implemented in mongos (SERVER-18292).
- */
- rpc::ProtocolSet _serverRPCProtocols{rpc::supports::kAll};
-
- rpc::RequestMetadataWriter _metadataWriter;
- rpc::ReplyMetadataReader _metadataReader;
-
- enum QueryOptions _cachedAvailableOptions;
- bool _haveCachedAvailableOptions;
- };
+ bool res = runCommand(db.c_str(), BSON("drop" << coll), *info);
+ return res;
+ }
+
+ /** Perform a repair and compaction of the specified database. May take a long time to run. Disk space
+ must be available equal to the size of the database while repairing.
+ */
+ bool repairDatabase(const std::string& dbname, BSONObj* info = 0) {
+ return simpleCommand(dbname, info, "repairDatabase");
+ }
+
+ /** Copy database from one server or name to another server or name.
+
+ Generally, you should dropDatabase() first as otherwise the copied information will MERGE
+ into whatever data is already present in this database.
+
+ For security reasons this function only works when you are authorized to access the "admin" db. However,
+ if you have access to said db, you can copy any database from one place to another.
+ TODO: this needs enhancement to be more flexible in terms of security.
+
+ This method provides a way to "rename" a database by copying it to a new db name and
+ location. The copy is "repaired" and compacted.
+
+ fromdb database name from which to copy.
+ todb database name to copy to.
+ fromhost hostname of the database (and optionally, ":port") from which to
+ copy the data. copies from self if "".
+
+ returns true if successful
+ */
+ bool copyDatabase(const std::string& fromdb,
+ const std::string& todb,
+ const std::string& fromhost = "",
+ BSONObj* info = 0);
+
+ /** Run javascript code on the database server.
+ dbname database SavedContext in which the code runs. The javascript variable 'db' will be assigned
+ to this database when the function is invoked.
+ jscode source code for a javascript function.
+ info the command object which contains any information on the invocation result including
+ the return value and other information. If an error occurs running the jscode, error
+ information will be in info. (try "log() << info.toString()")
+ retValue return value from the jscode function.
+ args args to pass to the jscode function. when invoked, the 'args' variable will be defined
+ for use by the jscode.
+
+ returns true if runs ok.
+
+ See testDbEval() in dbclient.cpp for an example of usage.
+ */
+ bool eval(const std::string& dbname,
+ const std::string& jscode,
+ BSONObj& info,
+ BSONElement& retValue,
+ BSONObj* args = 0);
+
+ /** validate a collection, checking for errors and reporting back statistics.
+ this operation is slow and blocking.
+ */
+ bool validate(const std::string& ns, bool scandata = true) {
+ BSONObj cmd = BSON("validate" << nsGetCollection(ns) << "scandata" << scandata);
+ BSONObj info;
+ return runCommand(nsGetDB(ns).c_str(), cmd, info);
+ }
+
+ /* The following helpers are simply more convenient forms of eval() for certain common cases */
+
+ /* invocation with no return value of interest -- with or without one simple parameter */
+ bool eval(const std::string& dbname, const std::string& jscode);
+ template <class T>
+ bool eval(const std::string& dbname, const std::string& jscode, T parm1) {
+ BSONObj info;
+ BSONElement retValue;
+ BSONObjBuilder b;
+ b.append("0", parm1);
+ BSONObj args = b.done();
+ return eval(dbname, jscode, info, retValue, &args);
+ }
+
+ /** eval invocation with one parm to server and one numeric field (either int or double) returned */
+ template <class T, class NumType>
+ bool eval(const std::string& dbname, const std::string& jscode, T parm1, NumType& ret) {
+ BSONObj info;
+ BSONElement retValue;
+ BSONObjBuilder b;
+ b.append("0", parm1);
+ BSONObj args = b.done();
+ if (!eval(dbname, jscode, info, retValue, &args))
+ return false;
+ ret = (NumType)retValue.number();
+ return true;
+ }
/**
- abstract class that implements the core db operations
+ get a list of all the current databases
+ uses the { listDatabases : 1 } command.
+ throws on error
*/
- class DBClientBase : public DBClientWithCommands {
- protected:
- static AtomicInt64 ConnectionIdSequence;
- long long _connectionId; // unique connection id for this connection
- int _minWireVersion;
- int _maxWireVersion;
- public:
- static const uint64_t INVALID_SOCK_CREATION_TIME;
-
- DBClientBase() {
- _connectionId = ConnectionIdSequence.fetchAndAdd(1);
- _minWireVersion = _maxWireVersion = 0;
- }
+ std::list<std::string> getDatabaseNames();
- long long getConnectionId() const { return _connectionId; }
+ /**
+ * Get a list of all the current collections in db.
+ * Returns fully qualified names.
+ */
+ std::list<std::string> getCollectionNames(const std::string& db);
- void setWireVersions( int minWireVersion, int maxWireVersion ){
- _minWireVersion = minWireVersion;
- _maxWireVersion = maxWireVersion;
- }
+ /**
+ * { name : "<short collection name>",
+ * options : { }
+ * }
+ */
+ std::list<BSONObj> getCollectionInfos(const std::string& db, const BSONObj& filter = BSONObj());
+
+ bool exists(const std::string& ns);
+
+ /** Create an index if it does not already exist.
+ @param ns collection to be indexed
+ @param keys the "key pattern" for the index. e.g., { name : 1 }
+ @param unique if true, indicates that key uniqueness should be enforced for this index
+ @param name if not specified, it will be created from the keys automatically (which is recommended)
+ @param background build index in the background (see mongodb docs for details)
+ @param v index version. leave at default value. (unit tests set this parameter.)
+ @param ttl. The value of how many seconds before data should be removed from a collection.
+ */
+ virtual void ensureIndex(const std::string& ns,
+ BSONObj keys,
+ bool unique = false,
+ const std::string& name = "",
+ bool background = false,
+ int v = -1,
+ int ttl = 0);
+
+ virtual std::list<BSONObj> getIndexSpecs(const std::string& ns, int options = 0);
+
+ virtual void dropIndex(const std::string& ns, BSONObj keys);
+ virtual void dropIndex(const std::string& ns, const std::string& indexName);
+
+ /**
+ drops all indexes for the collection
+ */
+ virtual void dropIndexes(const std::string& ns);
+
+ virtual void reIndex(const std::string& ns);
+
+ static std::string genIndexName(const BSONObj& keys);
+
+ /** Erase / drop an entire database */
+ virtual bool dropDatabase(const std::string& dbname, BSONObj* info = 0) {
+ return simpleCommand(dbname, info, "dropDatabase");
+ }
+
+ virtual std::string toString() const = 0;
+
+ /**
+ * Run a pseudo-command such as sys.inprog/currentOp, sys.killop/killOp
+ * or sys.unlock/fsyncUnlock
+ *
+ * The real command will be tried first, and if the remote server does not
+ * implement the command, it will fall back to the pseudoCommand.
+ *
+ * The cmdArgs parameter should NOT include {<commandName>: 1}.
+ *
+ * TODO: remove after MongoDB 3.2 is released and replace all callers with
+ * a call to plain runCommand
+ */
+ virtual bool runPseudoCommand(StringData db,
+ StringData realCommandName,
+ StringData pseudoCommandCol,
+ const BSONObj& cmdArgs,
+ BSONObj& info,
+ int options = 0);
+
+protected:
+ /** if the result of a command is ok*/
+ bool isOk(const BSONObj&);
- int getMinWireVersion() { return _minWireVersion; }
- int getMaxWireVersion() { return _maxWireVersion; }
+ /** if the element contains a not master error */
+ bool isNotMasterErrorString(const BSONElement& e);
- /** send a query to the database.
- @param ns namespace to query, format is <dbname>.<collectname>[.<collectname>]*
- @param query query to perform on the collection. this is a BSONObj (binary JSON)
- You may format as
- { query: { ... }, orderby: { ... } }
- to specify a sort order.
- @param nToReturn n to return (i.e., limit). 0 = unlimited
- @param nToSkip start with the nth item
- @param fieldsToReturn optional template of which fields to select. if unspecified, returns all fields
- @param queryOptions see options enum at top of this file
+ BSONObj _countCmd(
+ const std::string& ns, const BSONObj& query, int options, int limit, int skip);
+
+ /**
+ * Look up the options available on this client. Caches the answer from
+ * _lookupAvailableOptions(), below.
+ */
+ QueryOptions availableOptions();
- @return cursor. 0 if error (connection failure)
- @throws AssertionException
- */
- virtual std::unique_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
- const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
+ virtual QueryOptions _lookupAvailableOptions();
+ virtual void _auth(const BSONObj& params);
- /** Uses QueryOption_Exhaust, when available.
+ /**
+ * Use the MONGODB-CR protocol to authenticate as "username" against the database "dbname",
+ * with the given password. If digestPassword is false, the password is assumed to be
+ * pre-digested. Returns false on failure, and sets "errmsg".
+ */
+ bool _authMongoCR(const std::string& dbname,
+ const std::string& username,
+ const std::string& pwd,
+ BSONObj* info,
+ bool digestPassword);
- Exhaust mode sends back all data queries as fast as possible, with no back-and-forth for
- OP_GETMORE. If you are certain you will exhaust the query, it could be useful.
+ /**
+ * Use the MONGODB-X509 protocol to authenticate as "username. The certificate details
+ * has already been communicated automatically as part of the connect call.
+ * Returns false on failure and set "errmsg".
+ */
+ bool _authX509(const std::string& dbname, const std::string& username, BSONObj* info);
- Use the DBClientCursorBatchIterator version, below, if you want to do items in large
- blocks, perhaps to avoid granular locking and such.
- */
- virtual unsigned long long query( stdx::function<void(const BSONObj&)> f,
- const std::string& ns,
- Query query,
- const BSONObj *fieldsToReturn = 0,
- int queryOptions = 0 );
+ // should be set by subclasses during connection.
+ void _setServerRPCProtocols(rpc::ProtocolSet serverProtocols);
- virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator&)> f,
- const std::string& ns,
- Query query,
- const BSONObj *fieldsToReturn = 0,
- int queryOptions = 0 );
+private:
+ /**
+ * The rpc protocols this client supports.
+ *
+ * TODO: Change to rpc::supports::kAll once OP_COMMAND is implemented in
+ * mongos (SERVER-18292).
+ */
+ rpc::ProtocolSet _clientRPCProtocols{rpc::supports::kOpQueryOnly};
+ /**
+ * The rpc protocol the remote server(s) support.
+ *
+ * TODO: implement proper detection of RPC protocol support when OP_COMMAND
+ * is implemented in mongos (SERVER-18292).
+ */
+ rpc::ProtocolSet _serverRPCProtocols{rpc::supports::kAll};
- /** don't use this - called automatically by DBClientCursor for you
- @param cursorId id of cursor to retrieve
- @return an handle to a previously allocated cursor
- @throws AssertionException
- */
- virtual std::unique_ptr<DBClientCursor> getMore( const std::string &ns, long long cursorId, int nToReturn = 0, int options = 0 );
+ rpc::RequestMetadataWriter _metadataWriter;
+ rpc::ReplyMetadataReader _metadataReader;
- /**
- insert an object into the database
- */
- virtual void insert( const std::string &ns , BSONObj obj , int flags=0);
+ enum QueryOptions _cachedAvailableOptions;
+ bool _haveCachedAvailableOptions;
+};
- /**
- insert a vector of objects into the database
- */
- virtual void insert( const std::string &ns, const std::vector< BSONObj >& v , int flags=0);
+/**
+ abstract class that implements the core db operations
+ */
+class DBClientBase : public DBClientWithCommands {
+protected:
+ static AtomicInt64 ConnectionIdSequence;
+ long long _connectionId; // unique connection id for this connection
+ int _minWireVersion;
+ int _maxWireVersion;
+
+public:
+ static const uint64_t INVALID_SOCK_CREATION_TIME;
+
+ DBClientBase() {
+ _connectionId = ConnectionIdSequence.fetchAndAdd(1);
+ _minWireVersion = _maxWireVersion = 0;
+ }
- /**
- updates objects matching query
- */
- virtual void update( const std::string &ns,
- Query query,
- BSONObj obj,
- bool upsert = false, bool multi = false );
+ long long getConnectionId() const {
+ return _connectionId;
+ }
- virtual void update( const std::string &ns, Query query, BSONObj obj, int flags );
+ void setWireVersions(int minWireVersion, int maxWireVersion) {
+ _minWireVersion = minWireVersion;
+ _maxWireVersion = maxWireVersion;
+ }
- /**
- remove matching objects from the database
- @param justOne if this true, then once a single match is found will stop
- */
- virtual void remove( const std::string &ns , Query q , bool justOne = 0 );
+ int getMinWireVersion() {
+ return _minWireVersion;
+ }
+ int getMaxWireVersion() {
+ return _maxWireVersion;
+ }
- virtual void remove( const std::string &ns , Query query, int flags );
+ /** send a query to the database.
+ @param ns namespace to query, format is <dbname>.<collectname>[.<collectname>]*
+ @param query query to perform on the collection. this is a BSONObj (binary JSON)
+ You may format as
+ { query: { ... }, orderby: { ... } }
+ to specify a sort order.
+ @param nToReturn n to return (i.e., limit). 0 = unlimited
+ @param nToSkip start with the nth item
+ @param fieldsToReturn optional template of which fields to select. if unspecified, returns all fields
+ @param queryOptions see options enum at top of this file
+
+ @return cursor. 0 if error (connection failure)
+ @throws AssertionException
+ */
+ virtual std::unique_ptr<DBClientCursor> query(const std::string& ns,
+ Query query,
+ int nToReturn = 0,
+ int nToSkip = 0,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0,
+ int batchSize = 0);
- virtual bool isFailed() const = 0;
- /**
- * if not checked recently, checks whether the underlying socket/sockets are still valid
- */
- virtual bool isStillConnected() = 0;
+ /** Uses QueryOption_Exhaust, when available.
- virtual void killCursor( long long cursorID ) = 0;
+ Exhaust mode sends back all data queries as fast as possible, with no back-and-forth for
+ OP_GETMORE. If you are certain you will exhaust the query, it could be useful.
- virtual bool callRead( Message& toSend , Message& response ) = 0;
+ Use the DBClientCursorBatchIterator version, below, if you want to do items in large
+ blocks, perhaps to avoid granular locking and such.
+ */
+ virtual unsigned long long query(stdx::function<void(const BSONObj&)> f,
+ const std::string& ns,
+ Query query,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0);
+
+ virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
+ const std::string& ns,
+ Query query,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0);
+
+
+ /** don't use this - called automatically by DBClientCursor for you
+ @param cursorId id of cursor to retrieve
+ @return an handle to a previously allocated cursor
+ @throws AssertionException
+ */
+ virtual std::unique_ptr<DBClientCursor> getMore(const std::string& ns,
+ long long cursorId,
+ int nToReturn = 0,
+ int options = 0);
- virtual ConnectionString::ConnectionType type() const = 0;
+ /**
+ insert an object into the database
+ */
+ virtual void insert(const std::string& ns, BSONObj obj, int flags = 0);
- virtual double getSoTimeout() const = 0;
+ /**
+ insert a vector of objects into the database
+ */
+ virtual void insert(const std::string& ns, const std::vector<BSONObj>& v, int flags = 0);
- virtual uint64_t getSockCreationMicroSec() const {
- return INVALID_SOCK_CREATION_TIME;
- }
+ /**
+ updates objects matching query
+ */
+ virtual void update(
+ const std::string& ns, Query query, BSONObj obj, bool upsert = false, bool multi = false);
+
+ virtual void update(const std::string& ns, Query query, BSONObj obj, int flags);
+
+ /**
+ remove matching objects from the database
+ @param justOne if this true, then once a single match is found will stop
+ */
+ virtual void remove(const std::string& ns, Query q, bool justOne = 0);
+
+ virtual void remove(const std::string& ns, Query query, int flags);
+
+ virtual bool isFailed() const = 0;
+
+ /**
+ * if not checked recently, checks whether the underlying socket/sockets are still valid
+ */
+ virtual bool isStillConnected() = 0;
+
+ virtual void killCursor(long long cursorID) = 0;
+
+ virtual bool callRead(Message& toSend, Message& response) = 0;
+
+ virtual ConnectionString::ConnectionType type() const = 0;
+
+ virtual double getSoTimeout() const = 0;
+
+ virtual uint64_t getSockCreationMicroSec() const {
+ return INVALID_SOCK_CREATION_TIME;
+ }
+
+ virtual void reset() {}
- virtual void reset() {}
+}; // DBClientBase
- }; // DBClientBase
+class ConnectException : public UserException {
+public:
+ ConnectException(std::string msg) : UserException(9000, msg) {}
+};
- class ConnectException : public UserException {
- public:
- ConnectException(std::string msg) : UserException(9000,msg) { }
- };
+/**
+ A basic connection to the database.
+ This is the main entry point for talking to a simple Mongo setup
+*/
+class DBClientConnection : public DBClientBase {
+public:
+ using DBClientBase::query;
/**
- A basic connection to the database.
- This is the main entry point for talking to a simple Mongo setup
+ @param _autoReconnect if true, automatically reconnect on a connection failure
+ @param timeout tcp timeout in seconds - this is for read/write, not connect.
+ Connect timeout is fixed, but short, at 5 seconds.
+ */
+ DBClientConnection(bool _autoReconnect = false, double so_timeout = 0);
+
+ virtual ~DBClientConnection() {
+ _numConnections.fetchAndAdd(-1);
+ }
+
+ /** Connect to a Mongo database server.
+
+ If autoReconnect is true, you can try to use the DBClientConnection even when
+ false was returned -- it will try to connect again.
+
+ @param server server to connect to.
+ @param errmsg any relevant error message will appended to the string
+ @return false if fails to connect.
*/
- class DBClientConnection : public DBClientBase {
- public:
- using DBClientBase::query;
-
- /**
- @param _autoReconnect if true, automatically reconnect on a connection failure
- @param timeout tcp timeout in seconds - this is for read/write, not connect.
- Connect timeout is fixed, but short, at 5 seconds.
- */
- DBClientConnection(bool _autoReconnect = false, double so_timeout = 0);
-
- virtual ~DBClientConnection() {
- _numConnections.fetchAndAdd(-1);
- }
+ virtual bool connect(const HostAndPort& server, std::string& errmsg);
- /** Connect to a Mongo database server.
+ /** Connect to a Mongo database server. Exception throwing version.
+ Throws a UserException if cannot connect.
- If autoReconnect is true, you can try to use the DBClientConnection even when
- false was returned -- it will try to connect again.
+ If autoReconnect is true, you can try to use the DBClientConnection even when
+ false was returned -- it will try to connect again.
- @param server server to connect to.
- @param errmsg any relevant error message will appended to the string
- @return false if fails to connect.
- */
- virtual bool connect(const HostAndPort& server, std::string& errmsg);
+ @param serverHostname host to connect to. can include port number ( 127.0.0.1 , 127.0.0.1:5555 )
+ */
+ void connect(const std::string& serverHostname) {
+ std::string errmsg;
+ if (!connect(HostAndPort(serverHostname), errmsg))
+ throw ConnectException(std::string("can't connect ") + errmsg);
+ }
- /** Connect to a Mongo database server. Exception throwing version.
- Throws a UserException if cannot connect.
+ /**
+ * Logs out the connection for the given database.
+ *
+ * @param dbname the database to logout from.
+ * @param info the result object for the logout command (provided for backwards
+ * compatibility with mongo shell)
+ */
+ virtual void logout(const std::string& dbname, BSONObj& info);
+
+ virtual std::unique_ptr<DBClientCursor> query(const std::string& ns,
+ Query query = Query(),
+ int nToReturn = 0,
+ int nToSkip = 0,
+ const BSONObj* fieldsToReturn = 0,
+ int queryOptions = 0,
+ int batchSize = 0) {
+ checkConnection();
+ return DBClientBase::query(
+ ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions, batchSize);
+ }
- If autoReconnect is true, you can try to use the DBClientConnection even when
- false was returned -- it will try to connect again.
+ virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
+ const std::string& ns,
+ Query query,
+ const BSONObj* fieldsToReturn,
+ int queryOptions);
- @param serverHostname host to connect to. can include port number ( 127.0.0.1 , 127.0.0.1:5555 )
- */
- void connect(const std::string& serverHostname) {
- std::string errmsg;
- if( !connect(HostAndPort(serverHostname), errmsg) )
- throw ConnectException(std::string("can't connect ") + errmsg);
- }
+ virtual bool runCommand(const std::string& dbname,
+ const BSONObj& cmd,
+ BSONObj& info,
+ int options = 0);
- /**
- * Logs out the connection for the given database.
- *
- * @param dbname the database to logout from.
- * @param info the result object for the logout command (provided for backwards
- * compatibility with mongo shell)
- */
- virtual void logout(const std::string& dbname, BSONObj& info);
-
- virtual std::unique_ptr<DBClientCursor> query(const std::string &ns, Query query=Query(), int nToReturn = 0, int nToSkip = 0,
- const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 ) {
- checkConnection();
- return DBClientBase::query( ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions , batchSize );
- }
+ /**
+ @return true if this connection is currently in a failed state. When autoreconnect is on,
+ a connection will transition back to an ok state after reconnecting.
+ */
+ bool isFailed() const {
+ return _failed;
+ }
- virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator &)> f,
- const std::string& ns,
- Query query,
- const BSONObj *fieldsToReturn,
- int queryOptions );
-
- virtual bool runCommand(const std::string &dbname,
- const BSONObj& cmd,
- BSONObj &info,
- int options=0);
-
- /**
- @return true if this connection is currently in a failed state. When autoreconnect is on,
- a connection will transition back to an ok state after reconnecting.
- */
- bool isFailed() const { return _failed; }
-
- bool isStillConnected() { return p ? p->isStillConnected() : true; }
-
- MessagingPort& port() { verify(p); return *p; }
-
- std::string toString() const {
- std::stringstream ss;
- ss << _serverString;
- if ( !_serverAddrString.empty() ) ss << " (" << _serverAddrString << ")";
- if ( _failed ) ss << " failed";
- return ss.str();
- }
+ bool isStillConnected() {
+ return p ? p->isStillConnected() : true;
+ }
+
+ MessagingPort& port() {
+ verify(p);
+ return *p;
+ }
- std::string getServerAddress() const { return _serverString; }
- const HostAndPort& getServerHostAndPort() const { return _server; }
+ std::string toString() const {
+ std::stringstream ss;
+ ss << _serverString;
+ if (!_serverAddrString.empty())
+ ss << " (" << _serverAddrString << ")";
+ if (_failed)
+ ss << " failed";
+ return ss.str();
+ }
- virtual void killCursor( long long cursorID );
- virtual bool callRead( Message& toSend , Message& response ) { return call( toSend , response ); }
- virtual void say( Message &toSend, bool isRetry = false , std::string * actualServer = 0 );
- virtual bool recv( Message& m );
- virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, std::string* host = NULL );
- virtual bool call( Message &toSend, Message &response, bool assertOk = true , std::string * actualServer = 0 );
- virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
- void setSoTimeout(double timeout);
- double getSoTimeout() const { return _so_timeout; }
+ std::string getServerAddress() const {
+ return _serverString;
+ }
+ const HostAndPort& getServerHostAndPort() const {
+ return _server;
+ }
- virtual bool lazySupported() const { return true; }
+ virtual void killCursor(long long cursorID);
+ virtual bool callRead(Message& toSend, Message& response) {
+ return call(toSend, response);
+ }
+ virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0);
+ virtual bool recv(Message& m);
+ virtual void checkResponse(const char* data,
+ int nReturned,
+ bool* retry = NULL,
+ std::string* host = NULL);
+ virtual bool call(Message& toSend,
+ Message& response,
+ bool assertOk = true,
+ std::string* actualServer = 0);
+ virtual ConnectionString::ConnectionType type() const {
+ return ConnectionString::MASTER;
+ }
+ void setSoTimeout(double timeout);
+ double getSoTimeout() const {
+ return _so_timeout;
+ }
- static int getNumConnections() {
- return _numConnections.load();
- }
+ virtual bool lazySupported() const {
+ return true;
+ }
- /**
- * Set the name of the replica set that this connection is associated to.
- * Note: There is no validation on replSetName.
- */
- void setParentReplSetName(const std::string& replSetName);
-
- static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy; }
- static bool getLazyKillCursor() { return _lazyKillCursor; }
-
- uint64_t getSockCreationMicroSec() const;
-
- protected:
- friend class SyncClusterConnection;
- virtual void _auth(const BSONObj& params);
- virtual void sayPiggyBack( Message &toSend );
-
- std::unique_ptr<MessagingPort> p;
- std::unique_ptr<SockAddr> server;
- bool _failed;
- const bool autoReconnect;
- Backoff autoReconnectBackoff;
- HostAndPort _server; // remember for reconnects
- std::string _serverString; // server host and port
- std::string _serverAddrString; // resolved ip of server
- void _checkConnection();
-
- // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
- void checkConnection() { if( _failed ) _checkConnection(); }
-
- std::map<std::string, BSONObj> authCache;
- double _so_timeout;
- bool _connect( std::string& errmsg );
-
- static AtomicInt32 _numConnections;
- static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
-
- private:
-
- /**
- * Checks the BSONElement for the 'not master' keyword and if it does exist,
- * try to inform the replica set monitor that the host this connects to is
- * no longer primary.
- */
- void handleNotMasterResponse(const BSONElement& elemToCheck);
-
- // Contains the string for the replica set name of the host this is connected to.
- // Should be empty if this connection is not pointing to a replica set member.
- std::string _parentReplSetName;
- };
-
- BSONElement getErrField( const BSONObj& result );
- bool hasErrField( const BSONObj& result );
-
- inline std::ostream& operator<<( std::ostream &s, const Query &q ) {
- return s << q.toString();
+ static int getNumConnections() {
+ return _numConnections.load();
}
- void assembleQueryRequest(const std::string &ns,
- BSONObj query,
- int nToReturn,
- int nToSkip,
- const BSONObj *fieldsToReturn,
- int queryOptions,
- Message &toSend);
+ /**
+ * Set the name of the replica set that this connection is associated to.
+ * Note: There is no validation on replSetName.
+ */
+ void setParentReplSetName(const std::string& replSetName);
+
+ static void setLazyKillCursor(bool lazy) {
+ _lazyKillCursor = lazy;
+ }
+ static bool getLazyKillCursor() {
+ return _lazyKillCursor;
+ }
+
+ uint64_t getSockCreationMicroSec() const;
+
+protected:
+ friend class SyncClusterConnection;
+ virtual void _auth(const BSONObj& params);
+ virtual void sayPiggyBack(Message& toSend);
+
+ std::unique_ptr<MessagingPort> p;
+ std::unique_ptr<SockAddr> server;
+ bool _failed;
+ const bool autoReconnect;
+ Backoff autoReconnectBackoff;
+ HostAndPort _server; // remember for reconnects
+ std::string _serverString; // server host and port
+ std::string _serverAddrString; // resolved ip of server
+ void _checkConnection();
+
+ // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
+ void checkConnection() {
+ if (_failed)
+ _checkConnection();
+ }
+
+ std::map<std::string, BSONObj> authCache;
+ double _so_timeout;
+ bool _connect(std::string& errmsg);
+
+ static AtomicInt32 _numConnections;
+ static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
+
+private:
+ /**
+ * Checks the BSONElement for the 'not master' keyword and if it does exist,
+ * try to inform the replica set monitor that the host this connects to is
+ * no longer primary.
+ */
+ void handleNotMasterResponse(const BSONElement& elemToCheck);
+
+ // Contains the string for the replica set name of the host this is connected to.
+ // Should be empty if this connection is not pointing to a replica set member.
+ std::string _parentReplSetName;
+};
+
+BSONElement getErrField(const BSONObj& result);
+bool hasErrField(const BSONObj& result);
+
+inline std::ostream& operator<<(std::ostream& s, const Query& q) {
+ return s << q.toString();
+}
+
+void assembleQueryRequest(const std::string& ns,
+ BSONObj query,
+ int nToReturn,
+ int nToSkip,
+ const BSONObj* fieldsToReturn,
+ int queryOptions,
+ Message& toSend);
-} // namespace mongo
+} // namespace mongo
#include "mongo/client/dbclientcursor.h"