MongoDB C++ Driver  legacy-1.1.2
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 {
42  return _order;
43  }
44 
45 private:
46  BSONObj _order;
47 };
48 
49 typedef std::set<BSONObj, BSONObjCmp> BSONObjSet;
50 
51 enum FieldCompareResult {
52  LEFT_SUBFIELD = -2,
53  LEFT_BEFORE = -1,
54  SAME = 0,
55  RIGHT_BEFORE = 1,
56  RIGHT_SUBFIELD = 2
57 };
58 
72 #define BSON(x) ((::mongo::BSONObjBuilder(64) << x).obj())
73 
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 
137 private:
138  const Label& l_;
140 };
141 
142 // Utility class to allow adding a string to BSON as a Symbol
143 struct BSONSymbol {
144  explicit BSONSymbol(const StringData& sym) : symbol(sym) {}
145  StringData symbol;
146 };
147 
148 // Utility class to allow adding a string to BSON as Code
149 struct BSONCode {
150  explicit BSONCode(const StringData& str) : code(str) {}
151  StringData code;
152 };
153 
154 // Utility class to allow adding CodeWScope to BSON
156  explicit BSONCodeWScope(const StringData& str, const BSONObj& obj) : code(str), scope(obj) {}
157  StringData code;
158  BSONObj scope;
159 };
160 
161 // Utility class to allow adding a RegEx to BSON
162 struct BSONRegEx {
163  explicit BSONRegEx(const StringData& pat, const StringData& f = "") : pattern(pat), flags(f) {}
164  StringData pattern;
165  StringData flags;
166 };
167 
168 // Utility class to allow adding binary data to BSON
169 struct BSONBinData {
170  BSONBinData(const void* d, int l, BinDataType t) : data(d), length(l), type(t) {}
171  const void* data;
172  int length;
173  BinDataType type;
174 };
175 
176 // Utility class to allow adding deprecated DBRef type to BSON
177 struct BSONDBRef {
178  BSONDBRef(const StringData& nameSpace, const OID& o) : ns(nameSpace), oid(o) {}
179  StringData ns;
180  OID oid;
181 };
182 
183 extern MONGO_CLIENT_API Labeler::Label GT;
184 extern MONGO_CLIENT_API Labeler::Label GTE;
185 extern MONGO_CLIENT_API Labeler::Label LT;
186 extern MONGO_CLIENT_API Labeler::Label LTE;
187 extern MONGO_CLIENT_API Labeler::Label NE;
188 extern MONGO_CLIENT_API Labeler::Label NIN;
189 extern MONGO_CLIENT_API Labeler::Label BSIZE;
190 
191 
192 // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT << 6));
193 // becomes : {$or: [{x: {$gt: 7}}, {y: {$lt: 6}}]}
194 inline BSONObj OR(const BSONObj& a, const BSONObj& b);
195 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c);
196 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d);
197 inline BSONObj OR(
198  const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e);
199 inline BSONObj OR(const BSONObj& a,
200  const BSONObj& b,
201  const BSONObj& c,
202  const BSONObj& d,
203  const BSONObj& e,
204  const BSONObj& f);
205 // definitions in bsonobjbuilder.h b/c of incomplete types
206 
207 // Utility class to implement BSON( key << val ) as described above.
208 class MONGO_CLIENT_API BSONObjBuilderValueStream : public boost::noncopyable {
209 public:
210  friend class Labeler;
212 
213  BSONObjBuilder& operator<<(const BSONElement& e);
214 
215  template <class T>
216  BSONObjBuilder& operator<<(T value);
217 
218  BSONObjBuilder& operator<<(const DateNowLabeler& id);
219 
220  BSONObjBuilder& operator<<(const NullLabeler& id);
221  BSONObjBuilder& operator<<(const UndefinedLabeler& id);
222 
223  BSONObjBuilder& operator<<(const MinKeyLabeler& id);
224  BSONObjBuilder& operator<<(const MaxKeyLabeler& id);
225 
226  Labeler operator<<(const Labeler::Label& l);
227 
228  void endField(const StringData& nextFieldName = StringData());
229  bool subobjStarted() const {
230  return _fieldName != 0;
231  }
232 
233  // The following methods provide API compatibility with BSONArrayBuilder
234  BufBuilder& subobjStart();
235  BufBuilder& subarrayStart();
236 
237  // This method should only be called from inside of implementations of
238  // BSONObjBuilder& operator<<(BSONObjBuilderValueStream&, SOME_TYPE)
239  // to provide the return value.
240  BSONObjBuilder& builder() {
241  return *_builder;
242  }
243 
244 private:
245  StringData _fieldName;
246  BSONObjBuilder* _builder;
247 
248  bool haveSubobj() const {
249  return _subobj.get() != 0;
250  }
251  BSONObjBuilder* subobj();
252  std::auto_ptr<BSONObjBuilder> _subobj;
253 };
254 
260 public:
261  BSONSizeTracker() {
262  _pos = 0;
263  for (int i = 0; i < SIZE; i++)
264  _sizes[i] = 512; // this is the default, so just be consistent
265  }
266 
267  ~BSONSizeTracker() {}
268 
269  void got(int size) {
270  _sizes[_pos] = size;
271  _pos = (_pos + 1) % SIZE; // thread safe at least on certain compilers
272  }
273 
277  int getSize() const {
278  int x = 16; // sane min
279  for (int i = 0; i < SIZE; i++) {
280  if (_sizes[i] > x)
281  x = _sizes[i];
282  }
283  return x;
284  }
285 
286 private:
287  enum { SIZE = 10 };
288  int _pos;
289  int _sizes[SIZE];
290 };
291 
292 // considers order
293 bool fieldsMatch(const BSONObj& lhs, const BSONObj& rhs);
294 }
Definition: bsonmisc.h:155
Definition: bsonmisc.h:143
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents...
Definition: string_data.h:43
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
Definition: bsonmisc.h:35
Definition: bsonmisc.h:122
Object ID type.
Definition: oid.h:60
int woCompare(const BSONObj &r, const Ordering &o, bool considerFieldName=true) const
wo='well ordered'.
Definition: bsonmisc.h:86
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:259
Definition: bsonmisc.h:29
Definition: bsonmisc.h:100
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
Definition: bsonmisc.h:149
Definition: bsonmisc.h:114
Definition: bsonmisc.h:107
int getSize() const
right now choosing largest size
Definition: bsonmisc.h:277
Definition: bsonmisc.h:169
Definition: bsonmisc.h:93
Definition: bsonmisc.h:162
Definition: bsonmisc.h:177
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
Definition: bsonmisc.h:116
int woCompare(const BSONElement &e, bool considerFieldName=true) const
Well ordered comparison.
Definition: bsonmisc.h:120
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
Definition: bsonmisc.h:208