MongoDB  2.6.0
bsonmisc.h
1 // @file bsonmisc.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 <memory>
21 
22 #include "mongo/bson/bsonelement.h"
23 #include "mongo/client/export_macros.h"
24 
25 namespace mongo {
26 
27  int getGtLtOp(const BSONElement& e);
28 
30  bool operator()( const BSONElement &l, const BSONElement &r ) const {
31  return l.woCompare( r, false ) < 0;
32  }
33  };
34 
35  class BSONObjCmp {
36  public:
37  BSONObjCmp( const BSONObj &order = BSONObj() ) : _order( order ) {}
38  bool operator()( const BSONObj &l, const BSONObj &r ) const {
39  return l.woCompare( r, _order ) < 0;
40  }
41  BSONObj order() const { return _order; }
42  private:
43  BSONObj _order;
44  };
45 
46  typedef std::set<BSONObj,BSONObjCmp> BSONObjSet;
47 
48  enum FieldCompareResult {
49  LEFT_SUBFIELD = -2,
50  LEFT_BEFORE = -1,
51  SAME = 0,
52  RIGHT_BEFORE = 1 ,
53  RIGHT_SUBFIELD = 2
54  };
55 
56  class LexNumCmp;
57  FieldCompareResult compareDottedFieldNames( const std::string& l , const std::string& r ,
58  const LexNumCmp& cmp );
59 
73 #define BSON(x) (( ::mongo::BSONObjBuilder(64) << x ).obj())
74 
80 #define BSON_ARRAY(x) (( ::mongo::BSONArrayBuilder() << x ).arr())
81 
82  /* Utility class to auto assign object IDs.
83  Example:
84  std::cout << BSON( GENOID << "z" << 3 ); // { _id : ..., z : 3 }
85  */
86  struct MONGO_CLIENT_API GENOIDLabeler { };
87  extern MONGO_CLIENT_API GENOIDLabeler GENOID;
88 
89  /* Utility class to add a Date element with the current time
90  Example:
91  std::cout << BSON( "created" << DATENOW ); // { created : "2009-10-09 11:41:42" }
92  */
93  struct MONGO_CLIENT_API DateNowLabeler { };
94  extern MONGO_CLIENT_API DateNowLabeler DATENOW;
95 
96  /* Utility class to assign a NULL value to a given attribute
97  Example:
98  std::cout << BSON( "a" << BSONNULL ); // { a : null }
99  */
100  struct MONGO_CLIENT_API NullLabeler { };
101  extern MONGO_CLIENT_API NullLabeler BSONNULL;
102 
103  /* Utility class to assign an Undefined value to a given attribute
104  Example:
105  std::cout << BSON( "a" << BSONUndefined ); // { a : undefined }
106  */
107  struct MONGO_CLIENT_API UndefinedLabeler { };
108  extern MONGO_CLIENT_API UndefinedLabeler BSONUndefined;
109 
110  /* Utility class to add the minKey (minus infinity) to a given attribute
111  Example:
112  std::cout << BSON( "a" << MINKEY ); // { "a" : { "$minKey" : 1 } }
113  */
114  struct MONGO_CLIENT_API MinKeyLabeler { };
115  extern MONGO_CLIENT_API MinKeyLabeler MINKEY;
116  struct MONGO_CLIENT_API MaxKeyLabeler { };
117  extern MONGO_CLIENT_API MaxKeyLabeler MAXKEY;
118 
119  // Utility class to implement GT, GTE, etc as described above.
120  class Labeler {
121  public:
122  struct Label {
123  explicit Label( const char *l ) : l_( l ) {}
124  const char *l_;
125  };
126  Labeler( const Label &l, BSONObjBuilderValueStream *s ) : l_( l ), s_( s ) {}
127  template<class T>
128  BSONObjBuilder& operator<<( T value );
129 
130  /* the value of the element e is appended i.e. for
131  "age" << GT << someElement
132  one gets
133  { age : { $gt : someElement's value } }
134  */
135  BSONObjBuilder& operator<<( const BSONElement& e );
136  private:
137  const Label &l_;
139  };
140 
141  // Utility class to allow adding a string to BSON as a Symbol
142  struct BSONSymbol {
143  explicit BSONSymbol(const StringData& sym) :symbol(sym) {}
144  StringData symbol;
145  };
146 
147  // Utility class to allow adding a string to BSON as Code
148  struct BSONCode {
149  explicit BSONCode(const StringData& str) :code(str) {}
150  StringData code;
151  };
152 
153  // Utility class to allow adding CodeWScope to BSON
154  struct BSONCodeWScope {
155  explicit BSONCodeWScope(const StringData& str, const BSONObj& obj) :code(str), scope(obj) {}
156  StringData code;
157  BSONObj scope;
158  };
159 
160  // Utility class to allow adding a RegEx to BSON
161  struct BSONRegEx {
162  explicit BSONRegEx(const StringData& pat, const StringData& f="") :pattern(pat), flags(f) {}
163  StringData pattern;
164  StringData flags;
165  };
166 
167  // Utility class to allow adding binary data to BSON
168  struct BSONBinData {
169  BSONBinData(const void* d, int l, BinDataType t) :data(d), length(l), type(t) {}
170  const void* data;
171  int length;
172  BinDataType type;
173  };
174 
175  // Utility class to allow adding deprecated DBRef type to BSON
176  struct BSONDBRef {
177  BSONDBRef(const StringData& nameSpace, const OID& o) :ns(nameSpace), oid(o) {}
178  StringData ns;
179  OID oid;
180  };
181 
182  extern MONGO_CLIENT_API Labeler::Label GT;
183  extern MONGO_CLIENT_API Labeler::Label GTE;
184  extern MONGO_CLIENT_API Labeler::Label LT;
185  extern MONGO_CLIENT_API Labeler::Label LTE;
186  extern MONGO_CLIENT_API Labeler::Label NE;
187  extern MONGO_CLIENT_API Labeler::Label NIN;
188  extern MONGO_CLIENT_API Labeler::Label BSIZE;
189 
190 
191  // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT << 6));
192  // becomes : {$or: [{x: {$gt: 7}}, {y: {$lt: 6}}]}
193  inline BSONObj OR(const BSONObj& a, const BSONObj& b);
194  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c);
195  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d);
196  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e);
197  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f);
198  // definitions in bsonobjbuilder.h b/c of incomplete types
199 
200  // Utility class to implement BSON( key << val ) as described above.
201  class MONGO_CLIENT_API BSONObjBuilderValueStream : public boost::noncopyable {
202  public:
203  friend class Labeler;
205 
206  BSONObjBuilder& operator<<( const BSONElement& e );
207 
208  template<class T>
209  BSONObjBuilder& operator<<( T value );
210 
211  BSONObjBuilder& operator<<(const DateNowLabeler& id);
212 
213  BSONObjBuilder& operator<<(const NullLabeler& id);
214  BSONObjBuilder& operator<<(const UndefinedLabeler& id);
215 
216  BSONObjBuilder& operator<<(const MinKeyLabeler& id);
217  BSONObjBuilder& operator<<(const MaxKeyLabeler& id);
218 
219  Labeler operator<<( const Labeler::Label &l );
220 
221  void endField( const StringData& nextFieldName = StringData() );
222  bool subobjStarted() const { return _fieldName != 0; }
223 
224  // The following methods provide API compatibility with BSONArrayBuilder
225  BufBuilder& subobjStart();
226  BufBuilder& subarrayStart();
227 
228  // This method should only be called from inside of implementations of
229  // BSONObjBuilder& operator<<(BSONObjBuilderValueStream&, SOME_TYPE)
230  // to provide the return value.
231  BSONObjBuilder& builder() { return *_builder; }
232  private:
233  StringData _fieldName;
234  BSONObjBuilder * _builder;
235 
236  bool haveSubobj() const { return _subobj.get() != 0; }
237  BSONObjBuilder *subobj();
238  std::auto_ptr< BSONObjBuilder > _subobj;
239  };
240 
245  public:
246  BSONSizeTracker() {
247  _pos = 0;
248  for ( int i=0; i<SIZE; i++ )
249  _sizes[i] = 512; // this is the default, so just be consistent
250  }
251 
252  ~BSONSizeTracker() {
253  }
254 
255  void got( int size ) {
256  _sizes[_pos] = size;
257  _pos = (_pos + 1) % SIZE; // thread safe at least on certain compilers
258  }
259 
263  int getSize() const {
264  int x = 16; // sane min
265  for ( int i=0; i<SIZE; i++ ) {
266  if ( _sizes[i] > x )
267  x = _sizes[i];
268  }
269  return x;
270  }
271 
272  private:
273  enum { SIZE = 10 };
274  int _pos;
275  int _sizes[SIZE];
276  };
277 
278  // considers order
279  bool fieldsMatch(const BSONObj& lhs, const BSONObj& rhs);
280 }
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:52
int getSize() const
right now choosing largest size
Definition: bsonmisc.h:263
Definition: bsonmisc.h:100
Definition: bsonmisc.h:161
Definition: bsonmisc.h:86
Definition: bsonmisc.h:116
Definition: bsonmisc.h:201
Definition: bsonmisc.h:29
Definition: bsonmisc.h:148
Definition: bsonmisc.h:142
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:244
int woCompare(const BSONElement &e, bool considerFieldName=true) const
Well ordered comparison.
Definition: bson-inl.h:153
Definition: bsonmisc.h:176
Definition: bsonmisc.h:122
Definition: bsonmisc.h:120
Definition: bsonmisc.h:168
Definition: bsonmisc.h:154
Definition: bsonmisc.h:93
int woCompare(const BSONObj &r, const Ordering &o, bool considerFieldName=true) const
wo=&#39;well ordered&#39;.
BSONElement represents an &quot;element&quot; in a BSONObj.
Definition: bsonelement.h:62
C++ representation of a &quot;BSON&quot; object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
Definition: bsonmisc.h:107
Definition: bsonmisc.h:35
Definition: bsonmisc.h:114
Object ID type.
Definition: oid.h:42