MongoDB C++ Driver  legacy-1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dbclientinterface.h
Go to the documentation of this file.
1 
6 /* Copyright 2009 10gen Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #pragma once
22 
23 #include <boost/thread/locks.hpp>
24 #include <boost/thread/mutex.hpp>
25 
26 #include "mongo/config.h"
27 
28 #include "mongo/base/string_data.h"
29 #include "mongo/client/bulk_operation_builder.h"
30 #include "mongo/client/exceptions.h"
31 #include "mongo/client/export_macros.h"
32 #include "mongo/client/index_spec.h"
33 #include "mongo/client/write_concern.h"
34 #include "mongo/client/write_options.h"
35 #include "mongo/db/jsobj.h"
36 #include "mongo/logger/log_severity.h"
37 #include "mongo/platform/atomic_word.h"
38 #include "mongo/stdx/functional.h"
39 #include "mongo/util/mongoutils/str.h"
40 #include "mongo/util/net/message.h"
41 #include "mongo/util/net/message_port.h"
42 
43 namespace mongo {
44 
46  enum MONGO_CLIENT_API QueryOptions {
56 
60 
61  // findingStart mode is used to find the first operation of interest when
62  // we are scanning through a repl log. For efficiency in the common case,
63  // where the first operation of interest is closer to the tail than the head,
64  // we start from the tail of the log and work backwards until we find the
65  // first operation of interest. Then we scan forward from that first operation,
66  // actually returning results to the client. During the findingStart phase,
67  // we release the db mutex occasionally to avoid blocking the db process for
68  // an extended period of time.
69  QueryOption_OplogReplay = 1 << 3,
70 
75 
80 
89 
95 
96  QueryOption_AllSupported = QueryOption_CursorTailable |
98  QueryOption_OplogReplay |
103  };
104 
108  enum MONGO_CLIENT_API WriteOptions {
110  WriteOption_FromWriteback = 1 << 31
111  };
112 
113  //
114  // For legacy reasons, the reserved field pre-namespace of certain types of messages is used
115  // to store options as opposed to the flags after the namespace. This should be transparent to
116  // the api user, but we need these constants to disassemble/reassemble the messages correctly.
117  //
118 
119  enum MONGO_CLIENT_API ReservedOptions {
120  Reserved_InsertOption_ContinueOnError = 1 << 0 ,
121  Reserved_FromWriteback = 1 << 1
122  };
123 
124  enum MONGO_CLIENT_API ReadPreference {
131 
139 
144 
149 
154  };
155 
156  class MONGO_CLIENT_API DBClientBase;
157  class MONGO_CLIENT_API DBClientConnection;
158 
187  class MONGO_CLIENT_API ConnectionString {
188  public:
189 
190  enum ConnectionType { INVALID , MASTER , PAIR , SET , CUSTOM };
191 
192  ConnectionString() {
193  _type = INVALID;
194  }
195 
196  // Note: This should only be used for direct connections to a single server. For replica
197  // set and SyncClusterConnections, use ConnectionString::parse.
198  ConnectionString( const HostAndPort& server ) {
199  _type = MASTER;
200  _servers.push_back( server );
201  _finishInit();
202  }
203 
204  ConnectionString( ConnectionType type , const std::string& s , const std::string& setName = "" ) {
205  _type = type;
206  _setName = setName;
207  _fillServers( s );
208 
209  switch ( _type ) {
210  case MASTER:
211  verify( _servers.size() == 1 );
212  break;
213  case SET:
214  verify( _setName.size() );
215  verify( _servers.size() >= 1 ); // 1 is ok since we can derive
216  break;
217  case PAIR:
218  verify( _servers.size() == 2 );
219  break;
220  default:
221  verify( _servers.size() > 0 );
222  }
223 
224  _finishInit();
225  }
226 
227  ConnectionString( const std::string& s , ConnectionType favoredMultipleType ) {
228  _type = INVALID;
229 
230  _fillServers( s );
231  if ( _type != INVALID ) {
232  // set already
233  }
234  else if ( _servers.size() == 1 ) {
235  _type = MASTER;
236  }
237  else {
238  _type = favoredMultipleType;
239  verify( _type == SET );
240  }
241  _finishInit();
242  }
243 
244  bool isValid() const { return _type != INVALID; }
245 
246  std::string toString() const { return _string; }
247 
248  DBClientBase* connect( std::string& errmsg, double socketTimeout = 0 ) const;
249 
250  std::string getSetName() const { return _setName; }
251 
252  const std::vector<HostAndPort>& getServers() const { return _servers; }
253 
254  ConnectionType type() const { return _type; }
255 
256  const std::string& getUser() const { return _user; }
257 
258  const std::string& getPassword() const { return _password; }
259 
260  const BSONObj& getOptions() const { return _options; }
261 
262  const std::string& getDatabase() const { return _database; }
263 
270  bool sameLogicalEndpoint( const ConnectionString& other ) const;
271 
272  static ConnectionString MONGO_CLIENT_FUNC parse( const std::string& address , std::string& errmsg );
273 
274  static ConnectionString MONGO_CLIENT_FUNC parseDeprecated( const std::string& address , std::string& errmsg );
275 
276  static std::string MONGO_CLIENT_FUNC typeToString( ConnectionType type );
277 
278  //
279  // Allow overriding the default connection behavior
280  // This is needed for some tests, which otherwise would fail because they are unable to contact
281  // the correct servers.
282  //
283 
285  public:
286  virtual ~ConnectionHook(){}
287 
288  // Returns an alternative connection object for a string
289  virtual DBClientBase* connect( const ConnectionString& c,
290  std::string& errmsg,
291  double socketTimeout ) = 0;
292  };
293 
294  static void setConnectionHook( ConnectionHook* hook ){
295  boost::lock_guard<boost::mutex> lk( _connectHookMutex );
296  _connectHook = hook;
297  }
298 
299  static ConnectionHook* getConnectionHook() {
300  boost::lock_guard<boost::mutex> lk( _connectHookMutex );
301  return _connectHook;
302  }
303 
304  // Allows ConnectionStrings to be stored more easily in sets/maps
305  bool operator<(const ConnectionString& other) const {
306  return _string < other._string;
307  }
308 
309  //
310  // FOR TESTING ONLY - useful to be able to directly mock a connection string without
311  // including the entire client library.
312  //
313 
314  static ConnectionString mock( const HostAndPort& server ) {
315  ConnectionString connStr;
316  connStr._servers.push_back( server );
317  connStr._string = server.toString();
318  return connStr;
319  }
320 
321  private:
322  ConnectionString( ConnectionType type,
323  const std::string& user,
324  const std::string& password,
325  const std::string& servers,
326  const std::string& database,
327  const std::string& setName,
328  const BSONObj& options )
329  : _type( type )
330  , _servers( )
331  , _setName( setName )
332  , _user( user )
333  , _password( password )
334  , _database( database )
335  , _options( options ) {
336 
337  _fillServers( servers, false );
338  switch ( _type ) {
339  case MASTER:
340  verify( _servers.size() == 1 );
341  break;
342  case SET:
343  verify( _setName.size() );
344  verify( _servers.size() >= 1 ); // 1 is ok since we can derive
345  break;
346  case PAIR:
347  verify( _servers.size() == 2 );
348  break;
349  default:
350  verify( _servers.size() > 0 );
351  }
352 
353  _finishInit();
354  }
355 
356  static ConnectionString _parseURL( const std::string& url, std::string& errmsg );
357 
358  void _fillServers( std::string s, bool legacy = true );
359  void _finishInit();
360 
361  BSONObj _makeAuthObjFromOptions(int maxWireVersion) const;
362 
363  ConnectionType _type;
364  std::vector<HostAndPort> _servers;
365  std::string _string;
366  std::string _setName;
367 
368  std::string _user;
369  std::string _password;
370 
371  std::string _database;
372  BSONObj _options;
373 
374  static boost::mutex _connectHookMutex;
375  static ConnectionHook* _connectHook;
376  };
377 
378  class BSONObj;
379  class DBClientCursor;
380  class DBClientCursorBatchIterator;
381 
387  class MONGO_CLIENT_API Query {
388  public:
389  static const BSONField<BSONObj> ReadPrefField;
390  static const BSONField<std::string> ReadPrefModeField;
391  static const BSONField<BSONArray> ReadPrefTagsField;
392 
393  BSONObj obj;
394  Query() : obj(BSONObj()) { }
395  Query(const BSONObj& b) : obj(b) { }
396  Query(const std::string &json);
397  Query(const char * json);
398 
407  Query& sort(const BSONObj& sortPattern);
408 
414  Query& sort(const std::string &field, int asc = 1) { sort( BSON( field << asc ) ); return *this; }
415 
421  Query& hint(BSONObj keyPattern);
422  Query& hint(const std::string& indexName);
423 
428  Query& maxTimeMs(int millis);
429 
433  Query& minKey(const BSONObj &val);
437  Query& maxKey(const BSONObj &val);
438 
442  Query& explain();
443 
452  Query& snapshot();
453 
470  Query& where(const std::string &jscode, BSONObj scope);
471  Query& where(const std::string &jscode) { return where(jscode, BSONObj()); }
472 
479  Query& readPref(ReadPreference pref, const BSONArray& tags);
480 
484  bool isComplex( bool * hasDollar = 0 ) const;
485  BSONObj getModifiers() const;
486  static bool MONGO_CLIENT_FUNC isComplex(const BSONObj& obj, bool* hasDollar = 0);
487 
488  BSONObj getFilter() const;
489  BSONObj getSort() const;
490  BSONElement getHint() const;
491  BSONObj getReadPref() const;
492  int getMaxTimeMs() const;
493  bool isExplain() const;
494 
498  static bool MONGO_CLIENT_FUNC hasReadPreference(const BSONObj& queryObj);
499  bool hasReadPreference() const;
500  bool hasHint() const;
501  bool hasMaxTimeMs() const;
502 
503  std::string toString() const;
504  operator std::string() const { return toString(); }
505  private:
506  void makeComplex();
507  template< class T >
508  void appendComplex( const char *fieldName, const T& val ) {
509  makeComplex();
510  BSONObjBuilder b;
511  b.appendElements(obj);
512  b.append(fieldName, val);
513  obj = b.obj();
514  }
515  };
516 
521  class MONGO_CLIENT_API QuerySpec {
522 
523  std::string _ns;
524  int _ntoskip;
525  int _ntoreturn;
526  int _options;
527  BSONObj _query;
528  BSONObj _fields;
529  Query _queryObj;
530 
531  public:
532 
533  QuerySpec( const std::string& ns,
534  const BSONObj& query, const BSONObj& fields,
535  int ntoskip, int ntoreturn, int options )
536  : _ns( ns ), _ntoskip( ntoskip ), _ntoreturn( ntoreturn ), _options( options ),
537  _query( query.getOwned() ), _fields( fields.getOwned() ) , _queryObj( _query ) {
538  }
539 
540  QuerySpec() {}
541 
542  bool isEmpty() const { return _ns.size() == 0; }
543 
544  bool isExplain() const { return _queryObj.isExplain(); }
545  BSONObj filter() const { return _queryObj.getFilter(); }
546 
547  BSONElement hint() const { return _queryObj.getHint(); }
548  BSONObj sort() const { return _queryObj.getSort(); }
549  BSONObj query() const { return _query; }
550  BSONObj fields() const { return _fields; }
551  BSONObj* fieldsData() { return &_fields; }
552 
553  // don't love this, but needed downstrem
554  const BSONObj* fieldsPtr() const { return &_fields; }
555 
556  std::string ns() const { return _ns; }
557  int ntoskip() const { return _ntoskip; }
558  int ntoreturn() const { return _ntoreturn; }
559  int options() const { return _options; }
560 
561  void setFields( BSONObj& o ) { _fields = o.getOwned(); }
562 
563  std::string toString() const {
564  return str::stream() << "QSpec " <<
565  BSON( "ns" << _ns << "n2skip" << _ntoskip << "n2return" << _ntoreturn << "options" << _options
566  << "query" << _query << "fields" << _fields );
567  }
568 
569  };
570 
571 
575 #define MONGO_QUERY(x) ::mongo::Query( BSON(x) )
576 
577  // Useful utilities for namespaces
579  MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetDB( const std::string &ns );
580 
582  MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetCollection( const std::string &ns );
583 
587  class MONGO_CLIENT_API DBConnector {
588  public:
589  virtual ~DBConnector() {}
591  virtual bool call( Message &toSend, Message &response, bool assertOk=true , std::string * actualServer = 0 ) = 0;
592  virtual void say( Message &toSend, bool isRetry = false , std::string * actualServer = 0 ) = 0;
593  virtual void sayPiggyBack( Message &toSend ) = 0;
594  /* used by QueryOption_Exhaust. To use that your subclass must implement this. */
595  virtual bool recv( Message& m ) { verify(false); return false; }
596  // In general, for lazy queries, we'll need to say, recv, then checkResponse
597  virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, std::string* targetHost = NULL ) {
598  if( retry ) *retry = false; if( targetHost ) *targetHost = "";
599  }
600  virtual bool lazySupported() const = 0;
601  };
602 
606  class MONGO_CLIENT_API DBClientInterface : boost::noncopyable {
607  public:
608  virtual std::auto_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
609  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 ) = 0;
610 
611  virtual void insert( const std::string &ns, BSONObj obj , int flags=0, const WriteConcern* wc=NULL ) = 0;
612 
613  virtual void insert( const std::string &ns, const std::vector< BSONObj >& v , int flags=0, const WriteConcern* wc=NULL ) = 0;
614 
615  virtual void remove( const std::string &ns, Query query, bool justOne = false, const WriteConcern* wc=NULL ) = 0;
616 
617  virtual void remove( const std::string &ns, Query query, int flags, const WriteConcern* wc=NULL ) = 0;
618 
619  virtual void update( const std::string &ns,
620  Query query,
621  BSONObj obj,
622  bool upsert = false, bool multi = false, const WriteConcern* wc=NULL ) = 0;
623 
624  virtual void update( const std::string &ns, Query query, BSONObj obj, int flags, const WriteConcern* wc=NULL ) = 0;
625 
626  virtual ~DBClientInterface() { }
627 
632  virtual BSONObj findOne(const std::string &ns, const Query& query, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
633 
637  void findN(std::vector<BSONObj>& out, const std::string&ns, Query query, int nToReturn, int nToSkip = 0, const BSONObj *fieldsToReturn = 0, int queryOptions = 0, int batchSize = 0);
638 
650  void save(const StringData& ns, const BSONObj& toSave, const WriteConcern* wc = NULL);
651 
652  virtual std::string getServerAddress() const = 0;
653 
655  virtual std::auto_ptr<DBClientCursor> getMore( const std::string &ns, long long cursorId, int nToReturn = 0, int options = 0 ) = 0;
656  };
657 
662  class MONGO_CLIENT_API DBClientWithCommands : public DBClientInterface {
663  public:
665  logger::LogSeverity _logLevel;
666 
667  DBClientWithCommands() : _logLevel(logger::LogSeverity::Log()),
668  _minWireVersion(0),
669  _maxWireVersion(0),
670  _cachedAvailableOptions( (enum QueryOptions)0 ),
671  _haveCachedAvailableOptions(false) { }
672 
679  bool simpleCommand(const std::string &dbname, BSONObj *info, const std::string &command);
680 
694  virtual bool runCommand(const std::string &dbname, const BSONObj& cmd, BSONObj &info,
695  int options=0);
696 
720  void auth(const BSONObj& params);
721 
729  bool auth(const std::string &dbname, const std::string &username, const std::string &pwd, std::string& errmsg, bool digestPassword = true);
730 
738  virtual void logout(const std::string& dbname, BSONObj& info);
739 
743  virtual unsigned long long count(const std::string &ns, const Query& query = Query(), int options=0, int limit=0, int skip=0 );
744 
745  static std::string MONGO_CLIENT_FUNC createPasswordDigest(const std::string &username, const std::string &clearTextPassword);
746 
755  virtual bool isMaster(bool& isMaster, BSONObj *info=0);
756 
773  bool createCollection(
774  const std::string &ns,
775  long long size = 0,
776  bool capped = false,
777  int max = 0,
778  BSONObj *info = 0
779  );
780 
797  bool createCollectionWithOptions(
798  const std::string &ns,
799  long long size = 0,
800  bool capped = false,
801  int max = 0,
802  const BSONObj& extraOptions = BSONObj(),
803  BSONObj *info = 0
804  );
805 
810  std::string getLastError(const std::string& db,
811  bool fsync = false,
812  bool j = false,
813  int w = 0,
814  int wtimeout = 0);
818  std::string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
819 
827  virtual BSONObj getLastErrorDetailed(const std::string& db,
828  bool fsync = false,
829  bool j = false,
830  int w = 0,
831  int wtimeout = 0);
835  virtual BSONObj getLastErrorDetailed(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
836 
840  static std::string MONGO_CLIENT_FUNC getLastErrorString( const BSONObj& res );
841 
848  BSONObj getPrevError();
849 
854  bool resetError() { return simpleCommand("admin", 0, "reseterror"); }
855 
860  virtual bool dropCollection( const std::string &ns, BSONObj* info = NULL ) {
861  std::string db = nsGetDB( ns );
862  std::string coll = nsGetCollection( ns );
863  uassert( 10011 , "no collection name", coll.size() );
864 
865  BSONObj temp;
866  if ( info == NULL ) {
867  info = &temp;
868  }
869 
870  bool res = runCommand( db.c_str() , BSON( "drop" << coll ) , *info );
871  return res;
872  }
873 
877  bool repairDatabase(const std::string &dbname, BSONObj *info = 0) {
878  return simpleCommand(dbname, info, "repairDatabase");
879  }
880 
900  bool copyDatabase(const std::string& fromdb,
901  const std::string& todb,
902  const std::string& fromhost = "",
903  const std::string& mechanism = "DEFAULT",
904  const std::string& username = "",
905  const std::string& password = "",
906  BSONObj *info = 0);
907 
913  ProfileOff = 0,
914  ProfileSlow = 1, // log very slow (>100ms) operations
915  ProfileAll = 2
916 
917  };
918  bool setDbProfilingLevel(const std::string &dbname, ProfilingLevel level, BSONObj *info = 0);
919  bool getDbProfilingLevel(const std::string &dbname, ProfilingLevel& level, BSONObj *info = 0);
920 
921 
925  struct MROutput {
926  MROutput(const char* collection) : out(BSON("replace" << collection)) {}
927  MROutput(const std::string& collection) : out(BSON("replace" << collection)) {}
928  MROutput(const BSONObj& obj) : out(obj) {}
929 
930  BSONObj out;
931  };
932  static MROutput MRInline;
933 
957  BSONObj mapreduce(
958  const std::string &ns,
959  const std::string &jsmapf,
960  const std::string &jsreducef,
961  Query query = Query(),
962  MROutput output = MRInline
963  );
964 
985  void group(
986  const StringData& ns,
987  const StringData& jsreduce,
988  std::vector<BSONObj>* output,
989  const BSONObj& initial = BSONObj(),
990  const Query& query = Query(),
991  const BSONObj& key = BSONObj(),
992  const StringData& finalize = ""
993  );
994 
1002  void groupWithKeyFunction(
1003  const StringData& ns,
1004  const StringData& jsreduce,
1005  std::vector<BSONObj>* output,
1006  const BSONObj& initial = BSONObj(),
1007  const Query& query = Query(),
1008  const StringData& jskey = "",
1009  const StringData& finalize = ""
1010  );
1011 
1022  BSONObj distinct(
1023  const StringData& ns,
1024  const StringData& field,
1025  const Query& query = Query()
1026  );
1027 
1041  BSONObj findAndModify(
1042  const StringData& ns,
1043  const BSONObj& query,
1044  const BSONObj& update,
1045  bool upsert = false,
1046  bool returnNew = false,
1047  const BSONObj& sort = BSONObj(),
1048  const BSONObj& fields = BSONObj()
1049  );
1050 
1061  BSONObj findAndRemove(
1062  const StringData& ns,
1063  const BSONObj& query,
1064  const BSONObj& sort = BSONObj(),
1065  const BSONObj& fields = BSONObj()
1066  );
1067 
1083  bool eval(const std::string &dbname, const std::string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0);
1084 
1088  bool validate( const std::string &ns , bool scandata=true ) {
1089  BSONObj cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
1090  BSONObj info;
1091  return runCommand( nsGetDB( ns ).c_str() , cmd , info );
1092  }
1093 
1094  /* The following helpers are simply more convenient forms of eval() for certain common cases */
1095 
1096  /* invocation with no return value of interest -- with or without one simple parameter */
1097  bool eval(const std::string &dbname, const std::string &jscode);
1098  template< class T >
1099  bool eval(const std::string &dbname, const std::string &jscode, T parm1) {
1100  BSONObj info;
1101  BSONElement retValue;
1102  BSONObjBuilder b;
1103  b.append("0", parm1);
1104  BSONObj args = b.done();
1105  return eval(dbname, jscode, info, retValue, &args);
1106  }
1107 
1109  template< class T, class NumType >
1110  bool eval(const std::string &dbname, const std::string &jscode, T parm1, NumType& ret) {
1111  BSONObj info;
1112  BSONElement retValue;
1113  BSONObjBuilder b;
1114  b.append("0", parm1);
1115  BSONObj args = b.done();
1116  if ( !eval(dbname, jscode, info, retValue, &args) )
1117  return false;
1118  ret = (NumType) retValue.number();
1119  return true;
1120  }
1121 
1127  std::list<std::string> getDatabaseNames();
1128 
1132  std::list<std::string> getCollectionNames( const std::string& db,
1133  const BSONObj& filter = BSONObj() );
1139  std::list<BSONObj> getCollectionInfos( const std::string& db,
1140  const BSONObj& filter = BSONObj() );
1141 
1153  std::auto_ptr<DBClientCursor> enumerateCollections( const std::string& db,
1154  const BSONObj& filter = BSONObj(),
1155  int batchSize = 0 );
1156 
1157  bool exists( const std::string& ns );
1158 
1168  void createIndex( const StringData& ns, const BSONObj& keys ) {
1169  return createIndex( ns, IndexSpec().addKeys(keys) );
1170  }
1171 
1180  virtual void createIndex( const StringData& ns, const IndexSpec& descriptor );
1181 
1182  virtual std::list<BSONObj> getIndexSpecs( const std::string &ns, int options = 0 );
1183 
1187  virtual std::list<std::string> getIndexNames( const std::string& ns, int options = 0 );
1188 
1189  virtual std::auto_ptr<DBClientCursor> enumerateIndexes( const std::string& ns,
1190  int options = 0,
1191  int batchSize = 0 );
1192 
1193  virtual void dropIndex( const std::string& ns , BSONObj keys );
1194  virtual void dropIndex( const std::string& ns , const std::string& indexName );
1195 
1199  virtual void dropIndexes( const std::string& ns );
1200 
1201  virtual void reIndex( const std::string& ns );
1202 
1203  static std::string genIndexName( const BSONObj& keys );
1204 
1206  virtual bool dropDatabase(const std::string &dbname, BSONObj *info = 0) {
1207  bool ret = simpleCommand(dbname, info, "dropDatabase");
1208  return ret;
1209  }
1210 
1211  virtual std::string toString() const = 0;
1212 
1220  typedef stdx::function<void(BSONObjBuilder*)> RunCommandHookFunc;
1221  virtual void setRunCommandHook(RunCommandHookFunc func);
1222  RunCommandHookFunc getRunCommandHook() const {
1223  return _runCommandHook;
1224  }
1225 
1230  typedef stdx::function<void(const BSONObj&, const std::string&)> PostRunCommandHookFunc;
1231  virtual void setPostRunCommandHook(PostRunCommandHookFunc func);
1232  PostRunCommandHookFunc getPostRunCommandHook() const {
1233  return _postRunCommandHook;
1234  }
1235 
1236 
1237  protected:
1239  bool isOk(const BSONObj&);
1240 
1242  bool isNotMasterErrorString( const BSONElement& e );
1243 
1244  BSONObj _countCmd(const std::string &ns, const Query& query, int options, int limit, int skip );
1245 
1250  QueryOptions availableOptions();
1251 
1252  virtual QueryOptions _lookupAvailableOptions();
1253 
1254  virtual void _auth(const BSONObj& params);
1255 
1261  bool _authMongoCR(const std::string &dbname,
1262  const std::string &username,
1263  const std::string &pwd,
1264  BSONObj *info,
1265  bool digestPassword);
1266 
1272  bool _authX509(const std::string &dbname,
1273  const std::string &username,
1274  BSONObj *info);
1275 
1279  RunCommandHookFunc _runCommandHook;
1280  PostRunCommandHookFunc _postRunCommandHook;
1281  int _minWireVersion;
1282  int _maxWireVersion;
1283 
1284 
1285  private:
1286  enum QueryOptions _cachedAvailableOptions;
1287  bool _haveCachedAvailableOptions;
1288 
1289  void _buildGroupObj(
1290  const StringData& ns,
1291  const StringData& jsreduce,
1292  const BSONObj& initial,
1293  const Query& query,
1294  const StringData& finalize,
1295  BSONObjBuilder* groupObj
1296  );
1297 
1298  void _runGroup(
1299  const StringData& ns,
1300  const BSONObj& group,
1301  const Query& query,
1302  std::vector<BSONObj>* output
1303  );
1304 
1305  void _findAndModify(
1306  const StringData& ns,
1307  const BSONObj& query,
1308  const BSONObj& update,
1309  const BSONObj& sort,
1310  bool returnNew,
1311  bool upsert,
1312  const BSONObj& fields,
1313  BSONObjBuilder* out
1314  );
1315 
1316  std::auto_ptr<DBClientCursor> _legacyCollectionInfo(
1317  const std::string& db,
1318  const BSONObj& filter,
1319  int batchSize
1320  );
1321  };
1322 
1323  class DBClientWriter;
1324  class WriteOperation;
1325 
1329  class MONGO_CLIENT_API DBClientBase : public DBClientWithCommands, public DBConnector {
1330  friend class BulkOperationBuilder;
1331  protected:
1332  static AtomicInt64 ConnectionIdSequence;
1333  long long _connectionId; // unique connection id for this connection
1334  const boost::scoped_ptr<DBClientWriter> _wireProtocolWriter;
1335  const boost::scoped_ptr<DBClientWriter> _commandWriter;
1336  WriteConcern _writeConcern;
1337  int _maxBsonObjectSize;
1338  int _maxMessageSizeBytes;
1339  int _maxWriteBatchSize;
1340  void _write(
1341  const std::string& ns,
1342  const std::vector<WriteOperation*>& writes,
1343  bool ordered,
1344  const WriteConcern* writeConcern,
1345  WriteResult* writeResult
1346  );
1347  public:
1348  static const uint64_t INVALID_SOCK_CREATION_TIME;
1349 
1350  DBClientBase();
1351 
1352  // Required because compiler can't generate a destructor for the _writer
1353  // as it is an incomplete type.
1354  virtual ~DBClientBase();
1355 
1356  long long getConnectionId() const { return _connectionId; }
1357 
1358  const WriteConcern& getWriteConcern() const { return _writeConcern; }
1359  void setWriteConcern( const WriteConcern& w ) { _writeConcern = w; }
1360 
1361  void setWireVersions( int minWireVersion, int maxWireVersion ){
1362  _minWireVersion = minWireVersion;
1363  _maxWireVersion = maxWireVersion;
1364  }
1365 
1366  int getMinWireVersion() { return _minWireVersion; }
1367  int getMaxWireVersion() { return _maxWireVersion; }
1368  int getMaxBsonObjectSize() { return _maxBsonObjectSize; }
1369  int getMaxMessageSizeBytes() { return _maxMessageSizeBytes; }
1370  int getMaxWriteBatchSize() { return _maxWriteBatchSize; }
1371 
1386  virtual std::auto_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
1387  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
1388 
1408  virtual void parallelScan(
1409  const StringData& ns,
1410  int numCursors,
1411  std::vector<DBClientCursor*>* cursors,
1412  stdx::function<DBClientBase* ()> connectionFactory
1413  );
1414 
1415  virtual std::auto_ptr<DBClientCursor> aggregate(const std::string& ns,
1416  const BSONObj& pipeline,
1417  const BSONObj* aggregateOptions = NULL,
1418  int queryOptions = 0);
1419 
1420 
1429  virtual unsigned long long query( stdx::function<void(const BSONObj&)> f,
1430  const std::string& ns,
1431  Query query,
1432  const BSONObj *fieldsToReturn = 0,
1433  int queryOptions = 0 );
1434 
1435  virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator&)> f,
1436  const std::string& ns,
1437  Query query,
1438  const BSONObj *fieldsToReturn = 0,
1439  int queryOptions = 0 );
1440 
1441 
1447  virtual std::auto_ptr<DBClientCursor> getMore( const std::string &ns, long long cursorId, int nToReturn = 0, int options = 0 );
1448 
1452  virtual void insert(
1453  const std::string &ns,
1454  BSONObj obj,
1455  int flags=0,
1456  const WriteConcern* wc=NULL
1457  );
1458 
1462  virtual void insert(
1463  const std::string &ns,
1464  const std::vector< BSONObj >& v,
1465  int flags=0,
1466  const WriteConcern* wc=NULL
1467  );
1468 
1472  virtual void update(
1473  const std::string &ns,
1474  Query query,
1475  BSONObj obj,
1476  bool upsert=false,
1477  bool multi=false,
1478  const WriteConcern* wc=NULL
1479  );
1480 
1481  virtual void update(
1482  const std::string &ns,
1483  Query query,
1484  BSONObj obj,
1485  int flags,
1486  const WriteConcern* wc=NULL
1487  );
1488 
1496  virtual BulkOperationBuilder initializeUnorderedBulkOp(const std::string& ns);
1497 
1505  virtual BulkOperationBuilder initializeOrderedBulkOp(const std::string& ns);
1506 
1511  virtual void remove( const std::string &ns , Query q , bool justOne = 0, const WriteConcern* wc=NULL );
1512 
1513  virtual void remove( const std::string &ns , Query query, int flags, const WriteConcern* wc=NULL );
1514 
1515  virtual bool isFailed() const = 0;
1516 
1520  virtual bool isStillConnected() = 0;
1521 
1522  virtual void killCursor( long long cursorID ) = 0;
1523 
1524  virtual bool callRead( Message& toSend , Message& response ) = 0;
1525  // virtual bool callWrite( Message& toSend , Message& response ) = 0; // TODO: add this if needed
1526 
1527  virtual ConnectionString::ConnectionType type() const = 0;
1528 
1529  virtual double getSoTimeout() const = 0;
1530 
1531  virtual uint64_t getSockCreationMicroSec() const {
1532  return INVALID_SOCK_CREATION_TIME;
1533  }
1534 
1535  virtual void reset() {}
1536 
1537  }; // DBClientBase
1538 
1539  class DBClientReplicaSet;
1540 
1541  class MONGO_CLIENT_API ConnectException : public UserException {
1542  public:
1543  ConnectException(std::string msg) : UserException(9000,msg) { }
1544  };
1545 
1550  class MONGO_CLIENT_API DBClientConnection : public DBClientBase {
1551  public:
1552  using DBClientBase::query;
1553 
1560  DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet* cp=0, double so_timeout=0) :
1561  clientSet(cp), _failed(false), autoReconnect(_autoReconnect), autoReconnectBackoff(1000, 2000), _so_timeout(so_timeout) {
1562  _numConnections.fetchAndAdd(1);
1563  }
1564 
1565  virtual ~DBClientConnection() {
1566  _numConnections.fetchAndAdd(-1);
1567  }
1568 
1578  virtual bool connect(const HostAndPort& server, std::string& errmsg);
1579 
1581  bool connect(const std::string& server, std::string& errmsg) {
1582  return connect(HostAndPort(server), errmsg);
1583  }
1584 
1593  void connect(const std::string& serverHostname) {
1594  std::string errmsg;
1595  if( !connect(HostAndPort(serverHostname), errmsg) )
1596  throw ConnectException(std::string("can't connect ") + errmsg);
1597  }
1598 
1606  virtual void logout(const std::string& dbname, BSONObj& info);
1607 
1608  virtual std::auto_ptr<DBClientCursor> query(const std::string &ns, Query query=Query(), int nToReturn = 0, int nToSkip = 0,
1609  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
1610 
1611  virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator &)> f,
1612  const std::string& ns,
1613  Query query,
1614  const BSONObj *fieldsToReturn,
1615  int queryOptions );
1616 
1617  virtual bool runCommand(const std::string &dbname,
1618  const BSONObj& cmd,
1619  BSONObj &info,
1620  int options=0);
1621 
1626  bool isFailed() const { return _failed; }
1627 
1628  bool isStillConnected() { return p ? p->isStillConnected() : true; }
1629 
1630  MessagingPort& port() { verify(p); return *p; }
1631 
1632  std::string toString() const {
1633  std::stringstream ss;
1634  ss << _serverString;
1635  if ( !_serverAddrString.empty() ) ss << " (" << _serverAddrString << ")";
1636  if ( _failed ) ss << " failed";
1637  return ss.str();
1638  }
1639 
1640  std::string getServerAddress() const { return _serverString; }
1641  const HostAndPort& getServerHostAndPort() const { return _server; }
1642 
1643  virtual void killCursor( long long cursorID );
1644  virtual bool callRead( Message& toSend , Message& response ) { return call( toSend , response ); }
1645  virtual void say( Message &toSend, bool isRetry = false , std::string * actualServer = 0 );
1646  virtual bool recv( Message& m );
1647  virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, std::string* host = NULL );
1648  virtual bool call( Message &toSend, Message &response, bool assertOk = true , std::string * actualServer = 0 );
1649  virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
1650  void setSoTimeout(double timeout);
1651  double getSoTimeout() const { return _so_timeout; }
1652 
1653  virtual bool lazySupported() const { return true; }
1654 
1655  static int MONGO_CLIENT_FUNC getNumConnections() {
1656  return _numConnections.load();
1657  }
1658 
1669  void setReplSetClientCallback(DBClientReplicaSet* rsClient);
1670 
1671  static void MONGO_CLIENT_FUNC setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy; }
1672  static bool MONGO_CLIENT_FUNC getLazyKillCursor() { return _lazyKillCursor; }
1673 
1674  uint64_t getSockCreationMicroSec() const;
1675 
1676  protected:
1677  virtual void _auth(const BSONObj& params);
1678  virtual void sayPiggyBack( Message &toSend );
1679 
1680  DBClientReplicaSet *clientSet;
1681  boost::scoped_ptr<MessagingPort> p;
1682  boost::scoped_ptr<SockAddr> server;
1683  bool _failed;
1684  const bool autoReconnect;
1685  Backoff autoReconnectBackoff;
1686  HostAndPort _server; // remember for reconnects
1687  std::string _serverString; // server host and port
1688  std::string _serverAddrString; // resolved ip of server
1689  void _checkConnection();
1690 
1691  // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
1692  void checkConnection() { if( _failed ) _checkConnection(); }
1693 
1694  std::map<std::string, BSONObj> authCache;
1695  double _so_timeout;
1696  bool _connect( std::string& errmsg );
1697 
1698  static AtomicInt32 _numConnections;
1699  static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
1700 
1701 #ifdef MONGO_SSL
1702  SSLManagerInterface* sslManager();
1703 #endif
1704  };
1705 
1708  MONGO_CLIENT_API bool MONGO_CLIENT_FUNC serverAlive( const std::string &uri );
1709 
1710  MONGO_CLIENT_API BSONElement MONGO_CLIENT_FUNC getErrField( const BSONObj& result );
1711  MONGO_CLIENT_API bool MONGO_CLIENT_FUNC hasErrField( const BSONObj& result );
1712 
1713  MONGO_CLIENT_API inline std::ostream& MONGO_CLIENT_FUNC operator<<( std::ostream &s, const Query &q ) {
1714  return s << q.toString();
1715  }
1716 
1717 } // namespace mongo
std::string createPasswordDigest(const StringData &username, const StringData &clearTextPassword)
Hashes the password so that it can be stored in a user object or used for MONGODB-CR authentication...
Definition: bson_field.h:73
Represents a single server side write operation and encapsulates the process for encoding the operati...
Definition: write_operation.h:31
DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet *cp=0, double so_timeout=0)
Definition: dbclientinterface.h:1560
DB "commands" Basically just invocations of connection.
Definition: dbclientinterface.h:662
MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetDB(const std::string &ns)
bool eval(const std::string &dbname, const std::string &jscode, T parm1, NumType &ret)
eval invocation with one parm to server and one numeric field (either int or double) returned ...
Definition: dbclientinterface.h:1110
Definition: message.h:298
QueryOption_SlaveOk
allow query of replica slave.
Definition: dbclientinterface.h:59
the main MongoDB namespace
Definition: bulk_operation_builder.h:24
the idea here is to make one liners easy.
Definition: str.h:44
Class for constructing and executing bulk operations against MongoDB via a fluent API...
Definition: bulk_operation_builder.h:54
QueryOption_Exhaust
Stream the data down full blast in multiple "more" packages, on the assumption that the client will f...
Definition: dbclientinterface.h:88
BSON classes.
This implicitly converts from char*, string, and BSONObj to be an argument to mapreduce You shouldn't...
Definition: dbclientinterface.h:925
ReadPreference_SecondaryOnly
Read from secondary if available, otherwise error.
Definition: dbclientinterface.h:130
ReadPreference_SecondaryPreferred
Read from a secondary if available, otherwise read from the primary.
Definition: dbclientinterface.h:130
bool repairDatabase(const std::string &dbname, BSONObj *info=0)
Perform a repair and compaction of the specified database.
Definition: dbclientinterface.h:877
MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetCollection(const std::string &ns)
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:109
virtual bool dropCollection(const std::string &ns, BSONObj *info=NULL)
Delete the specified collection.
Definition: dbclientinterface.h:860
Represents a full query description, including all options required for the query to be passed on to ...
Definition: dbclientinterface.h:521
stdx::function< void(const BSONObj &, const std::string &)> PostRunCommandHookFunc
Similar to above, but for running a function on a command response after a command has been run...
Definition: dbclientinterface.h:1230
void createIndex(const StringData &ns, const BSONObj &keys)
Create an index on the collection 'ns' as described by the given keys.
Definition: dbclientinterface.h:1168
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:49
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:580
BSONObj getOwned() const
assure the data buffer is under the control of this BSONObj and not a remote buffer ...
virtual bool dropDatabase(const std::string &dbname, BSONObj *info=0)
Erase / drop an entire database.
Definition: dbclientinterface.h:1206
Class representing the result of a write operations sent to the server.
Definition: write_result.h:33
A basic connection to the database.
Definition: dbclientinterface.h:1550
QueryOption_PartialResults
When sharded, this means its ok to return partial results Usually we will fail a query if all require...
Definition: dbclientinterface.h:94
bool connect(const std::string &server, std::string &errmsg)
Compatibility connect now that HostAndPort has an explicit constructor.
Definition: dbclientinterface.h:1581
Use this class to connect to a replica set of servers.
Definition: dbclient_rs.h:42
ConnectionString can parse MongoDB URIs with the following format:
Definition: dbclientinterface.h:187
bool isFailed() const
Definition: dbclientinterface.h:1626
QueryOption_NoCursorTimeout
The server normally times out idle cursors after an inactivity period to prevent excess memory uses S...
Definition: dbclientinterface.h:74
logger::LogSeverity _logLevel
controls how chatty the client is about network errors & such.
Definition: dbclientinterface.h:665
Class to encapsulate client side "Write Concern" concept.
Definition: write_concern.h:35
void connect(const std::string &serverHostname)
Connect to a Mongo database server.
Definition: dbclientinterface.h:1593
Definition: assert_util.h:130
iterate over objects in current batch only - will not cause a network call
Definition: dbclientcursor.h:229
ReadPreference_PrimaryOnly
Read from primary only.
Definition: dbclientinterface.h:130
Name of a process on the network.
Definition: hostandport.h:36
MONGO_CLIENT_API bool MONGO_CLIENT_FUNC serverAlive(const std::string &uri)
pings server to check if it's up
stdx::function< void(BSONObjBuilder *)> RunCommandHookFunc
A function type for runCommand hooking; the function takes a pointer to a BSONObjBuilder and returns ...
Definition: dbclientinterface.h:1220
The interface that any db connection should implement.
Definition: dbclientinterface.h:606
bool validate(const std::string &ns, bool scandata=true)
validate a collection, checking for errors and reporting back statistics.
Definition: dbclientinterface.h:1088
double number() const
Retrieve the numeric value of the element.
Definition: bsonelement.h:236
Definition: dbclient_writer.h:27
Definition: dbclientinterface.h:1541
QueryOption_AwaitData
Use with QueryOption_CursorTailable.
Definition: dbclientinterface.h:79
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
virtual std::auto_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)
send a query to the database.
Represents a Mongo query expression.
Definition: dbclientinterface.h:387
ReadPreference_Nearest
Read from any member.
Definition: dbclientinterface.h:130
abstract class that implements the core db operations
Definition: dbclientinterface.h:1329
Definition: index_spec.h:29
bool resetError()
Reset the previous error state for this connection (accessed via getLastError and getPrevError)...
Definition: dbclientinterface.h:854
bool isStillConnected()
if not checked recently, checks whether the underlying socket/sockets are still valid ...
Definition: dbclientinterface.h:1628
RunCommandHookFunc _runCommandHook
These functions will be executed by the driver on runCommand calls.
Definition: dbclientinterface.h:1279
ReadPreference_PrimaryPreferred
Read from primary if available, otherwise a secondary.
Definition: dbclientinterface.h:130
ProfilingLevel
The Mongo database provides built-in performance profiling capabilities.
Definition: dbclientinterface.h:912
Query & sort(const std::string &field, int asc=1)
Add a sort (ORDER BY) criteria to the query expression.
Definition: dbclientinterface.h:414
interface that handles communication with the db
Definition: dbclientinterface.h:587
Definition: dbclientinterface.h:284
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:55
Definition: message_port.h:68