Skip to content

Commit ab3d5c5

Browse files
authored
CXX-2124 Add documentation for JSON-like syntax builder (#749)
1 parent 9ba665e commit ab3d5c5

File tree

7 files changed

+252
-48
lines changed

7 files changed

+252
-48
lines changed

docs/content/mongocxx-v3/working-with-bson.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use each. For more information and example code, see our
2222

2323
## Document Builders {#builders}
2424

25-
The bsoncxx library offers three interfaces for building BSON: one-off
26-
functions, a basic builder and a stream-based builder.
25+
The bsoncxx library offers four interfaces for building BSON: one-off
26+
functions, a basic builder, a list builder and a stream-based builder.
2727

2828
[`bsoncxx::builder::basic::document`](https://github.com/mongodb/mongo-cxx-driver/blob/master/src/bsoncxx/builder/basic/document.hpp)<br/>
2929
[`bsoncxx::builder::stream::document`](https://github.com/mongodb/mongo-cxx-driver/blob/master/src/bsoncxx/builder/stream/document.hpp)
@@ -32,10 +32,23 @@ The various methods of creating BSON documents and arrays are all
3232
equivalent. All interfaces will provide the same results, the choice of
3333
which to use is entirely aesthetic.
3434

35+
## List builder {#list}
36+
37+
The simplest way to create a BSON document or array is to use the JSON-like
38+
list builder:
39+
40+
```c++
41+
// { "hello": "world" }
42+
bsoncxx::builder::list list_builder = {"hello", "world"};
43+
bsoncxx::document::view document = list_builder.view().get_document();
44+
```
45+
46+
More advanced uses of the list builder are shown in [this
47+
example](https://github.com/mongodb/mongo-cxx-driver/blob/master/examples/bsoncxx/builder_list.cpp).
48+
3549
## "One-off" builder functions {#one-off}
3650
37-
The simplest way to create a BSON document or array is to use the one-off
38-
builder functions, which create documents and arrays in a single call.
51+
The "One-off" builder creates documents and arrays in a single call.
3952
These can be used when no additional logic (such as conditionals or loops)
4053
needs to be used to create the object:
4154

examples/bsoncxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ include_directories(
1818

1919
set(BSONCXX_EXAMPLES
2020
builder_core.cpp
21+
builder_list.cpp
2122
builder_basic.cpp
2223
builder_stream.cpp
2324
builder_stream_customization.cpp

examples/bsoncxx/builder_list.cpp

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2020 MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <bsoncxx/builder/list.hpp>
16+
#include <bsoncxx/types.hpp>
17+
#include <bsoncxx/types/bson_value/value.hpp>
18+
#include <chrono>
19+
20+
using namespace bsoncxx;
21+
22+
int main(int, char**) {
23+
using namespace bsoncxx::builder;
24+
25+
//
26+
// bsoncxx::builder::list, bsoncxx::builder::document, and bsoncxx::builder::array provides a
27+
// JSON-like interface for creating BSON objects.
28+
//
29+
30+
// builder::document builds an empty BSON document
31+
builder::document doc = {};
32+
// builder::array builds an empty BSON array
33+
builder::array arr = {};
34+
35+
//
36+
// We can append values to a document using an initializer list of key-value pairs.
37+
// { "hello" : "world" }
38+
//
39+
doc = {"hello", "world"};
40+
41+
//
42+
// Each document key must be a string type.
43+
//
44+
// {
45+
// "c-style" : "with value",
46+
// "basic string" : "with value"
47+
// }
48+
//
49+
doc = {"c-style", "with value", std::string("basic string"), "with value"};
50+
51+
//
52+
// Each document value must be a bson_value::value or implicitly convertible to one.
53+
//
54+
// {
55+
// "BSON boolean value" : false,
56+
// "BSON 32-bit signed integer value" : -123,
57+
// "BSON date value" : { "$date" : 123456789 },
58+
// "BSON Decimal128 value" : { "$numberDecimal" : "1.844674407370955161800E-6155" },
59+
// "BSON regex value with options" : { "$regex" : "any", "$options" : "imsx" }
60+
// }
61+
//
62+
// clang-format off
63+
doc = {"BSON boolean value", false,
64+
"BSON 32-bit signed integer value", -123,
65+
"BSON date value", std::chrono::milliseconds(123456789),
66+
"BSON Decimal128 value", decimal128{100, 200},
67+
"BSON regex value with options", bson_value::value("regex", "imsx" /* opts */)};
68+
// clang-format on
69+
70+
//
71+
// Nested documents can be added in-place.
72+
//
73+
// { "Answers" :
74+
// { "Everything" :
75+
// { "The Universe" : { "Life" : 42 } }
76+
// }
77+
// }
78+
//
79+
doc = {"Answers", {"Everything", {"The Universe", {"Life", 42}}}};
80+
81+
//
82+
// Each array element must be bson_value::value or implicitly convertible to one.
83+
//
84+
// { "0" : false,
85+
// "1" : -123,
86+
// "2" : { "$date" : 123456789 },
87+
// "3" : { "$numberDecimal" : "1.844674407370955161800E-6155" },
88+
// "4" : { "$regex" : "any", "$options" : "imsx" }
89+
// }
90+
//
91+
arr = {false,
92+
-123,
93+
std::chrono::milliseconds(123456789),
94+
decimal128{100, 200},
95+
bson_value::value("regex", "imsx" /* opts */)};
96+
97+
//
98+
// The list builder will create a BSON document, if possible. Otherwise, it will create a BSON
99+
// array. A document is possible if:
100+
// 1. The initializer list's size is even; this implies a list of
101+
// key-value pairs or an empty document if the size is zero.
102+
// 2. Each 'key' is a string type. In a list of key-value pairs, the 'key' is every other
103+
// element starting at the 0th element.
104+
//
105+
// BSON document
106+
// { "pi" : 3.1415899999999998826, "e" : 2.7182800000000000296 }
107+
builder::list lst = {"pi", 3.14159, "e", 2.71828};
108+
// BSON array
109+
// { "0" : "Numbers", "1" : 3.1415899999999998826, "2" : 2.7182800000000000296 }
110+
lst = {"Numbers", 3.14159, 2.71828};
111+
112+
//
113+
// BSON document
114+
//
115+
// { "this" : { "is" : 10 },
116+
// "valid" : { "BSON" : "document" }
117+
// "with" : [ 1, "nested", "array" ] }
118+
lst = {"this", {"is", 0xA}, "valid", {"BSON", "document"}, "with", {1, "nested", "array"}};
119+
120+
//
121+
// BSON array
122+
//
123+
// { "0" : "this",
124+
// "1" : { "will" : "be" },
125+
// "2" : "an",
126+
// "3" : "array",
127+
// "4" : [ 1, 2, 3] }
128+
lst = {"this", {"will", "be"}, "an", "array", {1, 2, 3}};
129+
}

examples/bsoncxx/builder_stream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ int main(int, char**) {
2323
using builder::stream::document;
2424
using builder::stream::array;
2525

26-
// bsoncxx::builder::stream presents an iostream like interface for succintly
26+
// bsoncxx::builder::stream presents an iostream like interface for succinctly
2727
// constructing complex BSON objects.
2828

2929
// stream::document builds a BSON document

src/bsoncxx/builder/basic/document.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class document : public sub_document {
7979
///
8080
/// @warning
8181
/// After calling extract() it is illegal to call any methods
82-
/// on this class, unless it is subsequenly moved into.
82+
/// on this class, unless it is subsequently moved into.
8383
///
8484
BSONCXX_INLINE bsoncxx::document::value extract() {
8585
return _core.extract_document();
@@ -100,7 +100,7 @@ class document : public sub_document {
100100
/// Creates a document from a list of key-value pairs.
101101
///
102102
/// @param args
103-
/// A variadiac list of key-value pairs. The types of the keys and values can be anything that
103+
/// A variadic list of key-value pairs. The types of the keys and values can be anything that
104104
/// builder::basic::sub_document::append accepts.
105105
///
106106
/// @return

src/bsoncxx/builder/list.hpp

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,60 +26,75 @@ BSONCXX_INLINE_NAMESPACE_BEGIN
2626
namespace builder {
2727
using namespace bsoncxx::types;
2828

29+
///
30+
/// A JSON-like builder for creating documents and arrays.
31+
///
2932
class list {
3033
using initializer_list_t = std::initializer_list<list>;
3134

3235
public:
36+
///
37+
/// Creates an empty document.
38+
///
3339
list() : list({}) {}
3440

41+
///
42+
/// Creates a bsoncxx::builder::list from a value of type T. T must be a
43+
/// bsoncxx::types::bson_value::value or implicitly convertible to a
44+
/// bsoncxx::types::bson_value::value.
45+
///
46+
/// @param value
47+
/// the BSON value
48+
///
49+
/// @see bsoncxx::types::bson_value::value.
50+
///
3551
template <typename T>
3652
list(T value) : val{value} {}
3753

54+
///
55+
/// Creates a BSON document, if possible. Otherwise, it will create a BSON array. A document is
56+
/// possible if:
57+
// 1. The initializer list's size is even; this implies a list of
58+
// key-value pairs or an empty document if the size is zero.
59+
// 2. Each 'key' is a string type. In a list of key-value pairs, the 'key' is every other
60+
// element starting at the 0th element.
61+
//
62+
/// @param init
63+
/// the initializer list used to construct the BSON document or array
64+
///
65+
/// @note
66+
/// to enforce the creation of a BSON document or array use the bsoncxx::builder::document
67+
/// or bsoncxx::builder::array constructor, respectively.
68+
///
69+
/// @see bsoncxx::builder::document
70+
/// @see bsoncxx::builder::array
71+
///
3872
list(initializer_list_t init) : list(init, true, true) {}
3973

40-
operator bson_value::value() {
41-
return value();
42-
}
43-
74+
///
75+
/// Provides a view of the underlying BSON value.
76+
///
77+
/// @see bsoncxx::types::bson_value::view.
78+
///
4479
operator bson_value::view() {
4580
return view();
4681
}
4782

83+
///
84+
/// Provides a view of the underlying BSON value.
85+
///
86+
/// @see bsoncxx::types::bson_value::view.
87+
///
4888
bson_value::view view() {
4989
return val.view();
5090
}
5191

52-
bson_value::value value() {
53-
return val;
54-
}
55-
56-
class array {
57-
public:
58-
array() = default;
59-
array(initializer_list_t init) : lst(init) {}
60-
operator list() {
61-
return list(lst, false, true);
62-
}
63-
64-
private:
65-
initializer_list_t lst;
66-
};
67-
68-
class document {
69-
public:
70-
document() = default;
71-
document(initializer_list_t init) : lst(init) {}
72-
operator list() {
73-
return list(lst, false, false);
74-
}
75-
76-
private:
77-
initializer_list_t lst;
78-
};
79-
8092
private:
8193
bson_value::value val;
8294

95+
friend class document;
96+
friend class array;
97+
8398
list(initializer_list_t init, bool type_deduction, bool is_array) : val{nullptr} {
8499
std::stringstream err_msg{"cannot construct document"};
85100
bool valid_document = false;
@@ -118,6 +133,54 @@ class list {
118133
}
119134
}
120135
};
136+
137+
///
138+
/// A JSON-like builder for creating documents.
139+
///
140+
class document : public list {
141+
using initializer_list_t = std::initializer_list<list>;
142+
143+
public:
144+
///
145+
/// Creates an empty document.
146+
///
147+
document() : list({}, false, false){};
148+
149+
///
150+
/// Creates a BSON document.
151+
///
152+
/// @param init
153+
/// the initializer list used to construct the BSON document
154+
///
155+
/// @see bsoncxx::builder::list
156+
/// @see bsoncxx::builder::array
157+
///
158+
document(initializer_list_t init) : list(init, false, false) {}
159+
};
160+
161+
///
162+
/// A JSON-like builder for creating arrays.
163+
///
164+
class array : public list {
165+
using initializer_list_t = std::initializer_list<list>;
166+
167+
public:
168+
///
169+
/// Creates an empty array.
170+
///
171+
array() : list({}, false, true){};
172+
173+
///
174+
/// Creates a BSON array.
175+
///
176+
/// @param init
177+
/// the initializer list used to construct the BSON array
178+
///
179+
/// @see bsoncxx::builder::list
180+
/// @see bsoncxx::builder::document
181+
///
182+
array(initializer_list_t init) : list(init, false, true) {}
183+
};
121184
}
122185
BSONCXX_INLINE_NAMESPACE_END
123186
}

0 commit comments

Comments
 (0)