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