MongoDB C++ Driver  legacy-1.0.7
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 
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:
774  logger::LogSeverity _logLevel;
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 
1150  BSONObj findAndModify(const StringData& ns,
1151  const BSONObj& query,
1152  const BSONObj& update,
1153  bool upsert = false,
1154  bool returnNew = false,
1155  const BSONObj& sort = BSONObj(),
1156  const BSONObj& fields = BSONObj());
1157 
1168  BSONObj findAndRemove(const StringData& ns,
1169  const BSONObj& query,
1170  const BSONObj& sort = BSONObj(),
1171  const BSONObj& fields = BSONObj());
1172 
1189  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0")
1190  bool eval(const std::string& dbname,
1191  const std::string& jscode,
1192  BSONObj& info,
1193  BSONElement& retValue,
1194  BSONObj* args = 0,
1195  bool nolock = false) {
1196  return evalDeprecated(dbname, jscode, info, retValue, args, nolock);
1197  }
1198 
1199  bool evalDeprecated(const std::string& dbname,
1200  const std::string& jscode,
1201  BSONObj& info,
1202  BSONElement& retValue,
1203  BSONObj* args = 0,
1204  bool nolock = false);
1205 
1209  bool validate(const std::string& ns, bool scandata = true) {
1210  BSONObj cmd = BSON("validate" << nsGetCollection(ns) << "scandata" << scandata);
1211  BSONObj info;
1212  return runCommand(nsGetDB(ns).c_str(), cmd, info);
1213  }
1214 
1215  /* The following helpers are simply more convenient forms of eval() for certain common cases */
1216 
1217  /* invocation with no return value of interest -- with or without one simple parameter */
1218 
1219  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0")
1220  bool eval(const std::string& dbname, const std::string& jscode) {
1221  return evalDeprecated(dbname, jscode);
1222  }
1223 
1224  bool evalDeprecated(const std::string& dbname, const std::string& jscode);
1225 
1226  template <class T>
1227  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0") bool eval(const std::string& dbname,
1228  const std::string& jscode,
1229  T parm1) {
1230  return evalDeprecated(dbname, jscode, parm1);
1231  }
1232 
1233  template <class T>
1234  bool evalDeprecated(const std::string& dbname, const std::string& jscode, T parm1) {
1235  BSONObj info;
1236  BSONElement retValue;
1237  BSONObjBuilder b;
1238  b.append("0", parm1);
1239  BSONObj args = b.done();
1240  return eval(dbname, jscode, info, retValue, &args);
1241  }
1242 
1246  template <class T, class NumType>
1247  MONGO_CLIENT_DEPRECATED("deprecated in MongoDB 3.0") bool eval(const std::string& dbname,
1248  const std::string& jscode,
1249  T parm1,
1250  NumType& ret) {
1251  return evalDeprecated(dbname, jscode, parm1, ret);
1252  }
1253 
1254  template <class T, class NumType>
1255  bool evalDeprecated(const std::string& dbname,
1256  const std::string& jscode,
1257  T parm1,
1258  NumType& ret) {
1259  BSONObj info;
1260  BSONElement retValue;
1261  BSONObjBuilder b;
1262  b.append("0", parm1);
1263  BSONObj args = b.done();
1264  if (!eval(dbname, jscode, info, retValue, &args))
1265  return false;
1266  ret = (NumType)retValue.number();
1267  return true;
1268  }
1269 
1275  std::list<std::string> getDatabaseNames();
1276 
1280  std::list<std::string> getCollectionNames(const std::string& db,
1281  const BSONObj& filter = BSONObj());
1287  std::list<BSONObj> getCollectionInfos(const std::string& db, const BSONObj& filter = BSONObj());
1288 
1300  std::auto_ptr<DBClientCursor> enumerateCollections(const std::string& db,
1301  const BSONObj& filter = BSONObj(),
1302  int batchSize = 0);
1303 
1304  bool exists(const std::string& ns);
1305 
1315  void createIndex(const StringData& ns, const BSONObj& keys) {
1316  return createIndex(ns, IndexSpec().addKeys(keys));
1317  }
1318 
1327  virtual void createIndex(const StringData& ns, const IndexSpec& descriptor);
1328 
1329  virtual std::list<BSONObj> getIndexSpecs(const std::string& ns, int options = 0);
1330 
1335  virtual std::list<std::string> getIndexNames(const std::string& ns, int options = 0);
1336 
1337  virtual std::auto_ptr<DBClientCursor> enumerateIndexes(const std::string& ns,
1338  int options = 0,
1339  int batchSize = 0);
1340 
1341  virtual void dropIndex(const std::string& ns, BSONObj keys);
1342  virtual void dropIndex(const std::string& ns, const std::string& indexName);
1343 
1347  virtual void dropIndexes(const std::string& ns);
1348 
1349  virtual void reIndex(const std::string& ns);
1350 
1351  static std::string genIndexName(const BSONObj& keys);
1352 
1354  virtual bool dropDatabase(const std::string& dbname, BSONObj* info = 0) {
1355  bool ret = simpleCommand(dbname, info, "dropDatabase");
1356  return ret;
1357  }
1358 
1359  virtual std::string toString() const = 0;
1360 
1368  typedef stdx::function<void(BSONObjBuilder*)> RunCommandHookFunc;
1369  virtual void setRunCommandHook(RunCommandHookFunc func);
1370  RunCommandHookFunc getRunCommandHook() const {
1371  return _runCommandHook;
1372  }
1373 
1378  typedef stdx::function<void(const BSONObj&, const std::string&)> PostRunCommandHookFunc;
1379  virtual void setPostRunCommandHook(PostRunCommandHookFunc func);
1380  PostRunCommandHookFunc getPostRunCommandHook() const {
1381  return _postRunCommandHook;
1382  }
1383 
1384 
1385 protected:
1387  bool isOk(const BSONObj&);
1388 
1390  bool isNotMasterErrorString(const BSONElement& e);
1391 
1392  BSONObj _countCmd(const std::string& ns, const Query& query, int options, int limit, int skip);
1393 
1398  QueryOptions availableOptions();
1399 
1400  virtual QueryOptions _lookupAvailableOptions();
1401 
1402  virtual void _auth(const BSONObj& params);
1403 
1409  bool _authMongoCR(const std::string& dbname,
1410  const std::string& username,
1411  const std::string& pwd,
1412  BSONObj* info,
1413  bool digestPassword);
1414 
1420  bool _authX509(const std::string& dbname, const std::string& username, BSONObj* info);
1421 
1425  RunCommandHookFunc _runCommandHook;
1426  PostRunCommandHookFunc _postRunCommandHook;
1427  int _minWireVersion;
1428  int _maxWireVersion;
1429 
1430 
1431 private:
1432  enum QueryOptions _cachedAvailableOptions;
1433  bool _haveCachedAvailableOptions;
1434 
1435  void _buildGroupObj(const StringData& ns,
1436  const StringData& jsreduce,
1437  const BSONObj& initial,
1438  const Query& query,
1439  const StringData& finalize,
1440  BSONObjBuilder* groupObj);
1441 
1442  void _runGroup(const StringData& ns,
1443  const BSONObj& group,
1444  const Query& query,
1445  std::vector<BSONObj>* output);
1446 
1447  void _findAndModify(const StringData& ns,
1448  const BSONObj& query,
1449  const BSONObj& update,
1450  const BSONObj& sort,
1451  bool returnNew,
1452  bool upsert,
1453  const BSONObj& fields,
1454  BSONObjBuilder* out);
1455 
1456  std::auto_ptr<DBClientCursor> _legacyCollectionInfo(const std::string& db,
1457  const BSONObj& filter,
1458  int batchSize);
1459 };
1460 
1461 class DBClientWriter;
1462 class WriteOperation;
1463 
1467 class MONGO_CLIENT_API DBClientBase : public DBClientWithCommands, public DBConnector {
1468  friend class BulkOperationBuilder;
1469 
1470 protected:
1471  static AtomicInt64 ConnectionIdSequence;
1472  long long _connectionId; // unique connection id for this connection
1473  const boost::scoped_ptr<DBClientWriter> _wireProtocolWriter;
1474  const boost::scoped_ptr<DBClientWriter> _commandWriter;
1475  WriteConcern _writeConcern;
1476  int _maxBsonObjectSize;
1477  int _maxMessageSizeBytes;
1478  int _maxWriteBatchSize;
1479  void _write(const std::string& ns,
1480  const std::vector<WriteOperation*>& writes,
1481  bool ordered,
1482  const WriteConcern* writeConcern,
1483  WriteResult* writeResult);
1484 
1485 public:
1486  static const uint64_t INVALID_SOCK_CREATION_TIME;
1487 
1488  DBClientBase();
1489 
1490  // Required because compiler can't generate a destructor for the _writer
1491  // as it is an incomplete type.
1492  virtual ~DBClientBase();
1493 
1494  long long getConnectionId() const {
1495  return _connectionId;
1496  }
1497 
1498  const WriteConcern& getWriteConcern() const {
1499  return _writeConcern;
1500  }
1501  void setWriteConcern(const WriteConcern& w) {
1502  _writeConcern = w;
1503  }
1504 
1505  void setWireVersions(int minWireVersion, int maxWireVersion) {
1506  _minWireVersion = minWireVersion;
1507  _maxWireVersion = maxWireVersion;
1508  }
1509 
1510  int getMinWireVersion() {
1511  return _minWireVersion;
1512  }
1513  int getMaxWireVersion() {
1514  return _maxWireVersion;
1515  }
1516  int getMaxBsonObjectSize() {
1517  return _maxBsonObjectSize;
1518  }
1519  int getMaxMessageSizeBytes() {
1520  return _maxMessageSizeBytes;
1521  }
1522  int getMaxWriteBatchSize() {
1523  return _maxWriteBatchSize;
1524  }
1525 
1541  virtual std::auto_ptr<DBClientCursor> query(const std::string& ns,
1542  Query query,
1543  int nToReturn = 0,
1544  int nToSkip = 0,
1545  const BSONObj* fieldsToReturn = 0,
1546  int queryOptions = 0,
1547  int batchSize = 0);
1548 
1568  virtual void parallelScan(const StringData& ns,
1569  int numCursors,
1570  std::vector<DBClientCursor*>* cursors,
1571  stdx::function<DBClientBase*()> connectionFactory);
1572 
1573  virtual std::auto_ptr<DBClientCursor> aggregate(const std::string& ns,
1574  const BSONObj& pipeline,
1575  const BSONObj* aggregateOptions = NULL,
1576  int queryOptions = 0);
1577 
1578 
1587  virtual unsigned long long query(stdx::function<void(const BSONObj&)> f,
1588  const std::string& ns,
1589  Query query,
1590  const BSONObj* fieldsToReturn = 0,
1591  int queryOptions = 0);
1592 
1593  virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
1594  const std::string& ns,
1595  Query query,
1596  const BSONObj* fieldsToReturn = 0,
1597  int queryOptions = 0);
1598 
1599 
1605  virtual std::auto_ptr<DBClientCursor> getMore(const std::string& ns,
1606  long long cursorId,
1607  int nToReturn = 0,
1608  int options = 0);
1609 
1613  virtual void insert(const std::string& ns,
1614  BSONObj obj,
1615  int flags = 0,
1616  const WriteConcern* wc = NULL);
1617 
1621  virtual void insert(const std::string& ns,
1622  const std::vector<BSONObj>& v,
1623  int flags = 0,
1624  const WriteConcern* wc = NULL);
1625 
1629  virtual void update(const std::string& ns,
1630  Query query,
1631  BSONObj obj,
1632  bool upsert = false,
1633  bool multi = false,
1634  const WriteConcern* wc = NULL);
1635 
1636  virtual void update(
1637  const std::string& ns, Query query, BSONObj obj, int flags, const WriteConcern* wc = NULL);
1638 
1646  virtual BulkOperationBuilder initializeUnorderedBulkOp(const std::string& ns);
1647 
1655  virtual BulkOperationBuilder initializeOrderedBulkOp(const std::string& ns);
1656 
1661  virtual void remove(const std::string& ns,
1662  Query q,
1663  bool justOne = 0,
1664  const WriteConcern* wc = NULL);
1665 
1666  virtual void remove(const std::string& ns,
1667  Query query,
1668  int flags,
1669  const WriteConcern* wc = NULL);
1670 
1671  virtual bool isFailed() const = 0;
1672 
1676  virtual bool isStillConnected() = 0;
1677 
1678  virtual void killCursor(long long cursorID) = 0;
1679 
1680  virtual bool callRead(Message& toSend, Message& response) = 0;
1681  // virtual bool callWrite( Message& toSend , Message& response ) = 0; // TODO: add this if
1682  // needed
1683 
1684  virtual ConnectionString::ConnectionType type() const = 0;
1685 
1686  virtual double getSoTimeout() const = 0;
1687 
1688  virtual uint64_t getSockCreationMicroSec() const {
1689  return INVALID_SOCK_CREATION_TIME;
1690  }
1691 
1692  virtual void reset() {}
1693 
1694 }; // DBClientBase
1695 
1696 class DBClientReplicaSet;
1697 
1698 class MONGO_CLIENT_API ConnectException : public UserException {
1699 public:
1700  ConnectException(std::string msg) : UserException(9000, msg) {}
1701 };
1702 
1707 class MONGO_CLIENT_API DBClientConnection : public DBClientBase {
1708 public:
1709  using DBClientBase::query;
1710 
1717  DBClientConnection(bool _autoReconnect = false,
1718  DBClientReplicaSet* cp = 0,
1719  double so_timeout = 0);
1720 
1721  virtual ~DBClientConnection() {
1722  _numConnections.fetchAndAdd(-1);
1723  }
1724 
1734  virtual bool connect(const HostAndPort& server, std::string& errmsg);
1735 
1737  bool connect(const std::string& server, std::string& errmsg) {
1738  return connect(HostAndPort(server), errmsg);
1739  }
1740 
1750  void connect(const std::string& serverHostname) {
1751  std::string errmsg;
1752  if (!connect(HostAndPort(serverHostname), errmsg))
1753  throw ConnectException(std::string("can't connect ") + errmsg);
1754  }
1755 
1763  virtual void logout(const std::string& dbname, BSONObj& info);
1764 
1765  virtual std::auto_ptr<DBClientCursor> query(const std::string& ns,
1766  Query query = Query(),
1767  int nToReturn = 0,
1768  int nToSkip = 0,
1769  const BSONObj* fieldsToReturn = 0,
1770  int queryOptions = 0,
1771  int batchSize = 0);
1772 
1773  virtual unsigned long long query(stdx::function<void(DBClientCursorBatchIterator&)> f,
1774  const std::string& ns,
1775  Query query,
1776  const BSONObj* fieldsToReturn,
1777  int queryOptions);
1778 
1779  virtual bool runCommand(const std::string& dbname,
1780  const BSONObj& cmd,
1781  BSONObj& info,
1782  int options = 0);
1783 
1788  bool isFailed() const {
1789  return _failed;
1790  }
1791 
1793  return p ? p->isStillConnected() : true;
1794  }
1795 
1796  MessagingPort& port() {
1797  verify(p);
1798  return *p;
1799  }
1800 
1801  std::string toString() const {
1802  std::stringstream ss;
1803  ss << _serverString;
1804  if (!_serverAddrString.empty())
1805  ss << " (" << _serverAddrString << ")";
1806  if (_failed)
1807  ss << " failed";
1808  return ss.str();
1809  }
1810 
1811  std::string getServerAddress() const {
1812  return _serverString;
1813  }
1814  const HostAndPort& getServerHostAndPort() const {
1815  return _server;
1816  }
1817 
1818  virtual void killCursor(long long cursorID);
1819  virtual bool callRead(Message& toSend, Message& response) {
1820  return call(toSend, response);
1821  }
1822  virtual void say(Message& toSend, bool isRetry = false, std::string* actualServer = 0);
1823  virtual bool recv(Message& m);
1824  virtual void checkResponse(const char* data,
1825  int nReturned,
1826  bool* retry = NULL,
1827  std::string* host = NULL);
1828  virtual bool call(Message& toSend,
1829  Message& response,
1830  bool assertOk = true,
1831  std::string* actualServer = 0);
1832  virtual ConnectionString::ConnectionType type() const {
1833  return ConnectionString::MASTER;
1834  }
1835  void setSoTimeout(double timeout);
1836  double getSoTimeout() const {
1837  return _so_timeout;
1838  }
1839 
1840  virtual bool lazySupported() const {
1841  return true;
1842  }
1843 
1844  static int MONGO_CLIENT_FUNC getNumConnections() {
1845  return _numConnections.load();
1846  }
1847 
1852  void setParentReplSetName(const std::string& replSetName);
1853 
1854  static void MONGO_CLIENT_FUNC setLazyKillCursor(bool lazy) {
1855  _lazyKillCursor = lazy;
1856  }
1857  static bool MONGO_CLIENT_FUNC getLazyKillCursor() {
1858  return _lazyKillCursor;
1859  }
1860 
1861  uint64_t getSockCreationMicroSec() const;
1862 
1863 protected:
1864  virtual void _auth(const BSONObj& params);
1865  virtual void sayPiggyBack(Message& toSend);
1866 
1867  boost::scoped_ptr<MessagingPort> p;
1868  boost::scoped_ptr<SockAddr> server;
1869  bool _failed;
1870  const bool autoReconnect;
1871  Backoff autoReconnectBackoff;
1872  HostAndPort _server; // remember for reconnects
1873  std::string _serverString; // server host and port
1874  std::string _serverAddrString; // resolved ip of server
1875  void _checkConnection();
1876 
1877  // throws SocketException if in failed state and not reconnecting or if waiting to reconnect
1878  void checkConnection() {
1879  if (_failed)
1880  _checkConnection();
1881  }
1882 
1883  std::map<std::string, BSONObj> authCache;
1884  double _so_timeout;
1885  bool _connect(std::string& errmsg);
1886 
1887  static AtomicInt32 _numConnections;
1888  static bool _lazyKillCursor; // lazy means we piggy back kill cursors on next op
1889 
1890 #ifdef MONGO_SSL
1891  SSLManagerInterface* sslManager();
1892 #endif
1893 
1894 private:
1900  void handleNotMasterResponse(const BSONElement& elemToCheck);
1901 
1902  // Contains the string for the replica set name of the host this is connected to.
1903  // Should be empty if this connection is not pointing to a replica set member.
1904  std::string _parentReplSetName;
1905 };
1906 
1909 MONGO_CLIENT_API bool MONGO_CLIENT_FUNC serverAlive(const std::string& uri);
1910 
1911 MONGO_CLIENT_API BSONElement MONGO_CLIENT_FUNC getErrField(const BSONObj& result);
1912 MONGO_CLIENT_API bool MONGO_CLIENT_FUNC hasErrField(const BSONObj& result);
1913 
1914 MONGO_CLIENT_API inline std::ostream& MONGO_CLIENT_FUNC
1915 operator<<(std::ostream& s, const Query& q) {
1916  return s << q.toString();
1917 }
1918 
1919 } // 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
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: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:1247
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:1378
void createIndex(const StringData &ns, const BSONObj &keys)
Create an index on the collection 'ns' as described by the given keys.
Definition: dbclientinterface.h:1315
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:1354
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:1707
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:1737
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:1788
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:1750
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:1368
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:1209
double number() const
Retrieve the numeric value of the element.
Definition: bsonelement.h:290
Definition: dbclient_writer.h:27
Definition: dbclientinterface.h:1698
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:1467
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:1792
RunCommandHookFunc _runCommandHook
These functions will be executed by the driver on runCommand calls.
Definition: dbclientinterface.h:1425
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
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:55
Definition: message_port.h:74