MongoDB C++ Driver  legacy-1.1.2
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 
76 
81 
92 
98 
99  QueryOption_AllSupported = QueryOption_CursorTailable | QueryOption_SlaveOk |
100  QueryOption_OplogReplay | QueryOption_NoCursorTimeout | QueryOption_AwaitData |
102 };
103 
107 enum MONGO_CLIENT_API WriteOptions {
109  WriteOption_FromWriteback = 1 << 31
110 };
111 
112 //
113 // For legacy reasons, the reserved field pre-namespace of certain types of messages is used
114 // to store options as opposed to the flags after the namespace. This should be transparent to
115 // the api user, but we need these constants to disassemble/reassemble the messages correctly.
116 //
117 
118 enum MONGO_CLIENT_API ReservedOptions {
119  Reserved_InsertOption_ContinueOnError = 1 << 0,
120  Reserved_FromWriteback = 1 << 1
121 };
122 
123 enum MONGO_CLIENT_API ReadPreference {
130 
138 
143 
148 
153 };
154 
155 class MONGO_CLIENT_API DBClientBase;
156 class MONGO_CLIENT_API DBClientConnection;
157 
186 class MONGO_CLIENT_API ConnectionString {
187 public:
188  enum ConnectionType { INVALID, MASTER, PAIR, SET, CUSTOM };
189 
190  ConnectionString() {
191  _type = INVALID;
192  }
193 
194  // Note: This should only be used for direct connections to a single server. For replica
195  // set and SyncClusterConnections, use ConnectionString::parse.
196  ConnectionString(const HostAndPort& server) {
197  _type = MASTER;
198  _servers.push_back(server);
199  _finishInit();
200  }
201 
202  ConnectionString(ConnectionType type, const std::string& s, const std::string& setName = "") {
203  _type = type;
204  _setName = setName;
205  _fillServers(s);
206 
207  switch (_type) {
208  case MASTER:
209  verify(_servers.size() == 1);
210  break;
211  case SET:
212  verify(_setName.size());
213  verify(_servers.size() >= 1); // 1 is ok since we can derive
214  break;
215  case PAIR:
216  verify(_servers.size() == 2);
217  break;
218  default:
219  verify(_servers.size() > 0);
220  }
221 
222  _finishInit();
223  }
224 
225  ConnectionString(const std::string& s, ConnectionType favoredMultipleType) {
226  _type = INVALID;
227 
228  _fillServers(s);
229  if (_type != INVALID) {
230  // set already
231  } else if (_servers.size() == 1) {
232  _type = MASTER;
233  } else {
234  _type = favoredMultipleType;
235  verify(_type == SET);
236  }
237  _finishInit();
238  }
239 
240  bool isValid() const {
241  return _type != INVALID;
242  }
243 
244  std::string toString() const {
245  return _string;
246  }
247 
248  DBClientBase* connect(std::string& errmsg, double socketTimeout = 0) const;
249 
250  std::string getSetName() const {
251  return _setName;
252  }
253 
254  const std::vector<HostAndPort>& getServers() const {
255  return _servers;
256  }
257 
258  ConnectionType type() const {
259  return _type;
260  }
261 
262  const std::string& getUser() const {
263  return _user;
264  }
265 
266  const std::string& getPassword() const {
267  return _password;
268  }
269 
270  const BSONObj& getOptions() const {
271  return _options;
272  }
273 
274  const std::string& getDatabase() const {
275  return _database;
276  }
277 
284  bool sameLogicalEndpoint(const ConnectionString& other) const;
285 
286  static ConnectionString MONGO_CLIENT_FUNC
287  parse(const std::string& address, std::string& errmsg);
288 
289  static ConnectionString MONGO_CLIENT_FUNC
290  parseDeprecated(const std::string& address, std::string& errmsg);
291 
292  static std::string MONGO_CLIENT_FUNC typeToString(ConnectionType type);
293 
294  //
295  // Allow overriding the default connection behavior
296  // This is needed for some tests, which otherwise would fail because they are unable to contact
297  // the correct servers.
298  //
299 
301  public:
302  virtual ~ConnectionHook() {}
303 
304  // Returns an alternative connection object for a string
305  virtual DBClientBase* connect(const ConnectionString& c,
306  std::string& errmsg,
307  double socketTimeout) = 0;
308  };
309 
310  static void setConnectionHook(ConnectionHook* hook) {
311  boost::lock_guard<boost::mutex> lk(_connectHookMutex);
312  _connectHook = hook;
313  }
314 
315  static ConnectionHook* getConnectionHook() {
316  boost::lock_guard<boost::mutex> lk(_connectHookMutex);
317  return _connectHook;
318  }
319 
320  // Allows ConnectionStrings to be stored more easily in sets/maps
321  bool operator<(const ConnectionString& other) const {
322  return _string < other._string;
323  }
324 
325  //
326  // FOR TESTING ONLY - useful to be able to directly mock a connection string without
327  // including the entire client library.
328  //
329 
330  static ConnectionString mock(const HostAndPort& server) {
331  ConnectionString connStr;
332  connStr._servers.push_back(server);
333  connStr._string = server.toString();
334  return connStr;
335  }
336 
337 private:
338  ConnectionString(ConnectionType type,
339  const std::string& user,
340  const std::string& password,
341  const std::string& servers,
342  const std::string& database,
343  const std::string& setName,
344  const BSONObj& options)
345  : _type(type),
346  _servers(),
347  _setName(setName),
348  _user(user),
349  _password(password),
350  _database(database),
351  _options(options) {
352  _fillServers(servers, false);
353  switch (_type) {
354  case MASTER:
355  verify(_servers.size() == 1);
356  break;
357  case SET:
358  verify(_setName.size());
359  verify(_servers.size() >= 1); // 1 is ok since we can derive
360  break;
361  case PAIR:
362  verify(_servers.size() == 2);
363  break;
364  default:
365  verify(_servers.size() > 0);
366  }
367 
368  _finishInit();
369  }
370 
371  static ConnectionString _parseURL(const std::string& url, std::string& errmsg);
372 
373  void _fillServers(std::string s, bool legacy = true);
374  void _finishInit();
375 
376  BSONObj _makeAuthObjFromOptions(int maxWireVersion) const;
377 
378  ConnectionType _type;
379  std::vector<HostAndPort> _servers;
380  std::string _string;
381  std::string _setName;
382 
383  std::string _user;
384  std::string _password;
385 
386  std::string _database;
387  BSONObj _options;
388 
389  static boost::mutex _connectHookMutex;
390  static ConnectionHook* _connectHook;
391 };
392 
393 class BSONObj;
394 class DBClientCursor;
395 class DBClientCursorBatchIterator;
396 
403 class MONGO_CLIENT_API Query {
404 public:
405  static const BSONField<BSONObj> ReadPrefField;
406  static const BSONField<std::string> ReadPrefModeField;
407  static const BSONField<BSONArray> ReadPrefTagsField;
408 
409  BSONObj obj;
410  Query() : obj(BSONObj()) {}
411  Query(const BSONObj& b) : obj(b) {}
412  Query(const std::string& json);
413  Query(const char* json);
414 
424  Query& sort(const BSONObj& sortPattern);
425 
431  Query& sort(const std::string& field, int asc = 1) {
432  sort(BSON(field << asc));
433  return *this;
434  }
435 
441  Query& hint(BSONObj keyPattern);
442  Query& hint(const std::string& indexName);
443 
448  Query& maxTimeMs(int millis);
449 
453  Query& minKey(const BSONObj& val);
457  Query& maxKey(const BSONObj& val);
458 
463  Query& explain();
464 
474  Query& snapshot();
475 
492  Query& where(const std::string& jscode, BSONObj scope);
493  Query& where(const std::string& jscode) {
494  return where(jscode, BSONObj());
495  }
496 
503  Query& readPref(ReadPreference pref, const BSONArray& tags);
504 
508  bool isComplex(bool* hasDollar = 0) const;
509  BSONObj getModifiers() const;
510  static bool MONGO_CLIENT_FUNC isComplex(const BSONObj& obj, bool* hasDollar = 0);
511 
512  BSONObj getFilter() const;
513  BSONObj getSort() const;
514  BSONElement getHint() const;
515  BSONObj getReadPref() const;
516  int getMaxTimeMs() const;
517  bool isExplain() const;
518 
522  static bool MONGO_CLIENT_FUNC hasReadPreference(const BSONObj& queryObj);
523  bool hasReadPreference() const;
524  bool hasHint() const;
525  bool hasMaxTimeMs() const;
526 
527  std::string toString() const;
528  operator std::string() const {
529  return toString();
530  }
531 
532 private:
533  void makeComplex();
534  template <class T>
535  void appendComplex(const char* fieldName, const T& val) {
536  makeComplex();
537  BSONObjBuilder b;
538  b.appendElements(obj);
539  b.append(fieldName, val);
540  obj = b.obj();
541  }
542 };
543 
548 class MONGO_CLIENT_API QuerySpec {
549  std::string _ns;
550  int _ntoskip;
551  int _ntoreturn;
552  int _options;
553  BSONObj _query;
554  BSONObj _fields;
555  Query _queryObj;
556 
557 public:
558  QuerySpec(const std::string& ns,
559  const BSONObj& query,
560  const BSONObj& fields,
561  int ntoskip,
562  int ntoreturn,
563  int options)
564  : _ns(ns),
565  _ntoskip(ntoskip),
566  _ntoreturn(ntoreturn),
567  _options(options),
568  _query(query.getOwned()),
569  _fields(fields.getOwned()),
570  _queryObj(_query) {}
571 
572  QuerySpec() {}
573 
574  bool isEmpty() const {
575  return _ns.size() == 0;
576  }
577 
578  bool isExplain() const {
579  return _queryObj.isExplain();
580  }
581  BSONObj filter() const {
582  return _queryObj.getFilter();
583  }
584 
585  BSONElement hint() const {
586  return _queryObj.getHint();
587  }
588  BSONObj sort() const {
589  return _queryObj.getSort();
590  }
591  BSONObj query() const {
592  return _query;
593  }
594  BSONObj fields() const {
595  return _fields;
596  }
597  BSONObj* fieldsData() {
598  return &_fields;
599  }
600 
601  // don't love this, but needed downstrem
602  const BSONObj* fieldsPtr() const {
603  return &_fields;
604  }
605 
606  std::string ns() const {
607  return _ns;
608  }
609  int ntoskip() const {
610  return _ntoskip;
611  }
612  int ntoreturn() const {
613  return _ntoreturn;
614  }
615  int options() const {
616  return _options;
617  }
618 
619  void setFields(BSONObj& o) {
620  _fields = o.getOwned();
621  }
622 
623  std::string toString() const {
624  return str::stream() << "QSpec " << BSON("ns" << _ns << "n2skip" << _ntoskip << "n2return"
625  << _ntoreturn << "options" << _options
626  << "query" << _query << "fields" << _fields);
627  }
628 };
629 
630 
634 #define MONGO_QUERY(x) ::mongo::Query(BSON(x))
635 
636 // Useful utilities for namespaces
638 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetDB(const std::string& ns);
639 
641 MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetCollection(const std::string& ns);
642 
646 class MONGO_CLIENT_API DBConnector {
647 public:
648  virtual ~DBConnector() {}
651  virtual bool call(Message& toSend,
652  Message& response,
653  bool assertOk = true,
654  std::string* actualServer = 0) = 0;
655  virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0) = 0;
656  virtual void sayPiggyBack(Message& toSend) = 0;
657  /* used by QueryOption_Exhaust. To use that your subclass must implement this. */
658  virtual bool recv(Message& m) {
659  verify(false);
660  return false;
661  }
662  // In general, for lazy queries, we'll need to say, recv, then checkResponse
663  virtual void checkResponse(const char* data,
664  int nReturned,
665  bool* retry = NULL,
666  std::string* targetHost = NULL) {
667  if (retry)
668  *retry = false;
669  if (targetHost)
670  *targetHost = "";
671  }
672  virtual bool lazySupported() const = 0;
673 };
674 
678 class MONGO_CLIENT_API DBClientInterface : boost::noncopyable {
679 public:
680  virtual std::auto_ptr<DBClientCursor> query(const std::string& ns,
681  Query query,
682  int nToReturn = 0,
683  int nToSkip = 0,
684  const BSONObj* fieldsToReturn = 0,
685  int queryOptions = 0,
686  int batchSize = 0) = 0;
687 
688  virtual void insert(const std::string& ns,
689  BSONObj obj,
690  int flags = 0,
691  const WriteConcern* wc = NULL) = 0;
692 
693  virtual void insert(const std::string& ns,
694  const std::vector<BSONObj>& v,
695  int flags = 0,
696  const WriteConcern* wc = NULL) = 0;
697 
698  virtual void remove(const std::string& ns,
699  Query query,
700  bool justOne = false,
701  const WriteConcern* wc = NULL) = 0;
702 
703  virtual void remove(const std::string& ns,
704  Query query,
705  int flags,
706  const WriteConcern* wc = NULL) = 0;
707 
708  virtual void update(const std::string& ns,
709  Query query,
710  BSONObj obj,
711  bool upsert = false,
712  bool multi = false,
713  const WriteConcern* wc = NULL) = 0;
714 
715  virtual void update(const std::string& ns,
716  Query query,
717  BSONObj obj,
718  int flags,
719  const WriteConcern* wc = NULL) = 0;
720 
721  virtual ~DBClientInterface() {}
722 
727  virtual BSONObj findOne(const std::string& ns,
728  const Query& query,
729  const BSONObj* fieldsToReturn = 0,
730  int queryOptions = 0);
731 
736  void findN(std::vector<BSONObj>& out,
737  const std::string& ns,
738  Query query,
739  int nToReturn,
740  int nToSkip = 0,
741  const BSONObj* fieldsToReturn = 0,
742  int queryOptions = 0,
743  int batchSize = 0);
744 
756  void save(const StringData& ns, const BSONObj& toSave, const WriteConcern* wc = NULL);
757 
758  virtual std::string getServerAddress() const = 0;
759 
761  virtual std::auto_ptr<DBClientCursor> getMore(const std::string& ns,
762  long long cursorId,
763  int nToReturn = 0,
764  int options = 0) = 0;
765 };
766 
771 class MONGO_CLIENT_API DBClientWithCommands : public DBClientInterface {
772 public:
775 
777  : _logLevel(logger::LogSeverity::Log()),
778  _minWireVersion(0),
779  _maxWireVersion(0),
780  _cachedAvailableOptions((enum QueryOptions)0),
781  _haveCachedAvailableOptions(false) {}
782 
789  bool simpleCommand(const std::string& dbname, BSONObj* info, const std::string& command);
790 
804  virtual bool runCommand(const std::string& dbname,
805  const BSONObj& cmd,
806  BSONObj& info,
807  int options = 0);
808 
832  void auth(const BSONObj& params);
833 
843  bool auth(const std::string& dbname,
844  const std::string& username,
845  const std::string& pwd,
846  std::string& errmsg,
847  bool digestPassword = true);
848 
856  virtual void logout(const std::string& dbname, BSONObj& info);
857 
861  virtual unsigned long long count(const std::string& ns,
862  const Query& query = Query(),
863  int options = 0,
864  int limit = 0,
865  int skip = 0);
866 
867  static std::string MONGO_CLIENT_FUNC
868  createPasswordDigest(const std::string& username, const std::string& clearTextPassword);
869 
878  virtual bool isMaster(bool& isMaster, BSONObj* info = 0);
879 
896  bool createCollection(const std::string& ns,
897  long long size = 0,
898  bool capped = false,
899  int max = 0,
900  BSONObj* info = 0);
901 
918  bool createCollectionWithOptions(const std::string& ns,
919  long long size = 0,
920  bool capped = false,
921  int max = 0,
922  const BSONObj& extraOptions = BSONObj(),
923  BSONObj* info = 0);
924 
929  std::string getLastError(
930  const std::string& db, bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
934  std::string getLastError(bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
935 
943  virtual BSONObj getLastErrorDetailed(
944  const std::string& db, bool fsync = false, bool j = false, int w = 0, int wtimeout = 0);
948  virtual BSONObj getLastErrorDetailed(bool fsync = false,
949  bool j = false,
950  int w = 0,
951  int wtimeout = 0);
952 
956  static std::string MONGO_CLIENT_FUNC getLastErrorString(const BSONObj& res);
957 
964  BSONObj getPrevError();
965 
970  bool resetError() {
971  return simpleCommand("admin", 0, "reseterror");
972  }
973 
978  virtual bool dropCollection(const std::string& ns, BSONObj* info = NULL) {
979  std::string db = nsGetDB(ns);
980  std::string coll = nsGetCollection(ns);
981  uassert(10011, "no collection name", coll.size());
982 
983  BSONObj temp;
984  if (info == NULL) {
985  info = &temp;
986  }
987 
988  bool res = runCommand(db.c_str(), BSON("drop" << coll), *info);
989  return res;
990  }
991 
995  bool repairDatabase(const std::string& dbname, BSONObj* info = 0) {
996  return simpleCommand(dbname, info, "repairDatabase");
997  }
998 
1019  bool copyDatabase(const std::string& fromdb,
1020  const std::string& todb,
1021  const std::string& fromhost = "",
1022  const std::string& mechanism = "DEFAULT",
1023  const std::string& username = "",
1024  const std::string& password = "",
1025  BSONObj* info = 0);
1026 
1032  ProfileOff = 0,
1033  ProfileSlow = 1, // log very slow (>100ms) operations
1034  ProfileAll = 2
1035 
1036  };
1037  bool setDbProfilingLevel(const std::string& dbname, ProfilingLevel level, BSONObj* info = 0);
1038  bool getDbProfilingLevel(const std::string& dbname, ProfilingLevel& level, BSONObj* info = 0);
1039 
1040 
1044  struct MROutput {
1045  MROutput(const char* collection) : out(BSON("replace" << collection)) {}
1046  MROutput(const std::string& collection) : out(BSON("replace" << collection)) {}
1047  MROutput(const BSONObj& obj) : out(obj) {}
1048 
1049  BSONObj out;
1050  };
1051  static MROutput MRInline;
1052 
1076  BSONObj mapreduce(const std::string& ns,
1077  const std::string& jsmapf,
1078  const std::string& jsreducef,
1079  Query query = Query(),
1080  MROutput output = MRInline);
1081 
1102  void group(const StringData& ns,
1103  const StringData& jsreduce,
1104  std::vector<BSONObj>* output,
1105  const BSONObj& initial = BSONObj(),
1106  const Query& query = Query(),
1107  const BSONObj& key = BSONObj(),
1108  const StringData& finalize = "");
1109 
1117  void groupWithKeyFunction(const StringData& ns,
1118  const StringData& jsreduce,
1119  std::vector<BSONObj>* output,
1120  const BSONObj& initial = BSONObj(),
1121  const Query& query = Query(),
1122  const StringData& jskey = "",
1123  const StringData& finalize = "");
1124 
1135  BSONObj distinct(const StringData& ns, const StringData& field, const Query& query = Query());
1136 
1153  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0")
1154  bool eval(const std::string& dbname,
1155  const std::string& jscode,
1156  BSONObj& info,
1157  BSONElement& retValue,
1158  BSONObj* args = 0,
1159  bool nolock = false) {
1160  return evalDeprecated(dbname, jscode, info, retValue, args, nolock);
1161  }
1162 
1163  bool evalDeprecated(const std::string& dbname,
1164  const std::string& jscode,
1165  BSONObj& info,
1166  BSONElement& retValue,
1167  BSONObj* args = 0,
1168  bool nolock = false);
1169 
1173  bool validate(const std::string& ns, bool scandata = true) {
1174  BSONObj cmd = BSON("validate" << nsGetCollection(ns) << "scandata" << scandata);
1175  BSONObj info;
1176  return runCommand(nsGetDB(ns).c_str(), cmd, info);
1177  }
1178 
1179  /* The following helpers are simply more convenient forms of eval() for certain common cases */
1180 
1181  /* invocation with no return value of interest -- with or without one simple parameter */
1182 
1183  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0")
1184  bool eval(const std::string& dbname, const std::string& jscode) {
1185  return evalDeprecated(dbname, jscode);
1186  }
1187 
1188  bool evalDeprecated(const std::string& dbname, const std::string& jscode);
1189 
1190  template <class T>
1191  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0") bool eval(const std::string& dbname,
1192  const std::string& jscode,
1193  T parm1) {
1194  return evalDeprecated(dbname, jscode, parm1);
1195  }
1196 
1197  template <class T>
1198  bool evalDeprecated(const std::string& dbname, const std::string& jscode, T parm1) {
1199  BSONObj info;
1200  BSONElement retValue;
1201  BSONObjBuilder b;
1202  b.append("0", parm1);
1203  BSONObj args = b.done();
1204  return eval(dbname, jscode, info, retValue, &args);
1205  }
1206 
1210  template <class T, class NumType>
1211  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0") bool eval(const std::string& dbname,
1212  const std::string& jscode,
1213  T parm1,
1214  NumType& ret) {
1215  return evalDeprecated(dbname, jscode, parm1, ret);
1216  }
1217 
1218  template <class T, class NumType>
1219  bool evalDeprecated(const std::string& dbname,
1220  const std::string& jscode,
1221  T parm1,
1222  NumType& ret) {
1223  BSONObj info;
1224  BSONElement retValue;
1225  BSONObjBuilder b;
1226  b.append("0", parm1);
1227  BSONObj args = b.done();
1228  if (!eval(dbname, jscode, info, retValue, &args))
1229  return false;
1230  ret = (NumType)retValue.number();
1231  return true;
1232  }
1233 
1239  std::list<std::string> getDatabaseNames();
1240 
1244  std::list<std::string> getCollectionNames(const std::string& db,
1245  const BSONObj& filter = BSONObj());
1251  std::list<BSONObj> getCollectionInfos(const std::string& db, const BSONObj& filter = BSONObj());
1252 
1264  std::auto_ptr<DBClientCursor> enumerateCollections(const std::string& db,
1265  const BSONObj& filter = BSONObj(),
1266  int batchSize = 0);
1267 
1268  bool exists(const std::string& ns);
1269 
1279  void createIndex(const StringData& ns, const BSONObj& keys) {
1280  return createIndex(ns, IndexSpec().addKeys(keys));
1281  }
1282 
1291  virtual void createIndex(const StringData& ns, const IndexSpec& descriptor);
1292 
1293  virtual std::list<BSONObj> getIndexSpecs(const std::string& ns, int options = 0);
1294 
1299  virtual std::list<std::string> getIndexNames(const std::string& ns, int options = 0);
1300 
1301  virtual std::auto_ptr<DBClientCursor> enumerateIndexes(const std::string& ns,
1302  int options = 0,
1303  int batchSize = 0);
1304 
1305  virtual void dropIndex(const std::string& ns, BSONObj keys);
1306  virtual void dropIndex(const std::string& ns, const std::string& indexName);
1307 
1311  virtual void dropIndexes(const std::string& ns);
1312 
1313  virtual void reIndex(const std::string& ns);
1314 
1315  static std::string genIndexName(const BSONObj& keys);
1316 
1318  virtual bool dropDatabase(const std::string& dbname, BSONObj* info = 0) {
1319  bool ret = simpleCommand(dbname, info, "dropDatabase");
1320  return ret;
1321  }
1322 
1323  virtual std::string toString() const = 0;
1324 
1332  typedef stdx::function<void(BSONObjBuilder*)> RunCommandHookFunc;
1333  virtual void setRunCommandHook(RunCommandHookFunc func);
1334  RunCommandHookFunc getRunCommandHook() const {
1335  return _runCommandHook;
1336  }
1337 
1342  typedef stdx::function<void(const BSONObj&, const std::string&)> PostRunCommandHookFunc;
1343  virtual void setPostRunCommandHook(PostRunCommandHookFunc func);
1344  PostRunCommandHookFunc getPostRunCommandHook() const {
1345  return _postRunCommandHook;
1346  }
1347 
1348 
1349 protected:
1351  bool isOk(const BSONObj&);
1352 
1354  bool isNotMasterErrorString(const BSONElement& e);
1355 
1356  BSONObj _countCmd(const std::string& ns, const Query& query, int options, int limit, int skip);
1357 
1362  QueryOptions availableOptions();
1363 
1364  virtual QueryOptions _lookupAvailableOptions();
1365 
1366  virtual void _auth(const BSONObj& params);
1367 
1373  bool _authMongoCR(const std::string& dbname,
1374  const std::string& username,
1375  const std::string& pwd,
1376  BSONObj* info,
1377  bool digestPassword);
1378 
1384  bool _authX509(const std::string& dbname, const std::string& username, BSONObj* info);
1385 
1389  RunCommandHookFunc _runCommandHook;
1390  PostRunCommandHookFunc _postRunCommandHook;
1391  int _minWireVersion;
1392  int _maxWireVersion;
1393 
1394 
1395 private:
1396  enum QueryOptions _cachedAvailableOptions;
1397  bool _haveCachedAvailableOptions;
1398 
1399  void _buildGroupObj(const StringData& ns,
1400  const StringData& jsreduce,
1401  const BSONObj& initial,
1402  const Query& query,
1403  const StringData& finalize,
1404  BSONObjBuilder* groupObj);
1405 
1406  void _runGroup(const StringData& ns,
1407  const BSONObj& group,
1408  const Query& query,
1409  std::vector<BSONObj>* output);
1410 
1411  std::auto_ptr<DBClientCursor> _legacyCollectionInfo(const std::string& db,
1412  const BSONObj& filter,
1413  int batchSize);
1414 };
1415 
1416 class DBClientWriter;
1417 class WriteOperation;
1418 
1422 class MONGO_CLIENT_API DBClientBase : public DBClientWithCommands, public DBConnector {
1423  friend class BulkOperationBuilder;
1424 
1425 protected:
1426  static AtomicInt64 ConnectionIdSequence;
1427  long long _connectionId; // unique connection id for this connection
1428  const boost::scoped_ptr<DBClientWriter> _wireProtocolWriter;
1429  const boost::scoped_ptr<DBClientWriter> _commandWriter;
1430  WriteConcern _writeConcern;
1431  int _maxBsonObjectSize;
1432  int _maxMessageSizeBytes;
1433  int _maxWriteBatchSize;
1434  void _write(const std::string& ns,
1435  const std::vector<WriteOperation*>& writes,
1436  bool ordered,
1437  bool bypassDocumentValidation,
1438  const WriteConcern* writeConcern,
1439  WriteResult* writeResult);
1440 
1441 public:
1442  static const uint64_t INVALID_SOCK_CREATION_TIME;
1443 
1444  DBClientBase();
1445 
1446  // Required because compiler can't generate a destructor for the _writer
1447  // as it is an incomplete type.
1448  virtual ~DBClientBase();
1449 
1450  long long getConnectionId() const {
1451  return _connectionId;
1452  }
1453 
1454  const WriteConcern& getWriteConcern() const {
1455  return _writeConcern;
1456  }
1457  void setWriteConcern(const WriteConcern& w) {
1458  _writeConcern = w;
1459  }
1460 
1461  void setWireVersions(int minWireVersion, int maxWireVersion) {
1462  _minWireVersion = minWireVersion;
1463  _maxWireVersion = maxWireVersion;
1464  }
1465 
1466  virtual int getMinWireVersion() {
1467  return _minWireVersion;
1468  }
1469  virtual int getMaxWireVersion() {
1470  return _maxWireVersion;
1471  }
1472  int getMaxBsonObjectSize() {
1473  return _maxBsonObjectSize;
1474  }
1475  int getMaxMessageSizeBytes() {
1476  return _maxMessageSizeBytes;
1477  }
1478  int getMaxWriteBatchSize() {
1479  return _maxWriteBatchSize;
1480  }
1481 
1497  virtual std::auto_ptr<DBClientCursor> query(const std::string& ns,
1498  Query query,
1499  int nToReturn = 0,
1500  int nToSkip = 0,
1501  const BSONObj* fieldsToReturn = 0,
1502  int queryOptions = 0,
1503  int batchSize = 0);
1504 
1524  virtual void parallelScan(const StringData& ns,
1525  int numCursors,
1526  std::vector<DBClientCursor*>* cursors,
1527  stdx::function<DBClientBase*()> connectionFactory);
1528 
1529  virtual std::auto_ptr<DBClientCursor> aggregate(const std::string& ns,
1530  const BSONObj& pipeline,
1531  const BSONObj* aggregateOptions = NULL,
1532  int queryOptions = 0);
1533 
1534 
1543  virtual unsigned long long query(stdx::function<void(const BSONObj&)> f,
1544  const std::string& ns,
1545  Query query,
1546  const BSONObj* fieldsToReturn = 0,
1547  int queryOptions = 0);
1548 
1549  virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
1550  const std::string& ns,
1551  Query query,
1552  const BSONObj* fieldsToReturn = 0,
1553  int queryOptions = 0);
1554 
1555 
1561  virtual std::auto_ptr<DBClientCursor> getMore(const std::string& ns,
1562  long long cursorId,
1563  int nToReturn = 0,
1564  int options = 0);
1565 
1569  virtual void insert(const std::string& ns,
1570  BSONObj obj,
1571  int flags = 0,
1572  const WriteConcern* wc = NULL);
1573 
1577  virtual void insert(const std::string& ns,
1578  const std::vector<BSONObj>& v,
1579  int flags = 0,
1580  const WriteConcern* wc = NULL);
1581 
1585  virtual void update(const std::string& ns,
1586  Query query,
1587  BSONObj obj,
1588  bool upsert = false,
1589  bool multi = false,
1590  const WriteConcern* wc = NULL);
1591 
1592  virtual void update(
1593  const std::string& ns, Query query, BSONObj obj, int flags, const WriteConcern* wc = NULL);
1594 
1609  BSONObj findAndModify(const StringData& ns,
1610  const BSONObj& query,
1611  const BSONObj& update,
1612  bool upsert = false,
1613  bool returnNew = false,
1614  const BSONObj& sort = BSONObj(),
1615  const BSONObj& fields = BSONObj(),
1616  const WriteConcern* wc = NULL,
1617  bool bypassDocumentValidation = false);
1618 
1630  BSONObj findAndRemove(const StringData& ns,
1631  const BSONObj& query,
1632  const BSONObj& sort = BSONObj(),
1633  const BSONObj& fields = BSONObj(),
1634  const WriteConcern* wc = NULL);
1635 
1643  virtual BulkOperationBuilder initializeUnorderedBulkOp(const std::string& ns);
1644 
1652  virtual BulkOperationBuilder initializeOrderedBulkOp(const std::string& ns);
1653 
1658  virtual void remove(const std::string& ns,
1659  Query q,
1660  bool justOne = 0,
1661  const WriteConcern* wc = NULL);
1662 
1663  virtual void remove(const std::string& ns,
1664  Query query,
1665  int flags,
1666  const WriteConcern* wc = NULL);
1667 
1668  virtual bool isFailed() const = 0;
1669 
1673  virtual bool isStillConnected() = 0;
1674 
1675  virtual void killCursor(long long cursorID) = 0;
1676 
1677  virtual bool callRead(Message& toSend, Message& response) = 0;
1678  // virtual bool callWrite( Message& toSend , Message& response ) = 0; // TODO: add this if
1679  // needed
1680 
1681  virtual ConnectionString::ConnectionType type() const = 0;
1682 
1683  virtual double getSoTimeout() const = 0;
1684 
1685  virtual uint64_t getSockCreationMicroSec() const {
1686  return INVALID_SOCK_CREATION_TIME;
1687  }
1688 
1689  virtual void reset() {}
1690 
1691 private:
1692  void _findAndModify(const StringData& ns,
1693  const BSONObj& query,
1694  const BSONObj& update,
1695  const BSONObj& sort,
1696  bool returnNew,
1697  bool upsert,
1698  const BSONObj& fields,
1699  const WriteConcern* wc,
1700  bool bypassDocumentValidation,
1701  BSONObjBuilder* out);
1702 
1703 }; // DBClientBase
1704 
1705 class DBClientReplicaSet;
1706 
1707 class MONGO_CLIENT_API ConnectException : public UserException {
1708 public:
1709  ConnectException(std::string msg) : UserException(9000, msg) {}
1710 };
1711 
1716 class MONGO_CLIENT_API DBClientConnection : public DBClientBase {
1717 public:
1718  using DBClientBase::query;
1719 
1726  DBClientConnection(bool _autoReconnect = false,
1727  DBClientReplicaSet* cp = 0,
1728  double so_timeout = 0);
1729 
1730  virtual ~DBClientConnection() {
1731  _numConnections.fetchAndAdd(-1);
1732  }
1733 
1743  virtual bool connect(const HostAndPort& server, std::string& errmsg);
1744 
1746  bool connect(const std::string& server, std::string& errmsg) {
1747  return connect(HostAndPort(server), errmsg);
1748  }
1749 
1759  void connect(const std::string& serverHostname) {
1760  std::string errmsg;
1761  if (!connect(HostAndPort(serverHostname), errmsg))
1762  throw ConnectException(std::string("can't connect ") + errmsg);
1763  }
1764 
1772  virtual void logout(const std::string& dbname, BSONObj& info);
1773 
1774  virtual std::auto_ptr<DBClientCursor> query(const std::string& ns,
1775  Query query = Query(),
1776  int nToReturn = 0,
1777  int nToSkip = 0,
1778  const BSONObj* fieldsToReturn = 0,
1779  int queryOptions = 0,
1780  int batchSize = 0);
1781 
1782  virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
1783  const std::string& ns,
1784  Query query,
1785  const BSONObj* fieldsToReturn,
1786  int queryOptions);
1787 
1788  virtual bool runCommand(const std::string& dbname,
1789  const BSONObj& cmd,
1790  BSONObj& info,
1791  int options = 0);
1792 
1797  bool isFailed() const {
1798  return _failed;
1799  }
1800 
1802  return p ? p->isStillConnected() : true;
1803  }
1804 
1805  MessagingPort& port() {
1806  verify(p);
1807  return *p;
1808  }
1809 
1810  std::string toString() const {
1811  std::stringstream ss;
1812  ss << _serverString;
1813  if (!_serverAddrString.empty())
1814  ss << " (" << _serverAddrString << ")";
1815  if (_failed)
1816  ss << " failed";
1817  return ss.str();
1818  }
1819 
1820  std::string getServerAddress() const {
1821  return _serverString;
1822  }
1823  const HostAndPort& getServerHostAndPort() const {
1824  return _server;
1825  }
1826 
1827  virtual void killCursor(long long cursorID);
1828  virtual bool callRead(Message& toSend, Message& response) {
1829  return call(toSend, response);
1830  }
1831  virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0);
1832  virtual bool recv(Message& m);
1833  virtual void checkResponse(const char* data,
1834  int nReturned,
1835  bool* retry = NULL,
1836  std::string* host = NULL);
1837  virtual bool call(Message& toSend,
1838  Message& response,
1839  bool assertOk = true,
1840  std::string* actualServer = 0);
1841  virtual ConnectionString::ConnectionType type() const {
1842  return ConnectionString::MASTER;
1843  }
1844  void setSoTimeout(double timeout);
1845  double getSoTimeout() const {
1846  return _so_timeout;
1847  }
1848 
1849  virtual bool lazySupported() const {
1850  return true;
1851  }
1852 
1853  static int MONGO_CLIENT_FUNC getNumConnections() {
1854  return _numConnections.load();
1855  }
1856 
1861  void setParentReplSetName(const std::string& replSetName);
1862 
1863  static void MONGO_CLIENT_FUNC setLazyKillCursor(bool lazy) {
1864  _lazyKillCursor = lazy;
1865  }
1866  static bool MONGO_CLIENT_FUNC getLazyKillCursor() {
1867  return _lazyKillCursor;
1868  }
1869 
1870  uint64_t getSockCreationMicroSec() const;
1871 
1872 protected:
1873  virtual void _auth(const BSONObj& params);
1874  virtual void sayPiggyBack(Message& toSend);
1875 
1876  boost::scoped_ptr<MessagingPort> p;
1877  boost::scoped_ptr<SockAddr> server;
1878  bool _failed;
1879  const bool autoReconnect;
1880  Backoff autoReconnectBackoff;
1881  HostAndPort _server; // remember for reconnects
1882  std::string _serverString; // server host and port
1883  std::string _serverAddrString; // resolved ip of server
1884  void _checkConnection();
1885 
1886  // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
1887  void checkConnection() {
1888  if (_failed)
1889  _checkConnection();
1890  }
1891 
1892  std::map<std::string, BSONObj> authCache;
1893  double _so_timeout;
1894  bool _connect(std::string& errmsg);
1895 
1896  static AtomicInt32 _numConnections;
1897  static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
1898 
1899 #ifdef MONGO_SSL
1900  SSLManagerInterface* sslManager();
1901 #endif
1902 
1903 private:
1909  void handleNotMasterResponse(const BSONElement& elemToCheck);
1910 
1911  // Contains the string for the replica set name of the host this is connected to.
1912  // Should be empty if this connection is not pointing to a replica set member.
1913  std::string _parentReplSetName;
1914 };
1915 
1918 MONGO_CLIENT_API bool MONGO_CLIENT_FUNC serverAlive(const std::string& uri);
1919 
1920 MONGO_CLIENT_API BSONElement MONGO_CLIENT_FUNC getErrField(const BSONObj& result);
1921 MONGO_CLIENT_API bool MONGO_CLIENT_FUNC hasErrField(const BSONObj& result);
1922 
1923 MONGO_CLIENT_API inline std::ostream& MONGO_CLIENT_FUNC
1924 operator<<(std::ostream& s, const Query& q) {
1925  return s << q.toString();
1926 }
1927 
1928 } // 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:76
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:771
MONGO_CLIENT_API std::string MONGO_CLIENT_FUNC nsGetDB(const std::string &ns)
Definition: message.h:305
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents...
Definition: string_data.h:43
QueryOption_SlaveOk
allow query of replica slave.
Definition: dbclientinterface.h:59
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
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:91
BSON classes.
This implicitly converts from char*, string, and BSONObj to be an argument to mapreduce You shouldn't...
Definition: dbclientinterface.h:1044
MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0") bool eval(const std
eval invocation with one parm to server and one numeric field (either int or double) returned ...
Definition: dbclientinterface.h:1211
ReadPreference_SecondaryOnly
Read from secondary if available, otherwise error.
Definition: dbclientinterface.h:129
ReadPreference_SecondaryPreferred
Read from a secondary if available, otherwise read from the primary.
Definition: dbclientinterface.h:129
bool repairDatabase(const std::string &dbname, BSONObj *info=0)
Perform a repair and compaction of the specified database.
Definition: dbclientinterface.h:995
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:124
virtual bool dropCollection(const std::string &ns, BSONObj *info=NULL)
Delete the specified collection.
Definition: dbclientinterface.h:978
Represents a full query description, including all options required for the query to be passed on to ...
Definition: dbclientinterface.h:548
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:1342
void createIndex(const StringData &ns, const BSONObj &keys)
Create an index on the collection 'ns' as described by the given keys.
Definition: dbclientinterface.h:1279
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:631
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:1318
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:1716
QueryOption_PartialResults
When sharded, this means its ok to return partial results Usually we will fail a query if all require...
Definition: dbclientinterface.h:97
bool connect(const std::string &server, std::string &errmsg)
Compatibility connect now that HostAndPort has an explicit constructor.
Definition: dbclientinterface.h:1746
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:186
bool isFailed() const
Definition: dbclientinterface.h:1797
QueryOption_NoCursorTimeout
The server normally times out idle cursors after an inactivity period to prevent excess memory uses S...
Definition: dbclientinterface.h:75
logger::LogSeverity _logLevel
controls how chatty the client is about network errors & such.
Definition: dbclientinterface.h:774
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:1759
Definition: assert_util.h:145
iterate over objects in current batch only - will not cause a network call
Definition: dbclientcursor.h:282
ReadPreference_PrimaryOnly
Read from primary only.
Definition: dbclientinterface.h:129
Name of a process on the network.
Definition: hostandport.h:37
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:1332
The interface that any db connection should implement.
Definition: dbclientinterface.h:678
bool validate(const std::string &ns, bool scandata=true)
validate a collection, checking for errors and reporting back statistics.
Definition: dbclientinterface.h:1173
double number() const
Retrieve the numeric value of the element.
Definition: bsonelement.h:290
Definition: dbclient_writer.h:27
Definition: dbclientinterface.h:1707
QueryOption_AwaitData
Use with QueryOption_CursorTailable.
Definition: dbclientinterface.h:80
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:403
ReadPreference_Nearest
Read from any member.
Definition: dbclientinterface.h:129
abstract class that implements the core db operations
Definition: dbclientinterface.h:1422
Definition: index_spec.h:29
bool resetError()
Reset the previous error state for this connection (accessed via getLastError and getPrevError)...
Definition: dbclientinterface.h:970
bool isStillConnected()
if not checked recently, checks whether the underlying socket/sockets are still valid ...
Definition: dbclientinterface.h:1801
RunCommandHookFunc _runCommandHook
These functions will be executed by the driver on runCommand calls.
Definition: dbclientinterface.h:1389
ReadPreference_PrimaryPreferred
Read from primary if available, otherwise a secondary.
Definition: dbclientinterface.h:129
ProfilingLevel
The Mongo database provides built-in performance profiling capabilities.
Definition: dbclientinterface.h:1031
Query & sort(const std::string &field, int asc=1)
Add a sort (ORDER BY) criteria to the query expression.
Definition: dbclientinterface.h:431
interface that handles communication with the db
Definition: dbclientinterface.h:646
Definition: dbclientinterface.h:300
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
Representation of the severity / priority of a log message.
Definition: log_severity.h:33
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:55
Definition: message_port.h:74