MongoDB  2.7.0
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 "mongo/pch.h"
24 
25 #include <boost/function.hpp>
26 
27 #include "mongo/base/string_data.h"
28 #include "mongo/client/export_macros.h"
29 #include "mongo/db/jsobj.h"
30 #include "mongo/logger/log_severity.h"
31 #include "mongo/platform/atomic_word.h"
32 #include "mongo/util/net/message.h"
33 #include "mongo/util/net/message_port.h"
34 
35 namespace mongo {
36 
38  enum MONGO_CLIENT_API QueryOptions {
48 
52 
53  // findingStart mode is used to find the first operation of interest when
54  // we are scanning through a repl log. For efficiency in the common case,
55  // where the first operation of interest is closer to the tail than the head,
56  // we start from the tail of the log and work backwards until we find the
57  // first operation of interest. Then we scan forward from that first operation,
58  // actually returning results to the client. During the findingStart phase,
59  // we release the db mutex occasionally to avoid blocking the db process for
60  // an extended period of time.
61  QueryOption_OplogReplay = 1 << 3,
62 
67 
72 
81 
87 
89 
90  };
91 
92  enum MONGO_CLIENT_API UpdateOptions {
95 
99 
101  UpdateOption_Broadcast = 1 << 2
102  };
103 
104  enum MONGO_CLIENT_API RemoveOptions {
107 
109  RemoveOption_Broadcast = 1 << 1
110  };
111 
112 
116  enum MONGO_CLIENT_API InsertOptions {
118  InsertOption_ContinueOnError = 1 << 0
119  };
120 
124  enum MONGO_CLIENT_API WriteOptions {
126  WriteOption_FromWriteback = 1 << 31
127  };
128 
129  //
130  // For legacy reasons, the reserved field pre-namespace of certain types of messages is used
131  // to store options as opposed to the flags after the namespace. This should be transparent to
132  // the api user, but we need these constants to disassemble/reassemble the messages correctly.
133  //
134 
135  enum MONGO_CLIENT_API ReservedOptions {
136  Reserved_InsertOption_ContinueOnError = 1 << 0 ,
137  Reserved_FromWriteback = 1 << 1
138  };
139 
140  enum MONGO_CLIENT_API ReadPreference {
147 
155 
160 
165 
170  };
171 
172  class MONGO_CLIENT_API DBClientBase;
173  class MONGO_CLIENT_API DBClientConnection;
174 
192  class MONGO_CLIENT_API ConnectionString {
193  public:
194 
195  enum ConnectionType { INVALID , MASTER , PAIR , SET , SYNC, CUSTOM };
196 
197  ConnectionString() {
198  _type = INVALID;
199  }
200 
201  // Note: This should only be used for direct connections to a single server. For replica
202  // set and SyncClusterConnections, use ConnectionString::parse.
203  ConnectionString( const HostAndPort& server ) {
204  _type = MASTER;
205  _servers.push_back( server );
206  _finishInit();
207  }
208 
209  ConnectionString( ConnectionType type , const string& s , const string& setName = "" ) {
210  _type = type;
211  _setName = setName;
212  _fillServers( s );
213 
214  switch ( _type ) {
215  case MASTER:
216  verify( _servers.size() == 1 );
217  break;
218  case SET:
219  verify( _setName.size() );
220  verify( _servers.size() >= 1 ); // 1 is ok since we can derive
221  break;
222  case PAIR:
223  verify( _servers.size() == 2 );
224  break;
225  default:
226  verify( _servers.size() > 0 );
227  }
228 
229  _finishInit();
230  }
231 
232  ConnectionString( const string& s , ConnectionType favoredMultipleType ) {
233  _type = INVALID;
234 
235  _fillServers( s );
236  if ( _type != INVALID ) {
237  // set already
238  }
239  else if ( _servers.size() == 1 ) {
240  _type = MASTER;
241  }
242  else {
243  _type = favoredMultipleType;
244  verify( _type == SET || _type == SYNC );
245  }
246  _finishInit();
247  }
248 
249  bool isValid() const { return _type != INVALID; }
250 
251  string toString() const { return _string; }
252 
253  DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) const;
254 
255  string getSetName() const { return _setName; }
256 
257  vector<HostAndPort> getServers() const { return _servers; }
258 
259  ConnectionType type() const { return _type; }
260 
267  bool sameLogicalEndpoint( const ConnectionString& other ) const;
268 
269  static ConnectionString parse( const string& url , string& errmsg );
270 
271  static string typeToString( ConnectionType type );
272 
273  //
274  // Allow overriding the default connection behavior
275  // This is needed for some tests, which otherwise would fail because they are unable to contact
276  // the correct servers.
277  //
278 
280  public:
281  virtual ~ConnectionHook(){}
282 
283  // Returns an alternative connection object for a string
284  virtual DBClientBase* connect( const ConnectionString& c,
285  string& errmsg,
286  double socketTimeout ) = 0;
287  };
288 
289  static void setConnectionHook( ConnectionHook* hook ){
290  scoped_lock lk( _connectHookMutex );
291  _connectHook = hook;
292  }
293 
294  static ConnectionHook* getConnectionHook() {
295  scoped_lock lk( _connectHookMutex );
296  return _connectHook;
297  }
298 
299  // Allows ConnectionStrings to be stored more easily in sets/maps
300  bool operator<(const ConnectionString& other) const {
301  return _string < other._string;
302  }
303 
304  //
305  // FOR TESTING ONLY - useful to be able to directly mock a connection string without
306  // including the entire client library.
307  //
308 
309  static ConnectionString mock( const HostAndPort& server ) {
310  ConnectionString connStr;
311  connStr._servers.push_back( server );
312  connStr._string = server.toString( true );
313  return connStr;
314  }
315 
316  private:
317 
318  void _fillServers( string s );
319  void _finishInit();
320 
321  ConnectionType _type;
322  vector<HostAndPort> _servers;
323  string _string;
324  string _setName;
325 
326  static mutex _connectHookMutex;
327  static ConnectionHook* _connectHook;
328  };
329 
334  enum MONGO_CLIENT_API WriteConcern {
335  W_NONE = 0 , // TODO: not every connection type fully supports this
336  W_NORMAL = 1
337  // TODO SAFE = 2
338  };
339 
340  class BSONObj;
341  class ScopedDbConnection;
342  class DBClientCursor;
343  class DBClientCursorBatchIterator;
344 
350  class MONGO_CLIENT_API Query {
351  public:
352  static const BSONField<BSONObj> ReadPrefField;
353  static const BSONField<std::string> ReadPrefModeField;
354  static const BSONField<BSONArray> ReadPrefTagsField;
355 
356  BSONObj obj;
357  Query() : obj(BSONObj()) { }
358  Query(const BSONObj& b) : obj(b) { }
359  Query(const string &json);
360  Query(const char * json);
361 
370  Query& sort(const BSONObj& sortPattern);
371 
377  Query& sort(const string &field, int asc = 1) { sort( BSON( field << asc ) ); return *this; }
378 
384  Query& hint(BSONObj keyPattern);
385  Query& hint(const string &jsonKeyPatt);
386 
390  Query& minKey(const BSONObj &val);
394  Query& maxKey(const BSONObj &val);
395 
399  Query& explain();
400 
409  Query& snapshot();
410 
427  Query& where(const string &jscode, BSONObj scope);
428  Query& where(const string &jscode) { return where(jscode, BSONObj()); }
429 
436  Query& readPref(ReadPreference pref, const BSONArray& tags);
437 
441  bool isComplex( bool * hasDollar = 0 ) const;
442  static bool isComplex(const BSONObj& obj, bool* hasDollar = 0);
443 
444  BSONObj getFilter() const;
445  BSONObj getSort() const;
446  BSONObj getHint() const;
447  bool isExplain() const;
448 
452  static bool hasReadPreference(const BSONObj& queryObj);
453 
454  string toString() const;
455  operator string() const { return toString(); }
456  private:
457  void makeComplex();
458  template< class T >
459  void appendComplex( const char *fieldName, const T& val ) {
460  makeComplex();
461  BSONObjBuilder b;
462  b.appendElements(obj);
463  b.append(fieldName, val);
464  obj = b.obj();
465  }
466  };
467 
472  class MONGO_CLIENT_API QuerySpec {
473 
474  string _ns;
475  int _ntoskip;
476  int _ntoreturn;
477  int _options;
478  BSONObj _query;
479  BSONObj _fields;
480  Query _queryObj;
481 
482  public:
483 
484  QuerySpec( const string& ns,
485  const BSONObj& query, const BSONObj& fields,
486  int ntoskip, int ntoreturn, int options )
487  : _ns( ns ), _ntoskip( ntoskip ), _ntoreturn( ntoreturn ), _options( options ),
488  _query( query.getOwned() ), _fields( fields.getOwned() ) , _queryObj( _query ) {
489  }
490 
491  QuerySpec() {}
492 
493  bool isEmpty() const { return _ns.size() == 0; }
494 
495  bool isExplain() const { return _queryObj.isExplain(); }
496  BSONObj filter() const { return _queryObj.getFilter(); }
497 
498  BSONObj hint() const { return _queryObj.getHint(); }
499  BSONObj sort() const { return _queryObj.getSort(); }
500  BSONObj query() const { return _query; }
501  BSONObj fields() const { return _fields; }
502  BSONObj* fieldsData() { return &_fields; }
503 
504  // don't love this, but needed downstrem
505  const BSONObj* fieldsPtr() const { return &_fields; }
506 
507  string ns() const { return _ns; }
508  int ntoskip() const { return _ntoskip; }
509  int ntoreturn() const { return _ntoreturn; }
510  int options() const { return _options; }
511 
512  void setFields( BSONObj& o ) { _fields = o.getOwned(); }
513 
514  string toString() const {
515  return str::stream() << "QSpec " <<
516  BSON( "ns" << _ns << "n2skip" << _ntoskip << "n2return" << _ntoreturn << "options" << _options
517  << "query" << _query << "fields" << _fields );
518  }
519 
520  };
521 
522 
526 #define QUERY(x) ::mongo::Query( BSON(x) )
527 
528  // Useful utilities for namespaces
530  MONGO_CLIENT_API string nsGetDB( const string &ns );
531 
533  MONGO_CLIENT_API string nsGetCollection( const string &ns );
534 
538  class MONGO_CLIENT_API DBConnector {
539  public:
540  virtual ~DBConnector() {}
542  virtual bool call( Message &toSend, Message &response, bool assertOk=true , string * actualServer = 0 ) = 0;
543  virtual void say( Message &toSend, bool isRetry = false , string * actualServer = 0 ) = 0;
544  virtual void sayPiggyBack( Message &toSend ) = 0;
545  /* used by QueryOption_Exhaust. To use that your subclass must implement this. */
546  virtual bool recv( Message& m ) { verify(false); return false; }
547  // In general, for lazy queries, we'll need to say, recv, then checkResponse
548  virtual void checkResponse( const char* data, int nReturned, bool* retry = NULL, string* targetHost = NULL ) {
549  if( retry ) *retry = false; if( targetHost ) *targetHost = "";
550  }
551  virtual bool lazySupported() const = 0;
552  };
553 
557  class MONGO_CLIENT_API DBClientInterface : boost::noncopyable {
558  public:
559  virtual auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
560  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 ) = 0;
561 
562  virtual void insert( const string &ns, BSONObj obj , int flags=0) = 0;
563 
564  virtual void insert( const string &ns, const vector< BSONObj >& v , int flags=0) = 0;
565 
566  virtual void remove( const string &ns , Query query, bool justOne = 0 ) = 0;
567 
568  virtual void remove( const string &ns , Query query, int flags ) = 0;
569 
570  virtual void update( const string &ns,
571  Query query,
572  BSONObj obj,
573  bool upsert = false, bool multi = false ) = 0;
574 
575  virtual void update( const string &ns, Query query, BSONObj obj, int flags ) = 0;
576 
577  virtual ~DBClientInterface() { }
578 
583  virtual BSONObj findOne(const string &ns, const Query& query, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
584 
588  void findN(vector<BSONObj>& out, const string&ns, Query query, int nToReturn, int nToSkip = 0, const BSONObj *fieldsToReturn = 0, int queryOptions = 0);
589 
590  virtual string getServerAddress() const = 0;
591 
593  virtual auto_ptr<DBClientCursor> getMore( const string &ns, long long cursorId, int nToReturn = 0, int options = 0 ) = 0;
594  };
595 
600  class MONGO_CLIENT_API DBClientWithCommands : public DBClientInterface {
601  set<string> _seenIndexes;
602  public:
604  logger::LogSeverity _logLevel;
605 
606  DBClientWithCommands() : _logLevel(logger::LogSeverity::Log()),
607  _cachedAvailableOptions( (enum QueryOptions)0 ),
608  _haveCachedAvailableOptions(false) { }
609 
616  bool simpleCommand(const string &dbname, BSONObj *info, const string &command);
617 
631  virtual bool runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info,
632  int options=0);
633 
657  void auth(const BSONObj& params);
658 
668  bool auth(const string &dbname, const string &username, const string &pwd, string& errmsg, bool digestPassword = true);
669 
677  virtual void logout(const string& dbname, BSONObj& info);
678 
682  virtual unsigned long long count(const string &ns, const BSONObj& query = BSONObj(), int options=0, int limit=0, int skip=0 );
683 
684  static string createPasswordDigest(const string &username, const string &clearTextPassword);
685 
694  virtual bool isMaster(bool& isMaster, BSONObj *info=0);
695 
712  bool createCollection(const string &ns, long long size = 0, bool capped = false, int max = 0, BSONObj *info = 0);
713 
718  string getLastError(const std::string& db,
719  bool fsync = false,
720  bool j = false,
721  int w = 0,
722  int wtimeout = 0);
726  string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
727 
735  virtual BSONObj getLastErrorDetailed(const std::string& db,
736  bool fsync = false,
737  bool j = false,
738  int w = 0,
739  int wtimeout = 0);
743  virtual BSONObj getLastErrorDetailed(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
744 
748  static string getLastErrorString( const BSONObj& res );
749 
756  BSONObj getPrevError();
757 
762  bool resetError() { return simpleCommand("admin", 0, "reseterror"); }
763 
768  virtual bool dropCollection( const string &ns, BSONObj* info = NULL ) {
769  string db = nsGetDB( ns );
770  string coll = nsGetCollection( ns );
771  uassert( 10011 , "no collection name", coll.size() );
772 
773  BSONObj temp;
774  if ( info == NULL ) {
775  info = &temp;
776  }
777 
778  bool res = runCommand( db.c_str() , BSON( "drop" << coll ) , *info );
779  resetIndexCache();
780  return res;
781  }
782 
786  bool repairDatabase(const string &dbname, BSONObj *info = 0) {
787  return simpleCommand(dbname, info, "repairDatabase");
788  }
789 
809  bool copyDatabase(const string &fromdb, const string &todb, const string &fromhost = "", BSONObj *info = 0);
810 
816  ProfileOff = 0,
817  ProfileSlow = 1, // log very slow (>100ms) operations
818  ProfileAll = 2
819 
820  };
821  bool setDbProfilingLevel(const string &dbname, ProfilingLevel level, BSONObj *info = 0);
822  bool getDbProfilingLevel(const string &dbname, ProfilingLevel& level, BSONObj *info = 0);
823 
824 
828  struct MROutput {
829  MROutput(const char* collection) : out(BSON("replace" << collection)) {}
830  MROutput(const string& collection) : out(BSON("replace" << collection)) {}
831  MROutput(const BSONObj& obj) : out(obj) {}
832 
833  BSONObj out;
834  };
835  static MROutput MRInline;
836 
860  BSONObj mapreduce(const string &ns, const string &jsmapf, const string &jsreducef, BSONObj query = BSONObj(), MROutput output = MRInline);
861 
877  bool eval(const string &dbname, const string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0);
878 
882  bool validate( const string &ns , bool scandata=true ) {
883  BSONObj cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
884  BSONObj info;
885  return runCommand( nsGetDB( ns ).c_str() , cmd , info );
886  }
887 
888  /* The following helpers are simply more convenient forms of eval() for certain common cases */
889 
890  /* invocation with no return value of interest -- with or without one simple parameter */
891  bool eval(const string &dbname, const string &jscode);
892  template< class T >
893  bool eval(const string &dbname, const string &jscode, T parm1) {
894  BSONObj info;
895  BSONElement retValue;
896  BSONObjBuilder b;
897  b.append("0", parm1);
898  BSONObj args = b.done();
899  return eval(dbname, jscode, info, retValue, &args);
900  }
901 
903  template< class T, class NumType >
904  bool eval(const string &dbname, const string &jscode, T parm1, NumType& ret) {
905  BSONObj info;
906  BSONElement retValue;
907  BSONObjBuilder b;
908  b.append("0", parm1);
909  BSONObj args = b.done();
910  if ( !eval(dbname, jscode, info, retValue, &args) )
911  return false;
912  ret = (NumType) retValue.number();
913  return true;
914  }
915 
921  list<string> getDatabaseNames();
922 
926  list<string> getCollectionNames( const string& db );
927 
928  bool exists( const string& ns );
929 
944  virtual bool ensureIndex( const string &ns,
945  BSONObj keys,
946  bool unique = false,
947  const string &name = "",
948  bool cache = true,
949  bool background = false,
950  int v = -1,
951  int ttl = 0 );
955  virtual void resetIndexCache();
956 
957  virtual auto_ptr<DBClientCursor> getIndexes( const string &ns );
958 
959  virtual void dropIndex( const string& ns , BSONObj keys );
960  virtual void dropIndex( const string& ns , const string& indexName );
961 
965  virtual void dropIndexes( const string& ns );
966 
967  virtual void reIndex( const string& ns );
968 
969  string genIndexName( const BSONObj& keys );
970 
972  virtual bool dropDatabase(const string &dbname, BSONObj *info = 0) {
973  bool ret = simpleCommand(dbname, info, "dropDatabase");
974  resetIndexCache();
975  return ret;
976  }
977 
978  virtual string toString() const = 0;
979 
987  typedef boost::function<void(BSONObjBuilder*)> RunCommandHookFunc;
988  virtual void setRunCommandHook(RunCommandHookFunc func);
989  RunCommandHookFunc getRunCommandHook() const {
990  return _runCommandHook;
991  }
992 
997  typedef boost::function<void(const BSONObj&, const std::string&)> PostRunCommandHookFunc;
998  virtual void setPostRunCommandHook(PostRunCommandHookFunc func);
999  PostRunCommandHookFunc getPostRunCommandHook() const {
1000  return _postRunCommandHook;
1001  }
1002 
1003 
1004  protected:
1006  bool isOk(const BSONObj&);
1007 
1009  bool isNotMasterErrorString( const BSONElement& e );
1010 
1011  BSONObj _countCmd(const string &ns, const BSONObj& query, int options, int limit, int skip );
1012 
1017  QueryOptions availableOptions();
1018 
1019  virtual QueryOptions _lookupAvailableOptions();
1020 
1021  virtual void _auth(const BSONObj& params);
1022 
1028  bool _authMongoCR(const string &dbname,
1029  const string &username,
1030  const string &pwd,
1031  BSONObj *info,
1032  bool digestPassword);
1033 
1039  bool _authX509(const string&dbname,
1040  const string &username,
1041  BSONObj *info);
1042 
1047  PostRunCommandHookFunc _postRunCommandHook;
1048 
1049 
1050  private:
1051  enum QueryOptions _cachedAvailableOptions;
1052  bool _haveCachedAvailableOptions;
1053  };
1054 
1058  class MONGO_CLIENT_API DBClientBase : public DBClientWithCommands, public DBConnector {
1059  protected:
1060  static AtomicInt64 ConnectionIdSequence;
1061  long long _connectionId; // unique connection id for this connection
1062  WriteConcern _writeConcern;
1063  int _minWireVersion;
1064  int _maxWireVersion;
1065  public:
1066  static const uint64_t INVALID_SOCK_CREATION_TIME;
1067 
1068  DBClientBase() {
1069  _writeConcern = W_NORMAL;
1070  _connectionId = ConnectionIdSequence.fetchAndAdd(1);
1071  _minWireVersion = _maxWireVersion = 0;
1072  }
1073 
1074  long long getConnectionId() const { return _connectionId; }
1075 
1076  WriteConcern getWriteConcern() const { return _writeConcern; }
1077  void setWriteConcern( WriteConcern w ) { _writeConcern = w; }
1078 
1079  void setWireVersions( int minWireVersion, int maxWireVersion ){
1080  _minWireVersion = minWireVersion;
1081  _maxWireVersion = maxWireVersion;
1082  }
1083 
1084  int getMinWireVersion() { return _minWireVersion; }
1085  int getMaxWireVersion() { return _maxWireVersion; }
1086 
1101  virtual auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
1102  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 );
1103 
1104 
1113  virtual unsigned long long query( boost::function<void(const BSONObj&)> f,
1114  const string& ns,
1115  Query query,
1116  const BSONObj *fieldsToReturn = 0,
1117  int queryOptions = 0 );
1118 
1119  virtual unsigned long long query( boost::function<void(DBClientCursorBatchIterator&)> f,
1120  const string& ns,
1121  Query query,
1122  const BSONObj *fieldsToReturn = 0,
1123  int queryOptions = 0 );
1124 
1125 
1131  virtual auto_ptr<DBClientCursor> getMore( const string &ns, long long cursorId, int nToReturn = 0, int options = 0 );
1132 
1136  virtual void insert( const string &ns , BSONObj obj , int flags=0);
1137 
1141  virtual void insert( const string &ns, const vector< BSONObj >& v , int flags=0);
1142 
1146  virtual void update( const string &ns,
1147  Query query,
1148  BSONObj obj,
1149  bool upsert = false, bool multi = false );
1150 
1151  virtual void update( const string &ns, Query query, BSONObj obj, int flags );
1152 
1157  virtual void remove( const string &ns , Query q , bool justOne = 0 );
1158 
1159  virtual void remove( const string &ns , Query query, int flags );
1160 
1161  virtual bool isFailed() const = 0;
1162 
1166  virtual bool isStillConnected() = 0;
1167 
1168  virtual void killCursor( long long cursorID ) = 0;
1169 
1170  virtual bool callRead( Message& toSend , Message& response ) = 0;
1171  // virtual bool callWrite( Message& toSend , Message& response ) = 0; // TODO: add this if needed
1172 
1173  virtual ConnectionString::ConnectionType type() const = 0;
1174 
1175  virtual double getSoTimeout() const = 0;
1176 
1177  virtual uint64_t getSockCreationMicroSec() const {
1178  return INVALID_SOCK_CREATION_TIME;
1179  }
1180 
1181  }; // DBClientBase
1182 
1183  class DBClientReplicaSet;
1184 
1185  class MONGO_CLIENT_API ConnectException : public UserException {
1186  public:
1187  ConnectException(string msg) : UserException(9000,msg) { }
1188  };
1189 
1194  class MONGO_CLIENT_API DBClientConnection : public DBClientBase {
1195  public:
1196  using DBClientBase::query;
1197 
1204  DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet* cp=0, double so_timeout=0) :
1205  clientSet(cp), _failed(false), autoReconnect(_autoReconnect), autoReconnectBackoff(1000, 2000), _so_timeout(so_timeout) {
1206  _numConnections++;
1207  }
1208 
1209  virtual ~DBClientConnection() {
1210  _numConnections--;
1211  }
1212 
1224  virtual bool connect(const char * hostname, string& errmsg) {
1225  // TODO: remove this method
1226  HostAndPort t( hostname );
1227  return connect( t , errmsg );
1228  }
1229 
1239  virtual bool connect(const HostAndPort& server, string& errmsg);
1240 
1249  void connect(const string& serverHostname) {
1250  string errmsg;
1251  if( !connect(HostAndPort(serverHostname), errmsg) )
1252  throw ConnectException(string("can't connect ") + errmsg);
1253  }
1254 
1262  virtual void logout(const string& dbname, BSONObj& info);
1263 
1264  virtual auto_ptr<DBClientCursor> query(const string &ns, Query query=Query(), int nToReturn = 0, int nToSkip = 0,
1265  const BSONObj *fieldsToReturn = 0, int queryOptions = 0 , int batchSize = 0 ) {
1266  checkConnection();
1267  return DBClientBase::query( ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions , batchSize );
1268  }
1269 
1270  virtual unsigned long long query( boost::function<void(DBClientCursorBatchIterator &)> f,
1271  const string& ns,
1272  Query query,
1273  const BSONObj *fieldsToReturn,
1274  int queryOptions );
1275 
1276  virtual bool runCommand(const string &dbname,
1277  const BSONObj& cmd,
1278  BSONObj &info,
1279  int options=0);
1280 
1285  bool isFailed() const { return _failed; }
1286 
1287  bool isStillConnected() { return p ? p->isStillConnected() : true; }
1288 
1289  MessagingPort& port() { verify(p); return *p; }
1290 
1291  string toString() const {
1292  stringstream ss;
1293  ss << _serverString;
1294  if ( !_serverAddrString.empty() ) ss << " (" << _serverAddrString << ")";
1295  if ( _failed ) ss << " failed";
1296  return ss.str();
1297  }
1298 
1299  string getServerAddress() const { return _serverString; }
1300 
1301  virtual void killCursor( long long cursorID );
1302  virtual bool callRead( Message& toSend , Message& response ) { return call( toSend , response ); }
1303  virtual void say( Message &toSend, bool isRetry = false , string * actualServer = 0 );
1304  virtual bool recv( Message& m );
1305  virtual void checkResponse( const char *data, int nReturned, bool* retry = NULL, string* host = NULL );
1306  virtual bool call( Message &toSend, Message &response, bool assertOk = true , string * actualServer = 0 );
1307  virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
1308  void setSoTimeout(double timeout);
1309  double getSoTimeout() const { return _so_timeout; }
1310 
1311  virtual bool lazySupported() const { return true; }
1312 
1313  static int getNumConnections() {
1314  return _numConnections;
1315  }
1316 
1327  void setReplSetClientCallback(DBClientReplicaSet* rsClient);
1328 
1329  static void setLazyKillCursor( bool lazy ) { _lazyKillCursor = lazy; }
1330  static bool getLazyKillCursor() { return _lazyKillCursor; }
1331 
1332  uint64_t getSockCreationMicroSec() const;
1333 
1334  protected:
1335  friend class SyncClusterConnection;
1336  virtual void _auth(const BSONObj& params);
1337  virtual void sayPiggyBack( Message &toSend );
1338 
1339  DBClientReplicaSet *clientSet;
1340  boost::scoped_ptr<MessagingPort> p;
1341  boost::scoped_ptr<SockAddr> server;
1342  bool _failed;
1343  const bool autoReconnect;
1344  Backoff autoReconnectBackoff;
1345  HostAndPort _server; // remember for reconnects
1346  string _serverString; // server host and port
1347  string _serverAddrString; // resolved ip of server
1348  void _checkConnection();
1349 
1350  // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
1351  void checkConnection() { if( _failed ) _checkConnection(); }
1352 
1353  map<string, BSONObj> authCache;
1354  double _so_timeout;
1355  bool _connect( string& errmsg );
1356 
1357  static AtomicUInt _numConnections;
1358  static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
1359 
1360 #ifdef MONGO_SSL
1361  SSLManagerInterface* sslManager();
1362 #endif
1363  };
1364 
1367  MONGO_CLIENT_API bool serverAlive( const string &uri );
1368 
1369  MONGO_CLIENT_API DBClientBase * createDirectClient();
1370 
1371  MONGO_CLIENT_API BSONElement getErrField( const BSONObj& result );
1372  MONGO_CLIENT_API bool hasErrField( const BSONObj& result );
1373 
1374  MONGO_CLIENT_API inline std::ostream& operator<<( std::ostream &s, const Query &q ) {
1375  return s << q.toString();
1376  }
1377 
1378 } // namespace mongo
1379 
1380 #include "mongo/client/dbclientcursor.h"
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: password_digest.cpp:35
UpdateOption_Upsert
Upsert - that is, insert the item if no matching item is found.
Definition: dbclientinterface.h:94
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:52
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:85
Definition: assert_util.h:149
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:587
Query & sort(const string &field, int asc=1)
Add a sort (ORDER BY) criteria to the query expression.
Definition: dbclientinterface.h:377
Definition: message_port.h:66
virtual auto_ptr< DBClientCursor > query(const string &ns, Query query=Query(), int nToReturn=0, int nToSkip=0, const BSONObj *fieldsToReturn=0, int queryOptions=0, int batchSize=0)
send a query to the database.
Definition: dbclientinterface.h:1264
LogstreamBuilder out()
Synonym for log().
Definition: log.h:79
QueryOption_SlaveOk
allow query of replica slave.
Definition: dbclientinterface.h:51
iterate over objects in current batch only - will not cause a network call
Definition: dbclientcursor.h:259
the idea here is to make one liners easy.
Definition: str.h:48
bool repairDatabase(const string &dbname, BSONObj *info=0)
Perform a repair and compaction of the specified database.
Definition: dbclientinterface.h:786
virtual bool dropCollection(const string &ns, BSONObj *info=NULL)
Delete the specified collection.
Definition: dbclientinterface.h:768
Definition: mutex.h:101
QueryOption_Exhaust
Stream the data down full blast in multiple "more" packages, on the assumption that the client will f...
Definition: dbclientinterface.h:80
BSON classes.
RunCommandHookFunc _runCommandHook
These functions will be executed by the driver on runCommand calls.
Definition: dbclientinterface.h:1046
ReadPreference_SecondaryOnly
Read from secondary if available, otherwise error.
Definition: dbclientinterface.h:146
boost::function< void(BSONObjBuilder *)> RunCommandHookFunc
A function type for runCommand hooking; the function takes a pointer to a BSONObjBuilder and returns ...
Definition: dbclientinterface.h:987
ReadPreference_SecondaryPreferred
Read from a secondary if available, otherwise read from the primary.
Definition: dbclientinterface.h:146
BSONObj getOwned() const
assure the data buffer is under the control of this BSONObj and not a remote buffer ...
Definition: bson-inl.h:232
This implicitly converts from char*, string, and BSONObj to be an argument to mapreduce You shouldn't...
Definition: dbclientinterface.h:828
bool isStillConnected()
if not checked recently, checks whether the underlying socket/sockets are still valid ...
Definition: dbclientinterface.h:1287
Represents a full query description, including all options required for the query to be passed on to ...
Definition: dbclientinterface.h:472
interface that handles communication with the db
Definition: dbclientinterface.h:538
abstract class that implements the core db operations
Definition: dbclientinterface.h:1058
bool serverAlive(const string &uri)
pings server to check if it's up
Definition: dbclient.cpp:1491
bool isFailed() const
Definition: dbclientinterface.h:1285
Definition: dbclientinterface.h:279
boost::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:997
Definition: bson_field.h:75
double number() const
Retrieve the numeric value of the element.
Definition: bsonelement.h:228
DBClientConnection(bool _autoReconnect=false, DBClientReplicaSet *cp=0, double so_timeout=0)
Definition: dbclientinterface.h:1204
Use this class to connect to a replica set of servers.
Definition: dbclient_rs.h:42
A basic connection to the database.
Definition: dbclientinterface.h:1194
bool validate(const string &ns, bool scandata=true)
validate a collection, checking for errors and reporting back statistics.
Definition: dbclientinterface.h:882
QueryOption_PartialResults
When sharded, this means its ok to return partial results Usually we will fail a query if all require...
Definition: dbclientinterface.h:86
The interface that any db connection should implement.
Definition: dbclientinterface.h:557
ProfilingLevel
The Mongo database provides built-in performance profiling capabilities.
Definition: dbclientinterface.h:815
logger::LogSeverity _logLevel
controls how chatty the client is about network errors & such.
Definition: dbclientinterface.h:604
QueryOption_NoCursorTimeout
The server normally times out idle cursors after an inactivity period to prevent excess memory uses S...
Definition: dbclientinterface.h:66
virtual bool dropDatabase(const string &dbname, BSONObj *info=0)
Erase / drop an entire database.
Definition: dbclientinterface.h:972
DB "commands" Basically just invocations of connection.
Definition: dbclientinterface.h:600
Definition: dbclientinterface.h:1185
ReadPreference_PrimaryOnly
Read from primary only.
Definition: dbclientinterface.h:146
UpdateOption_Multi
Update multiple documents (if multiple documents match query expression).
Definition: dbclientinterface.h:98
string nsGetDB(const string &ns)
Definition: dbclient.cpp:1503
RemoveOption_JustOne
only delete one option
Definition: dbclientinterface.h:106
virtual auto_ptr< DBClientCursor > query(const 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.
Definition: dbclient.cpp:1021
helper for manipulating host:port connection endpoints.
Definition: hostandport.h:31
virtual bool connect(const char *hostname, string &errmsg)
Connect to a Mongo database server.
Definition: dbclientinterface.h:1224
void connect(const string &serverHostname)
Connect to a Mongo database server.
Definition: dbclientinterface.h:1249
QueryOption_AwaitData
Use with QueryOption_CursorTailable.
Definition: dbclientinterface.h:71
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:62
ReadPreference_Nearest
Read from any member.
Definition: dbclientinterface.h:146
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
string nsGetCollection(const string &ns)
Definition: dbclient.cpp:1512
ReadPreference_PrimaryPreferred
Read from primary if available, otherwise a secondary.
Definition: dbclientinterface.h:146
Represents a Mongo query expression.
Definition: dbclientinterface.h:350
Definition: message.h:153
bool eval(const string &dbname, const 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:904
ConnectionString handles parsing different ways to connect to mongo and determining method samples: s...
Definition: dbclientinterface.h:192
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:47
bool resetError()
Reset the previous error state for this connection (accessed via getLastError and getPrevError)...
Definition: dbclientinterface.h:762