MongoDB C++ Driver  legacy-1.0.5
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 
1084  bool eval(const std::string &dbname, const std::string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0, bool nolock = false);
1085 
1089  bool validate( const std::string &ns , bool scandata=true ) {
1090  BSONObj cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
1091  BSONObj info;
1092  return runCommand( nsGetDB( ns ).c_str() , cmd , info );
1093  }
1094 
1095  /* The following helpers are simply more convenient forms of eval() for certain common cases */
1096 
1097  /* invocation with no return value of interest -- with or without one simple parameter */
1098  bool eval(const std::string &dbname, const std::string &jscode);
1099  template< class T >
1100  bool eval(const std::string &dbname, const std::string &jscode, T parm1) {
1101  BSONObj info;
1102  BSONElement retValue;
1103  BSONObjBuilder b;
1104  b.append("0", parm1);
1105  BSONObj args = b.done();
1106  return eval(dbname, jscode, info, retValue, &args);
1107  }
1108 
1110  template< class T, class NumType >
1111  bool eval(const std::string &dbname, const std::string &jscode, T parm1, NumType& ret) {
1112  BSONObj info;
1113  BSONElement retValue;
1114  BSONObjBuilder b;
1115  b.append("0", parm1);
1116  BSONObj args = b.done();
1117  if ( !eval(dbname, jscode, info, retValue, &args) )
1118  return false;
1119  ret = (NumType) retValue.number();
1120  return true;
1121  }
1122 
1128  std::list<std::string> getDatabaseNames();
1129 
1133  std::list<std::string> getCollectionNames( const std::string& db,
1134  const BSONObj& filter = BSONObj() );
1140  std::list<BSONObj> getCollectionInfos( const std::string& db,
1141  const BSONObj& filter = BSONObj() );
1142 
1154  std::auto_ptr<DBClientCursor> enumerateCollections( const std::string& db,
1155  const BSONObj& filter = BSONObj(),
1156  int batchSize = 0 );
1157 
1158  bool exists( const std::string& ns );
1159 
1169  void createIndex( const StringData& ns, const BSONObj& keys ) {
1170  return createIndex( ns, IndexSpec().addKeys(keys) );
1171  }
1172 
1181  virtual void createIndex( const StringData& ns, const IndexSpec& descriptor );
1182 
1183  virtual std::list<BSONObj> getIndexSpecs( const std::string &ns, int options = 0 );
1184 
1188  virtual std::list<std::string> getIndexNames( const std::string& ns, int options = 0 );
1189 
1190  virtual std::auto_ptr<DBClientCursor> enumerateIndexes( const std::string& ns,
1191  int options = 0,
1192  int batchSize = 0 );
1193 
1194  virtual void dropIndex( const std::string& ns , BSONObj keys );
1195  virtual void dropIndex( const std::string& ns , const std::string& indexName );
1196 
1200  virtual void dropIndexes( const std::string& ns );
1201 
1202  virtual void reIndex( const std::string& ns );
1203 
1204  static std::string genIndexName( const BSONObj& keys );
1205 
1207  virtual bool dropDatabase(const std::string &dbname, BSONObj *info = 0) {
1208  bool ret = simpleCommand(dbname, info, "dropDatabase");
1209  return ret;
1210  }
1211 
1212  virtual std::string toString() const = 0;
1213 
1221  typedef stdx::function<void(BSONObjBuilder*)> RunCommandHookFunc;
1222  virtual void setRunCommandHook(RunCommandHookFunc func);
1223  RunCommandHookFunc getRunCommandHook() const {
1224  return _runCommandHook;
1225  }
1226 
1231  typedef stdx::function<void(const BSONObj&, const std::string&)> PostRunCommandHookFunc;
1232  virtual void setPostRunCommandHook(PostRunCommandHookFunc func);
1233  PostRunCommandHookFunc getPostRunCommandHook() const {
1234  return _postRunCommandHook;
1235  }
1236 
1237 
1238  protected:
1240  bool isOk(const BSONObj&);
1241 
1243  bool isNotMasterErrorString( const BSONElement& e );
1244 
1245  BSONObj _countCmd(const std::string &ns, const Query& query, int options, int limit, int skip );
1246 
1251  QueryOptions availableOptions();
1252 
1253  virtual QueryOptions _lookupAvailableOptions();
1254 
1255  virtual void _auth(const BSONObj& params);
1256 
1262  bool _authMongoCR(const std::string &dbname,
1263  const std::string &username,
1264  const std::string &pwd,
1265  BSONObj *info,
1266  bool digestPassword);
1267 
1273  bool _authX509(const std::string &dbname,
1274  const std::string &username,
1275  BSONObj *info);
1276 
1280  RunCommandHookFunc _runCommandHook;
1281  PostRunCommandHookFunc _postRunCommandHook;
1282  int _minWireVersion;
1283  int _maxWireVersion;
1284 
1285 
1286  private:
1287  enum QueryOptions _cachedAvailableOptions;
1288  bool _haveCachedAvailableOptions;
1289 
1290  void _buildGroupObj(
1291  const StringData& ns,
1292  const StringData& jsreduce,
1293  const BSONObj& initial,
1294  const Query& query,
1295  const StringData& finalize,
1296  BSONObjBuilder* groupObj
1297  );
1298 
1299  void _runGroup(
1300  const StringData& ns,
1301  const BSONObj& group,
1302  const Query& query,
1303  std::vector<BSONObj>* output
1304  );
1305 
1306  void _findAndModify(
1307  const StringData& ns,
1308  const BSONObj& query,
1309  const BSONObj& update,
1310  const BSONObj& sort,
1311  bool returnNew,
1312  bool upsert,
1313  const BSONObj& fields,
1314  BSONObjBuilder* out
1315  );
1316 
1317  std::auto_ptr<DBClientCursor> _legacyCollectionInfo(
1318  const std::string& db,
1319  const BSONObj& filter,
1320  int batchSize
1321  );
1322  };
1323 
1324  class DBClientWriter;
1325  class WriteOperation;
1326 
1330  class MONGO_CLIENT_API DBClientBase : public DBClientWithCommands, public DBConnector {
1331  friend class BulkOperationBuilder;
1332  protected:
1333  static AtomicInt64 ConnectionIdSequence;
1334  long long _connectionId; // unique connection id for this connection
1335  const boost::scoped_ptr<DBClientWriter> _wireProtocolWriter;
1336  const boost::scoped_ptr<DBClientWriter> _commandWriter;
1337  WriteConcern _writeConcern;
1338  int _maxBsonObjectSize;
1339  int _maxMessageSizeBytes;
1340  int _maxWriteBatchSize;
1341  void _write(
1342  const std::string& ns,
1343  const std::vector<WriteOperation*>& writes,
1344  bool ordered,
1345  const WriteConcern* writeConcern,
1346  WriteResult* writeResult
1347  );
1348  public:
1349  static const uint64_t INVALID_SOCK_CREATION_TIME;
1350 
1351  DBClientBase();
1352 
1353  // Required because compiler can't generate a destructor for the _writer
1354  // as it is an incomplete type.
1355  virtual ~DBClientBase();
1356 
1357  long long getConnectionId() const { return _connectionId; }
1358 
1359  const WriteConcern& getWriteConcern() const { return _writeConcern; }
1360  void setWriteConcern( const WriteConcern& w ) { _writeConcern = w; }
1361 
1362  void setWireVersions( int minWireVersion, int maxWireVersion ){
1363  _minWireVersion = minWireVersion;
1364  _maxWireVersion = maxWireVersion;
1365  }
1366 
1367  int getMinWireVersion() { return _minWireVersion; }
1368  int getMaxWireVersion() { return _maxWireVersion; }
1369  int getMaxBsonObjectSize() { return _maxBsonObjectSize; }
1370  int getMaxMessageSizeBytes() { return _maxMessageSizeBytes; }
1371  int getMaxWriteBatchSize() { return _maxWriteBatchSize; }
1372 
1387  virtual std::auto_ptr<DBClientCursor> query(const std::string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
1388  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
1389 
1409  virtual void parallelScan(
1410  const StringData& ns,
1411  int numCursors,
1412  std::vector<DBClientCursor*>* cursors,
1413  stdx::function<DBClientBase* ()> connectionFactory
1414  );
1415 
1416  virtual std::auto_ptr<DBClientCursor> aggregate(const std::string& ns,
1417  const BSONObj& pipeline,
1418  const BSONObj* aggregateOptions = NULL,
1419  int queryOptions = 0);
1420 
1421 
1430  virtual unsigned long long query( stdx::function<void(const BSONObj&)> f,
1431  const std::string& ns,
1432  Query query,
1433  const BSONObj *fieldsToReturn = 0,
1434  int queryOptions = 0 );
1435 
1436  virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator&)> f,
1437  const std::string& ns,
1438  Query query,
1439  const BSONObj *fieldsToReturn = 0,
1440  int queryOptions = 0 );
1441 
1442 
1448  virtual std::auto_ptr<DBClientCursor> getMore( const std::string &ns, long long cursorId, int nToReturn = 0, int options = 0 );
1449 
1453  virtual void insert(
1454  const std::string &ns,
1455  BSONObj obj,
1456  int flags=0,
1457  const WriteConcern* wc=NULL
1458  );
1459 
1463  virtual void insert(
1464  const std::string &ns,
1465  const std::vector< BSONObj >& v,
1466  int flags=0,
1467  const WriteConcern* wc=NULL
1468  );
1469 
1473  virtual void update(
1474  const std::string &ns,
1475  Query query,
1476  BSONObj obj,
1477  bool upsert=false,
1478  bool multi=false,
1479  const WriteConcern* wc=NULL
1480  );
1481 
1482  virtual void update(
1483  const std::string &ns,
1484  Query query,
1485  BSONObj obj,
1486  int flags,
1487  const WriteConcern* wc=NULL
1488  );
1489 
1497  virtual BulkOperationBuilder initializeUnorderedBulkOp(const std::string& ns);
1498 
1506  virtual BulkOperationBuilder initializeOrderedBulkOp(const std::string& ns);
1507 
1512  virtual void remove( const std::string &ns , Query q , bool justOne = 0, const WriteConcern* wc=NULL );
1513 
1514  virtual void remove( const std::string &ns , Query query, int flags, const WriteConcern* wc=NULL );
1515 
1516  virtual bool isFailed() const = 0;
1517 
1521  virtual bool isStillConnected() = 0;
1522 
1523  virtual void killCursor( long long cursorID ) = 0;
1524 
1525  virtual bool callRead( Message& toSend , Message& response ) = 0;
1526  // virtual bool callWrite( Message& toSend , Message& response ) = 0; // TODO: add this if needed
1527 
1528  virtual ConnectionString::ConnectionType type() const = 0;
1529 
1530  virtual double getSoTimeout() const = 0;
1531 
1532  virtual uint64_t getSockCreationMicroSec() const {
1533  return INVALID_SOCK_CREATION_TIME;
1534  }
1535 
1536  virtual void reset() {}
1537 
1538  }; // DBClientBase
1539 
1540  class DBClientReplicaSet;
1541 
1542  class MONGO_CLIENT_API ConnectException : public UserException {
1543  public:
1544  ConnectException(std::string msg) : UserException(9000,msg) { }
1545  };
1546 
1551  class MONGO_CLIENT_API DBClientConnection : public DBClientBase {
1552  public:
1553  using DBClientBase::query;
1554 
1561  DBClientConnection(bool _autoReconnect = false, DBClientReplicaSet* cp = 0, double so_timeout = 0);
1562 
1563  virtual ~DBClientConnection() {
1564  _numConnections.fetchAndAdd(-1);
1565  }
1566 
1576  virtual bool connect(const HostAndPort& server, std::string& errmsg);
1577 
1579  bool connect(const std::string& server, std::string& errmsg) {
1580  return connect(HostAndPort(server), errmsg);
1581  }
1582 
1591  void connect(const std::string& serverHostname) {
1592  std::string errmsg;
1593  if( !connect(HostAndPort(serverHostname), errmsg) )
1594  throw ConnectException(std::string("can't connect ") + errmsg);
1595  }
1596 
1604  virtual void logout(const std::string& dbname, BSONObj& info);
1605 
1606  virtual std::auto_ptr<DBClientCursor> query(const std::string &ns, Query query=Query(), int nToReturn = 0, int nToSkip = 0,
1607  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
1608 
1609  virtual unsigned long long query( stdx::function<void(DBClientCursorBatchIterator &)> f,
1610  const std::string& ns,
1611  Query query,
1612  const BSONObj *fieldsToReturn,
1613  int queryOptions );
1614 
1615  virtual bool runCommand(const std::string &dbname,
1616  const BSONObj& cmd,
1617  BSONObj &info,
1618  int options=0);
1619 
1624  bool isFailed() const { return _failed; }
1625 
1626  bool isStillConnected() { return p ? p->isStillConnected() : true; }
1627 
1628  MessagingPort& port() { verify(p); return *p; }
1629 
1630  std::string toString() const {
1631  std::stringstream ss;
1632  ss << _serverString;
1633  if ( !_serverAddrString.empty() ) ss << " (" << _serverAddrString << ")";
1634  if ( _failed ) ss << " failed";
1635  return ss.str();
1636  }
1637 
1638  std::string getServerAddress() const { return _serverString; }
1639  const HostAndPort& getServerHostAndPort() const { return _server; }
1640 
1641  virtual void killCursor( long long cursorID );
1642  virtual bool callRead( Message& toSend , Message& response ) { return call( toSend , response ); }
1643  virtual void say( Message &toSend, bool isRetry = false , std::string * actualServer = 0 );
1644  virtual bool recv( Message& m );
1645  virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, std::string* host = NULL );
1646  virtual bool call( Message &toSend, Message &response, bool assertOk = true , std::string * actualServer = 0 );
1647  virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
1648  void setSoTimeout(double timeout);
1649  double getSoTimeout() const { return _so_timeout; }
1650 
1651  virtual bool lazySupported() const { return true; }
1652 
1653  static int MONGO_CLIENT_FUNC getNumConnections() {
1654  return _numConnections.load();
1655  }
1656 
1661  void setParentReplSetName(const std::string& replSetName);
1662 
1663  static void MONGO_CLIENT_FUNC setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy; }
1664  static bool MONGO_CLIENT_FUNC getLazyKillCursor() { return _lazyKillCursor; }
1665 
1666  uint64_t getSockCreationMicroSec() const;
1667 
1668  protected:
1669  virtual void _auth(const BSONObj& params);
1670  virtual void sayPiggyBack( Message &toSend );
1671 
1672  boost::scoped_ptr<MessagingPort> p;
1673  boost::scoped_ptr<SockAddr> server;
1674  bool _failed;
1675  const bool autoReconnect;
1676  Backoff autoReconnectBackoff;
1677  HostAndPort _server; // remember for reconnects
1678  std::string _serverString; // server host and port
1679  std::string _serverAddrString; // resolved ip of server
1680  void _checkConnection();
1681 
1682  // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
1683  void checkConnection() { if( _failed ) _checkConnection(); }
1684 
1685  std::map<std::string, BSONObj> authCache;
1686  double _so_timeout;
1687  bool _connect( std::string& errmsg );
1688 
1689  static AtomicInt32 _numConnections;
1690  static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
1691 
1692 #ifdef MONGO_SSL
1693  SSLManagerInterface* sslManager();
1694 #endif
1695 
1696  private:
1697 
1703  void handleNotMasterResponse(const BSONElement& elemToCheck);
1704 
1705  // Contains the string for the replica set name of the host this is connected to.
1706  // Should be empty if this connection is not pointing to a replica set member.
1707  std::string _parentReplSetName;
1708  };
1709 
1712  MONGO_CLIENT_API bool MONGO_CLIENT_FUNC serverAlive( const std::string &uri );
1713 
1714  MONGO_CLIENT_API BSONElement MONGO_CLIENT_FUNC getErrField( const BSONObj& result );
1715  MONGO_CLIENT_API bool MONGO_CLIENT_FUNC hasErrField( const BSONObj& result );
1716 
1717  MONGO_CLIENT_API inline std::ostream& MONGO_CLIENT_FUNC operator<<( std::ostream &s, const Query &q ) {
1718  return s << q.toString();
1719  }
1720 
1721 } // 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
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:1111
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:123
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:1231
void createIndex(const StringData &ns, const BSONObj &keys)
Create an index on the collection 'ns' as described by the given keys.
Definition: dbclientinterface.h:1169
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:623
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:1207
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:1551
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:1579
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:1624
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:1591
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:1221
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:1089
double number() const
Retrieve the numeric value of the element.
Definition: bsonelement.h:236
Definition: dbclient_writer.h:27
Definition: dbclientinterface.h:1542
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:1330
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:1626
RunCommandHookFunc _runCommandHook
These functions will be executed by the driver on runCommand calls.
Definition: dbclientinterface.h:1280
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