MongoDB C++ Driver  legacy-1.0.5
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bsonobj.h
1 // @file bsonobj.h
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <boost/noncopyable.hpp>
21 #include <set>
22 #include <list>
23 #include <string>
24 #include <vector>
25 #include <utility>
26 
27 #include "mongo/bson/bsonelement.h"
28 #include "mongo/base/data_view.h"
29 #include "mongo/base/string_data.h"
30 #include "mongo/bson/util/builder.h"
31 #include "mongo/client/export_macros.h"
32 #include "mongo/platform/atomic_word.h"
33 #include "mongo/util/shared_buffer.h"
34 
35 namespace mongo {
36 
37  typedef std::set< BSONElement, BSONElementCmpWithoutField > BSONElementSet;
38  typedef std::multiset< BSONElement, BSONElementCmpWithoutField > BSONElementMSet;
39 
78  class MONGO_CLIENT_API BSONObj {
79  public:
80 
82  BSONObj() {
83  // Little endian ordering here, but that is ok regardless as BSON is spec'd to be
84  // little endian external to the system. (i.e. the rest of the implementation of
85  // bson, not this part, fails to support big endian)
86  static const char kEmptyObjectPrototype[] = { /*size*/5, 0, 0, 0, /*eoo*/0 };
87  _objdata = kEmptyObjectPrototype;
88  }
89 
93  explicit BSONObj(const char *bsonData) {
94  init(bsonData);
95  }
96 
97  explicit BSONObj(SharedBuffer ownedBuffer)
98  : _objdata(ownedBuffer.get() ? ownedBuffer.get() : BSONObj().objdata())
99  , _ownedBuffer(ownedBuffer.moveFrom()) {
100  }
101 
102 #if __cplusplus >= 201103L
103 
104  BSONObj(BSONObj&& other)
105  : _objdata(std::move(other._objdata))
106  , _ownedBuffer(std::move(other._ownedBuffer)) {
107  other._objdata = BSONObj()._objdata; // To return to an empty state.
108  }
109 
110  // The explicit move constructor above will inhibit generation of the copy ctor, so
111  // explicitly request the default implementation.
112 
114  BSONObj(const BSONObj&) = default;
115 #endif
116 
120  BSONObj& operator=(BSONObj otherCopy) {
121  this->swap(otherCopy);
122  return *this;
123  }
124 
126  void swap(BSONObj& other) {
127  using std::swap;
128  swap(_objdata, other._objdata);
129  swap(_ownedBuffer, other._ownedBuffer);
130  }
131 
160  bool isOwned() const { return _ownedBuffer.get() != 0; }
161 
165  BSONObj getOwned() const;
166 
168  BSONObj copy() const;
169 
173  enum { maxToStringRecursionDepth = 100 };
174 
175  std::string toString( bool isArray = false, bool full=false ) const;
176  void toString( StringBuilder& s, bool isArray = false, bool full=false, int depth=0 ) const;
177 
181  std::string jsonString(
182  JsonStringFormat format = Strict,
183  int pretty = 0,
184  bool isArray = false
185  ) const;
186 
188  int addFields(BSONObj& from, std::set<std::string>& fields); /* returns n added */
189 
193  BSONObj removeField(const StringData& name) const;
194 
198  int nFields() const;
199 
201  int getFieldNames(std::set<std::string>& fields) const;
202 
207  BSONElement getFieldDotted(const StringData &name) const;
208 
213  void getFieldsDotted(const StringData& name, BSONElementSet &ret, bool expandLastArray = true ) const;
214  void getFieldsDotted(const StringData& name, BSONElementMSet &ret, bool expandLastArray = true ) const;
215 
219  BSONElement getFieldDottedOrArray(const char *&name) const;
220 
224  BSONElement getField(const StringData& name) const;
225 
232  void getFields(unsigned n, const char **fieldNames, BSONElement *fields) const;
233 
237  BSONElement operator[] (const StringData& field) const {
238  return getField(field);
239  }
240 
241  BSONElement operator[] (int field) const {
242  StringBuilder ss;
243  ss << field;
244  std::string s = ss.str();
245  return getField(s.c_str());
246  }
247 
249  bool hasField( const StringData& name ) const { return !getField(name).eoo(); }
251  bool hasElement(const StringData& name) const { return hasField(name); }
252 
254  const char * getStringField(const StringData& name) const;
255 
257  BSONObj getObjectField(const StringData& name) const;
258 
260  int getIntField(const StringData& name) const;
261 
265  bool getBoolField(const StringData& name) const;
266 
279  BSONObj extractFieldsUnDotted(const BSONObj& pattern) const;
280 
286  BSONObj extractFields(const BSONObj &pattern , bool fillWithNull=false) const;
287 
288  BSONObj filterFieldsUndotted(const BSONObj &filter, bool inFilter) const;
289 
290  BSONElement getFieldUsingIndexNames(const StringData& fieldName,
291  const BSONObj &indexKey) const;
292 
296  bool couldBeArray() const;
297 
299  const char *objdata() const {
300  return _objdata;
301  }
302 
304  int objsize() const {
305  return ConstDataView(objdata()).readLE<int>();
306  }
307 
309  bool isValid() const {
310  int x = objsize();
311  return x > 0 && x <= BSONObjMaxInternalSize;
312  }
313 
320  inline bool okForStorage() const {
321  return _okForStorage(false, true).isOK();
322  }
323 
330  inline bool okForStorageAsRoot() const {
331  return _okForStorage(true, true).isOK();
332  }
333 
342  inline Status storageValidEmbedded(const bool deep = true) const {
343  return _okForStorage(false, deep);
344  }
345 
354  inline Status storageValid(const bool deep = true) const {
355  return _okForStorage(true, deep);
356  }
357 
359  bool isEmpty() const { return objsize() <= 5; }
360 
361  void dump() const;
362 
364  std::string hexDump() const;
365 
371  int woCompare(const BSONObj& r, const Ordering &o,
372  bool considerFieldName=true) const;
373 
379  int woCompare(const BSONObj& r, const BSONObj &ordering = BSONObj(),
380  bool considerFieldName=true) const;
381 
382  bool operator<( const BSONObj& other ) const { return woCompare( other ) < 0; }
383  bool operator<=( const BSONObj& other ) const { return woCompare( other ) <= 0; }
384  bool operator>( const BSONObj& other ) const { return woCompare( other ) > 0; }
385  bool operator>=( const BSONObj& other ) const { return woCompare( other ) >= 0; }
386 
390  int woSortOrder( const BSONObj& r , const BSONObj& sortKey , bool useDotted=false ) const;
391 
392  bool equal(const BSONObj& r) const;
393 
399  struct Hasher {
400  size_t operator() (const BSONObj& obj) const;
401  };
402 
409  bool isPrefixOf( const BSONObj& otherObj ) const;
410 
417  bool isFieldNamePrefixOf( const BSONObj& otherObj ) const;
418 
422  bool binaryEqual(const BSONObj& r) const {
423  int os = objsize();
424  if ( os == r.objsize() ) {
425  return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
426  }
427  return false;
428  }
429 
431  BSONElement firstElement() const { return BSONElement(objdata() + 4); }
432 
436  const char * firstElementFieldName() const {
437  const char *p = objdata() + 4;
438  return *p == EOO ? "" : p+1;
439  }
440 
441  BSONType firstElementType() const {
442  const char *p = objdata() + 4;
443  return (BSONType) *p;
444  }
445 
451  bool getObjectID(BSONElement& e) const;
452 
453  // Return a version of this object where top level elements of types
454  // that are not part of the bson wire protocol are replaced with
455  // string identifier equivalents.
456  // TODO Support conversion of element types other than min and max.
457  BSONObj clientReadable() const;
458 
461  BSONObj replaceFieldNames( const BSONObj &obj ) const;
462 
464  bool valid() const;
465 
466  bool operator==( const BSONObj& other ) const { return equal( other ); }
467  bool operator!=(const BSONObj& other) const { return !operator==( other); }
468 
469  enum MatchType {
470  Equality = 0,
471  LT = 0x1,
472  LTE = 0x3,
473  GTE = 0x6,
474  GT = 0x4,
475  opIN = 0x8, // { x : { $in : [1,2,3] } }
476  NE = 0x9,
477  opSIZE = 0x0A,
478  opALL = 0x0B,
479  NIN = 0x0C,
480  opEXISTS = 0x0D,
481  opMOD = 0x0E,
482  opTYPE = 0x0F,
483  opREGEX = 0x10,
484  opOPTIONS = 0x11,
485  opELEM_MATCH = 0x12,
486  opNEAR = 0x13,
487  opWITHIN = 0x14,
488  opMAX_DISTANCE = 0x15,
489  opGEO_INTERSECTS = 0x16,
490  };
491 
493  void elems(std::vector<BSONElement> &) const;
495  void elems(std::list<BSONElement> &) const;
496 
497  friend class BSONObjIterator;
498  typedef BSONObjIterator iterator;
499 
506  BSONObjIterator begin() const;
507 
508  void appendSelfToBufBuilder(BufBuilder& b) const {
509  verify( objsize() );
510  b.appendBuf(objdata(), objsize());
511  }
512 
513  template<typename T> bool coerceVector( std::vector<T>* out ) const;
514 
515  typedef SharedBuffer::Holder Holder;
516 
524  static BSONObj takeOwnership(char* holderPrefixedData) {
525  return BSONObj(SharedBuffer::takeOwnership(holderPrefixedData));
526  }
527 
528  private:
529  void _assertInvalid() const;
530 
531  void init(const char *data) {
532  _objdata = data;
533  if ( !isValid() )
534  _assertInvalid();
535  }
536 
543  Status _okForStorage(bool root, bool deep) const;
544 
545  const char* _objdata;
546  SharedBuffer _ownedBuffer;
547  };
548 
549  MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<( std::ostream &s, const BSONObj &o );
550  MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<( std::ostream &s, const BSONElement &e );
551 
552  MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC operator<<( StringBuilder &s, const BSONObj &o );
553  MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC operator<<( StringBuilder &s, const BSONElement &e );
554 
555  inline void swap(BSONObj& l, BSONObj& r) {
556  l.swap(r);
557  }
558 
559  struct BSONArray : BSONObj {
560  // Don't add anything other than forwarding constructors!!!
561  BSONArray(): BSONObj() {}
562  explicit BSONArray(const BSONObj& obj): BSONObj(obj) {}
563  };
564 
565 }
end of object
Definition: bsontypes.h:42
JsonStringFormat
Formatting mode for generating JSON from BSON.
Definition: oid.h:204
BSONElement firstElement() const
Definition: bsonobj.h:431
bool isOwned() const
A BSONObj can use a buffer it "owns" or one it does not.
Definition: bsonobj.h:160
std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 ...
Definition: builder.h:53
int objsize() const
Definition: bsonobj.h:304
Definition: shared_buffer.h:25
bool hasField(const StringData &name) const
Definition: bsonobj.h:249
the main MongoDB namespace
Definition: bulk_operation_builder.h:24
BSONObj(const char *bsonData)
Construct a BSONObj from data in the proper format.
Definition: bsonobj.h:93
static BSONObj takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned memory containing BSON data, prefixed by sufficient space for...
Definition: bsonobj.h:524
const char * objdata() const
Definition: bsonobj.h:299
bool okForStorage() const
Definition: bsonobj.h:320
bool hasElement(const StringData &name) const
Definition: bsonobj.h:251
strict RFC format
Definition: oid.h:206
BSONObj & operator=(BSONObj otherCopy)
Provide assignment semantics.
Definition: bsonobj.h:120
void swap(BSONObj &other)
Swap this BSONObj with 'other'.
Definition: bsonobj.h:126
bool isValid() const
performs a cursory check on the object's size only.
Definition: bsonobj.h:309
BSONType
the complete list of valid BSON types see also bsonspec.org
Definition: bsontypes.h:38
Status storageValid(const bool deep=true) const
Validates that this can be stored as a document (in a collection) See details above in okForStorageAs...
Definition: bsonobj.h:354
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
bool okForStorageAsRoot() const
Same as above with the following extra restrictions Not valid if:
Definition: bsonobj.h:330
static SharedBuffer takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned data, prefixed by sufficient space for a SharedBuffer::Holder...
Definition: shared_buffer.h:54
const char * firstElementFieldName() const
faster than firstElement().fieldName() - for the first element we can easily find the fieldname witho...
Definition: bsonobj.h:436
Status storageValidEmbedded(const bool deep=true) const
Validates that this can be stored as an embedded document See details above in okForStorage.
Definition: bsonobj.h:342
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
Definition: bsonobj.h:559
bool isEmpty() const
Definition: bsonobj.h:359
bool binaryEqual(const BSONObj &r) const
This is "shallow equality" – ints and doubles won't match.
Definition: bsonobj.h:422
BSONObj()
Construct an empty BSONObj – that is, {}.
Definition: bsonobj.h:82
A precomputation of a BSON index or sort key pattern.
Definition: ordering.h:32
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
MONGO_CLIENT_API Status(MONGO_CLIENT_FUNC *saslClientAuthenticate)(DBClientWithCommands *client
Attempts to authenticate "client" using the SASL protocol.
Functor compatible with std::hash for std::unordered_{map,set} Warning: The hash function is subject ...
Definition: bsonobj.h:399