SequoiaDB
 All Classes Namespaces Files Functions Macros Pages
bsonobj.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 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
23 #include "core.hpp"
24 #include "oss.hpp"
25 #endif
26 //#include <boost/intrusive_ptr.hpp>
27 #include <set>
28 #include <list>
29 #include <vector>
30 #include "lib/atomic_int.h"
31 #include "util/builder.h"
32 #include "stringdata.h"
33 #include "bsonelement.h"
34 #include "bsonnoncopyable.h"
35 #include "bsonintrusiveptr.h"
36 #include "bsonDecimal.h"
40 namespace bson {
43  typedef set< BSONElement, BSONElementCmpWithoutField > BSONElementSet;
46  typedef multiset< BSONElement, BSONElementCmpWithoutField > BSONElementMSet;
47 
89 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
90  class BSONObj : public SDBObject {
91 #else
92  class BSONObj {
93 #endif
94 
95  public:
96 #pragma pack(1)
97  class Holder : bsonnoncopyable
98  {
99  private:
100  Holder() ; // this class should never be explicitly created
101  mongo::AtomicUInt refCount ;
102  public:
103  char data[4]; // start of object
104 
105  void zeroRef() { refCount.zero() ; }
106  void addRef () { refCount++ ; }
107  int decRef ()
108  {
109 #if defined(_DEBUG) // cant use dassert or DEV here
110  // make sure we haven't already freed the buffer
111  assert( (int)refCount > 0 ) ;
112 #endif
113  return --refCount ;
114  }
115  const char* dataptr() const { return &data[0] ; }
116  int datasize() const { return *(int*)dataptr() ; }
117 
118  static int refLen() { return sizeof( mongo::AtomicUInt ) ; }
119  } ;
120  typedef bson_intrusive_ptr< Holder, TrivialAllocator > holder_type ;
121 #pragma pack()
122 
123  public:
127  explicit BSONObj(const char *msgdata, bool check=true) {
128  //_holder = NULL ;
129  init(msgdata, check);
130  }
131 
136  /*explicit BSONObj(Holder* holder) {
137  init( holder ) ;
138  }*/
139 
140  explicit BSONObj( holder_type holder ) {
141  init( holder ) ;
142  }
143 
145  BSONObj();
146 
147  ~BSONObj()
148  {
149  /*defensive:*/
150  _objdata = 0;
151  }
152 
189  bool isOwned() const
190  {
191  return _holder.get() != 0;
192  //return _holder != 0 ;
193  }
194 
198  BSONObj getOwned() const;
199 
201  BSONObj copy() const;
202 
207  string toString( bool isArray = false, bool full=false,
208  bool noThrow = true ) const;
209 #if defined ( SDB_ENGINE ) || defined ( SDB_FMP ) || defined ( SDB_TOOL )
210  ossPoolString toPoolString( bool isArray = false, bool full=false,
211  bool noThrow = true ) const ;
212 #endif //SDB_ENGINE || SDB_FMP || SDB_TOOL
213 
214  void toString(StringBuilder& s, bool isArray = false, bool full=false )
215  const;
216 
220  string jsonString( JsonStringFormat format = Strict, int pretty = 0 )
221  const;
222 
224  int addFields(BSONObj& from, set<string>& fields); /* returns n added */
225 
229  int nFields() const;
230 
233  int getFieldNames(set<string>& fields) const;
234 
236  bool hasAllFieldNames(const BSONObj &obj) const;
237 
242  BSONElement getFieldDotted(const char *name) const;
247  BSONElement getFieldDotted(const string& name) const {
248  return getFieldDotted( name.c_str() );
249  }
250 
254  void getFieldsDotted(const StringData& name, BSONElementSet &ret) const;
255  void getFieldsDotted(const StringData& name, BSONElementMSet &ret)const;
256 
260  BSONElement getFieldDottedOrArray(const char *&name) const;
261 
265  BSONElement getField(const StringData& name) const;
266  BSONElement getField(const char *name) const;
267 
274  void getFields(unsigned n, const char **fieldNames, BSONElement *fields) const;
275 
279  BSONElement operator[] (const char *field) const {
280  return getField(field);
281  }
282 
283  BSONElement operator[] (const string& field) const {
284  return getField(field);
285  }
286 
287  BSONElement operator[] (int field) const {
288  StringBuilder ss;
289  ss << field;
290  string s = ss.str();
291  return getField(s.c_str());
292  }
293 
295  bool hasField( const char * name ) const
296  { return !getField(name).eoo(); }
298  bool hasElement(const char *name) const
299  { return hasField(name); }
300 
302  const char * getStringField(const char *name) const;
303 
305  BSONObj getObjectField(const char *name) const;
306 
308  BSONObj getObjectField( const StringData &name ) const ;
309 
311  int getIntField(const char *name) const;
312 
316  bool getBoolField(const char *name) const;
317 
323  BSONObj extractFieldsUnDotted(BSONObj pattern) const;
324 
330  BSONObj extractFields(const BSONObj &pattern , bool fillWithNull=false)
331  const;
332 
333  BSONObj filterFieldsUndotted(const BSONObj &filter, bool inFilter)
334  const;
335 
336  BSONElement getFieldUsingIndexNames(const char *fieldName,
337  const BSONObj &indexKey) const;
338 
340  const char *objdata() const {
341  return _objdata;
342  }
344  int objsize() const
345  { return *(reinterpret_cast<const int*>(objdata())); }
346 
348  bool isValid() const ;
349 
353  bool okForStorage() const;
354 
356  bool isEmpty() const { return objsize() <= 5; }
357 
358  void dump() const;
359 
361  string hexDump() const;
362 
368  int woCompare(const BSONObj& r, const Ordering &o,
369  bool considerFieldName=true) const;
370 
376  int woCompare(const BSONObj& r, const BSONObj &ordering = BSONObj(),
377  bool considerFieldName=true) const;
378 
379  bool operator<( const BSONObj& other ) const
380  { return woCompare( other ) < 0; }
381  bool operator<=( const BSONObj& other ) const
382  { return woCompare( other ) <= 0; }
383  bool operator>( const BSONObj& other ) const
384  { return woCompare( other ) > 0; }
385  bool operator>=( const BSONObj& other ) const
386  { return woCompare( other ) >= 0; }
387 
392  int woSortOrder( const BSONObj& r , const BSONObj& sortKey ,
393  bool useDotted=false ) const;
394 
395  bool equal(const BSONObj& r) const;
396 
400  bool shallowEqual(const BSONObj& r) const {
401  int os = objsize();
402  if ( os == r.objsize() ) {
403  return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
404  }
405  return false;
406  }
407 
409  BSONElement firstElement() const { return BSONElement(objdata() + 4); }
410 
414  const char * firstElementFieldName() const {
415  const char *p = objdata() + 4;
416  return *p == EOO ? "" : p+1;
417  }
418 
424  bool getObjectID(BSONElement& e) const;
425 
427  int hash() const {
428  unsigned x = 0;
429  const char *p = objdata();
430  for ( int i = 0; i < objsize(); i++ )
431  x = x * 131 + p[i];
432  return (x & 0x7fffffff) | 0x8000000; // must be > 0
433  }
434 
435  // Return a version of this object where top level elements of types
436  // that are not part of the bson wire protocol are replaced with
437  // string identifier equivalents.
438  // TODO Support conversion of element types other than min and max.
439  BSONObj clientReadable() const;
440 
443  BSONObj replaceFieldNames( const BSONObj &obj ) const;
444 
446  bool valid() const;
447 
449  string md5() const;
450 
451  bool operator==( const BSONObj& other ) const { return equal( other ); }
452 
453  enum MatchType {
454  Equality = 0,
455  LT = 0x1,
456  LTE = 0x3,
457  GTE = 0x6,
458  GT = 0x4,
459  opIN = 0x8, // { x : { $in : [1,2,3] } }
460  NE = 0x9,
461  opSIZE = 0x0A,
462  opALL = 0x0B,
463  NIN = 0x0C,
464  opEXISTS = 0x0D,
465  opMOD = 0x0E,
466  opTYPE = 0x0F,
467  opREGEX = 0x10,
468  opOPTIONS = 0x11,
469  opELEM_MATCH = 0x12,
470  opNEAR = 0x13,
471  opWITHIN = 0x14,
472  opMAX_DISTANCE=0x15,
473  opISNULL=0x16
474  };
475 
477  void elems(vector<BSONElement> &) const;
479  void elems(list<BSONElement> &) const;
480 
490  template <class T>
491  void Vals(vector<T> &) const;
494  template <class T>
495  void Vals(list<T> &) const;
496 
499  template <class T>
500  void vals(vector<T> &) const;
503  template <class T>
504  void vals(list<T> &) const;
505 
506  friend class BSONObjIterator;
507  typedef BSONObjIterator iterator;
508 
515  BSONObjIterator begin() const;
516 
517  void appendSelfToBufBuilder(BufBuilder& b) const {
518  assert( objsize() );
519  b.appendBuf(reinterpret_cast<const void *>( objdata() ), objsize());
520  }
521 
524  void init(const char *data, bool check=true ) {
525  _objdata = data;
526  if ( check && !isValid() )
527  _assertInvalid();
528  }
529  public:
536  static void setJSCompatibility(bool compatible) {
537  _jsCompatibility = compatible;
538  }
539 
544  static bool getJSCompatibility() {
545  return _jsCompatibility;
546  }
547 
548  private:
549  SDB_EXPORT static bool _jsCompatibility;
550 
551  private:
552  const char *_objdata ;
553  holder_type _holder ;
554 
555  void _assertInvalid() const;
556 
557  void init( Holder *holder ) {
558  _holder = holder ; // holder is now managed by intrusive_ptr
559  init(_holder->data);
560  }
561 
562  void init( holder_type holder ) {
563  _holder = holder ;
564  init( _holder->data ) ;
565  }
566  };
567 
568  ostream& operator<<( ostream &s, const BSONObj &o );
569  ostream& operator<<( ostream &s, const BSONElement &e );
570 
571  StringBuilder& operator<<( StringBuilder &s, const BSONObj &o );
572  StringBuilder& operator<<( StringBuilder &s, const BSONElement &e );
573 
574 
575  struct BSONArray : BSONObj {
576  // Don't add anything other than forwarding constructors!!!
577  BSONArray(): BSONObj() {}
578  explicit BSONArray(const BSONObj& obj): BSONObj(obj) {}
579  };
580 
581 }