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 
88 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
89  class BSONObj : public SDBObject {
90 #else
91  class BSONObj {
92 #endif
93  public:
94  class Holder;
98  explicit BSONObj(const char *msgdata, bool check=true) {
99  //_holder = NULL ;
100  init(msgdata, check);
101  }
102 
107  explicit BSONObj(Holder* holder) {
108  init(holder);
109  }
110 
112  BSONObj();
113 
114  ~BSONObj()
115  {
116  /*defensive:*/
117  _objdata = 0;
118  /* if ( _holder )
119  {
120  _holder->dec() ;
121  if ( _holder->isZero() )
122  free ( _holder ) ;
123  }*/
124  }
125 
162  bool isOwned() const
163  {
164  return _holder.get() != 0;
165  //return _holder != 0 ;
166  }
167 
171  BSONObj getOwned() const;
172 
174  BSONObj copy() const;
175 
180  string toString( bool isArray = false, bool full=false ) const;
181  void toString(StringBuilder& s, bool isArray = false, bool full=false )
182  const;
183 
187  string jsonString( JsonStringFormat format = Strict, int pretty = 0 )
188  const;
189 
191  int addFields(BSONObj& from, set<string>& fields); /* returns n added */
192 
196  int nFields() const;
197 
200  int getFieldNames(set<string>& fields) const;
201 
206  BSONElement getFieldDotted(const char *name) const;
211  BSONElement getFieldDotted(const string& name) const {
212  return getFieldDotted( name.c_str() );
213  }
214 
218  void getFieldsDotted(const StringData& name, BSONElementSet &ret) const;
219  void getFieldsDotted(const StringData& name, BSONElementMSet &ret)const;
220 
224  BSONElement getFieldDottedOrArray(const char *&name) const;
225 
229  BSONElement getField(const StringData& name) const;
230 
237  void getFields(unsigned n, const char **fieldNames, BSONElement *fields) const;
238 
242  BSONElement operator[] (const char *field) const {
243  return getField(field);
244  }
245 
246  BSONElement operator[] (const string& field) const {
247  return getField(field);
248  }
249 
250  BSONElement operator[] (int field) const {
251  StringBuilder ss;
252  ss << field;
253  string s = ss.str();
254  return getField(s.c_str());
255  }
256 
258  bool hasField( const char * name ) const
259  { return !getField(name).eoo(); }
261  bool hasElement(const char *name) const
262  { return hasField(name); }
263 
265  const char * getStringField(const char *name) const;
266 
268  BSONObj getObjectField(const char *name) const;
269 
271  int getIntField(const char *name) const;
272 
276  bool getBoolField(const char *name) const;
277 
283  BSONObj extractFieldsUnDotted(BSONObj pattern) const;
284 
290  BSONObj extractFields(const BSONObj &pattern , bool fillWithNull=false)
291  const;
292 
293  BSONObj filterFieldsUndotted(const BSONObj &filter, bool inFilter)
294  const;
295 
296  BSONElement getFieldUsingIndexNames(const char *fieldName,
297  const BSONObj &indexKey) const;
298 
300  const char *objdata() const {
301  return _objdata;
302  }
304  int objsize() const
305  { return *(reinterpret_cast<const int*>(objdata())); }
306 
308  bool isValid();
309 
313  bool okForStorage() const;
314 
316  bool isEmpty() const { return objsize() <= 5; }
317 
318  void dump() const;
319 
321  string hexDump() const;
322 
328  int woCompare(const BSONObj& r, const Ordering &o,
329  bool considerFieldName=true) const;
330 
336  int woCompare(const BSONObj& r, const BSONObj &ordering = BSONObj(),
337  bool considerFieldName=true) const;
338 
339  bool operator<( const BSONObj& other ) const
340  { return woCompare( other ) < 0; }
341  bool operator<=( const BSONObj& other ) const
342  { return woCompare( other ) <= 0; }
343  bool operator>( const BSONObj& other ) const
344  { return woCompare( other ) > 0; }
345  bool operator>=( const BSONObj& other ) const
346  { return woCompare( other ) >= 0; }
347 
352  int woSortOrder( const BSONObj& r , const BSONObj& sortKey ,
353  bool useDotted=false ) const;
354 
355  bool equal(const BSONObj& r) const;
356 
360  bool shallowEqual(const BSONObj& r) const {
361  int os = objsize();
362  if ( os == r.objsize() ) {
363  return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
364  }
365  return false;
366  }
367 
369  BSONElement firstElement() const { return BSONElement(objdata() + 4); }
370 
374  const char * firstElementFieldName() const {
375  const char *p = objdata() + 4;
376  return *p == EOO ? "" : p+1;
377  }
378 
384  bool getObjectID(BSONElement& e) const;
385 
387  int hash() const {
388  unsigned x = 0;
389  const char *p = objdata();
390  for ( int i = 0; i < objsize(); i++ )
391  x = x * 131 + p[i];
392  return (x & 0x7fffffff) | 0x8000000; // must be > 0
393  }
394 
395  // Return a version of this object where top level elements of types
396  // that are not part of the bson wire protocol are replaced with
397  // string identifier equivalents.
398  // TODO Support conversion of element types other than min and max.
399  BSONObj clientReadable() const;
400 
403  BSONObj replaceFieldNames( const BSONObj &obj ) const;
404 
406  bool valid() const;
407 
409  string md5() const;
410 
411  bool operator==( const BSONObj& other ) const { return equal( other ); }
412 
413  enum MatchType {
414  Equality = 0,
415  LT = 0x1,
416  LTE = 0x3,
417  GTE = 0x6,
418  GT = 0x4,
419  opIN = 0x8, // { x : { $in : [1,2,3] } }
420  NE = 0x9,
421  opSIZE = 0x0A,
422  opALL = 0x0B,
423  NIN = 0x0C,
424  opEXISTS = 0x0D,
425  opMOD = 0x0E,
426  opTYPE = 0x0F,
427  opREGEX = 0x10,
428  opOPTIONS = 0x11,
429  opELEM_MATCH = 0x12,
430  opNEAR = 0x13,
431  opWITHIN = 0x14,
432  opMAX_DISTANCE=0x15,
433  opISNULL=0x16
434  };
435 
437  void elems(vector<BSONElement> &) const;
439  void elems(list<BSONElement> &) const;
440 
450  template <class T>
451  void Vals(vector<T> &) const;
454  template <class T>
455  void Vals(list<T> &) const;
456 
459  template <class T>
460  void vals(vector<T> &) const;
463  template <class T>
464  void vals(list<T> &) const;
465 
466  friend class BSONObjIterator;
467  typedef BSONObjIterator iterator;
468 
475  BSONObjIterator begin() const;
476 
477  void appendSelfToBufBuilder(BufBuilder& b) const {
478  assert( objsize() );
479  b.appendBuf(reinterpret_cast<const void *>( objdata() ), objsize());
480  }
481 
482 #pragma pack(1)
483  class Holder : bsonnoncopyable {
484  private:
485  Holder(); // this class should never be explicitly created
486  mongo::AtomicUInt refCount;
487  public:
488  char data[4]; // start of object
489 
490  void zero() { refCount.zero(); }
491  //void inc () { refCount++ ; }
492  //void dec () { if(--refCount == 0){
493  // free(this) ; } }
494  //void dec () { --refCount ; }
495  //bool isZero () { return 0 == refCount ; }
496  // these are called automatically by boost::intrusive_ptr
497  friend void intrusive_ptr_add_ref(Holder* h) { h->refCount++; }
498  friend void intrusive_ptr_release(Holder* h) {
499 #if defined(_DEBUG) // cant use dassert or DEV here
500  assert((int)h->refCount > 0); // make sure we haven't already freed the buffer
501 #endif
502  if(--(h->refCount) == 0){
503  free(h);
504  }
505  }
506  };
507 #pragma pack()
508 
510  void init(const char *data, bool check=true ) {
511  _objdata = data;
512  if ( check && !isValid() )
513  _assertInvalid();
514  }
515  public:
522  static void setJSCompatibility(bool compatible) {
523  _jsCompatibility = compatible;
524  }
525 
530  static bool getJSCompatibility() {
531  return _jsCompatibility;
532  }
533 
534  private:
535  SDB_EXPORT static bool _jsCompatibility;
536 
537 
538  private:
539  const char *_objdata;
540  //Holder *_holder ;
541  bson_intrusive_ptr< Holder > _holder;
542 
543  void _assertInvalid() const;
544 
545  void init(Holder *holder) {
546  _holder = holder; // holder is now managed by intrusive_ptr
547  //_holder->inc() ;
548  init(holder->data);
549  }
550  };
551 
552  ostream& operator<<( ostream &s, const BSONObj &o );
553  ostream& operator<<( ostream &s, const BSONElement &e );
554 
555  StringBuilder& operator<<( StringBuilder &s, const BSONObj &o );
556  StringBuilder& operator<<( StringBuilder &s, const BSONElement &e );
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 }