37
37
// corresponding page on mongodb.com/docs. See CXX-1249 and DRIVERS-356 for more info.
38
38
39
39
template <typename T>
40
- void check_field (const T& document, const char * field, bool should_have, int example_no) {
40
+ void check_field (const T& document,
41
+ const char * field,
42
+ bool should_have,
43
+ int example_no,
44
+ const char * example_type = NULL ) {
45
+ std::string example_type_formatted = example_type ? example_type + std::string (" " ) : " " ;
41
46
if (should_have) {
42
47
if (!document[field]) {
43
- throw std::logic_error (std::string (" document in example " ) +
44
- std::to_string (example_no) + " should have field " + field);
48
+ throw std::logic_error (std::string (" document in " ) + example_type_formatted +
49
+ std::string (" example " ) + std::to_string (example_no) +
50
+ " should not have field " + field);
45
51
}
46
52
} else {
47
53
if (document[field]) {
48
- throw std::logic_error (std::string (" document in example " ) +
49
- std::to_string (example_no) + " should not have field " + field);
54
+ throw std::logic_error (std::string (" document in " ) + example_type_formatted +
55
+ std::string (" example " ) + std::to_string (example_no) +
56
+ " should not have field " + field);
50
57
}
51
58
}
52
59
}
@@ -61,6 +68,22 @@ void check_has_no_field(const T& document, const char* field, int example_no) {
61
68
check_field (document, field, false , example_no);
62
69
}
63
70
71
+ template <typename T>
72
+ void check_has_field (const T& document,
73
+ const char * field,
74
+ int example_no,
75
+ const char * example_type) {
76
+ check_field (document, field, true , example_no, example_type);
77
+ }
78
+
79
+ template <typename T>
80
+ void check_has_no_field (const T& document,
81
+ const char * field,
82
+ int example_no,
83
+ const char * example_type) {
84
+ check_field (document, field, false , example_no, example_type);
85
+ }
86
+
64
87
bool should_run_client_side_encryption_test (void ) {
65
88
const char * const vars[] = {
66
89
" MONGOCXX_TEST_AWS_SECRET_ACCESS_KEY" ,
@@ -187,6 +210,46 @@ static bool is_replica_set(const mongocxx::client& client) {
187
210
return static_cast <bool >(reply.view ()[" setName" ]);
188
211
}
189
212
213
+ static bool version_at_least (mongocxx::database& db,
214
+ int minimum_major,
215
+ int minimum_minor,
216
+ int minimum_patch) {
217
+ using bsoncxx::builder::basic::kvp;
218
+ using bsoncxx::builder::basic::make_document;
219
+
220
+ auto resp = db.run_command (make_document (kvp (" buildInfo" , 1 )));
221
+ auto version = resp.find (" version" )->get_string ().value ;
222
+ std::string major_string;
223
+ std::string minor_string;
224
+ std::string patch_string;
225
+ int split = 0 ;
226
+ for (auto i : version) {
227
+ if (i == ' .' ) {
228
+ split += 1 ;
229
+ continue ;
230
+ }
231
+ if (split == 0 ) {
232
+ major_string += i;
233
+ } else if (split == 1 ) {
234
+ minor_string += i;
235
+ } else if (split == 2 ) {
236
+ patch_string += i;
237
+ }
238
+ }
239
+
240
+ std::vector<int > server_semver{
241
+ std::stoi (major_string), std::stoi (minor_string), std::stoi (minor_string)};
242
+ std::vector<int > minimum_semver{minimum_major, minimum_minor, minimum_patch};
243
+ for (size_t i = 0 ; i < server_semver.size (); i++) {
244
+ if (server_semver[i] < minimum_semver[i]) {
245
+ return false ;
246
+ } else if (server_semver[i] > minimum_semver[i]) {
247
+ return true ;
248
+ }
249
+ }
250
+ return true ;
251
+ }
252
+
190
253
void insert_examples (mongocxx::database db) {
191
254
db[" inventory" ].drop ();
192
255
@@ -869,7 +932,7 @@ void query_null_missing_fields_examples(mongocxx::database db) {
869
932
}
870
933
}
871
934
872
- void projection_examples (mongocxx::database db) {
935
+ void projection_insertion_example (mongocxx::database db) {
873
936
db[" inventory" ].drop ();
874
937
875
938
{
@@ -915,6 +978,10 @@ void projection_examples(mongocxx::database db) {
915
978
throw std::logic_error (" wrong count in example 42" );
916
979
}
917
980
}
981
+ }
982
+
983
+ void projection_examples (mongocxx::database db) {
984
+ projection_insertion_example (db);
918
985
919
986
{
920
987
// Start Example 43
@@ -1092,6 +1159,63 @@ void projection_examples(mongocxx::database db) {
1092
1159
}
1093
1160
}
1094
1161
1162
+ void projection_with_aggregation_example (mongocxx::database db) {
1163
+ {
1164
+ if (!version_at_least (db, 4 , 4 , 0 )) {
1165
+ return ;
1166
+ }
1167
+
1168
+ projection_insertion_example (db);
1169
+
1170
+ // Start Aggregation Projection Example 1
1171
+ using bsoncxx::builder::basic::kvp;
1172
+ using bsoncxx::builder::basic::make_array;
1173
+ using bsoncxx::builder::basic::make_document;
1174
+
1175
+ auto cursor = db[" inventory" ].find (
1176
+ make_document (),
1177
+ mongocxx::options::find{}.projection (make_document (
1178
+ kvp (" _id" , 0 ),
1179
+ kvp (" item" , 1 ),
1180
+ kvp (" status" ,
1181
+ make_document (kvp (
1182
+ " $switch" ,
1183
+ make_document (
1184
+ kvp (" branches" ,
1185
+ make_array (
1186
+ make_document (
1187
+ kvp (" case" ,
1188
+ make_document (kvp (" $eq" , make_array (" $status" , " A" )))),
1189
+ kvp (" then" , " Available" )),
1190
+ make_document (
1191
+ kvp (" case" ,
1192
+ make_document (kvp (" $eq" , make_array (" $status" , " D" )))),
1193
+ kvp (" then" , " Discontinued" )))),
1194
+ kvp (" default" , " No status found" ))))),
1195
+ kvp (" area" ,
1196
+ make_document (kvp (
1197
+ " $concat" ,
1198
+ make_array (
1199
+ make_document (kvp (
1200
+ " $toString" ,
1201
+ make_document (kvp (" $multiply" , make_array (" $size.h" , " $size.w" ))))),
1202
+ " " ,
1203
+ " $size.uom" )))),
1204
+ kvp (" reportNumber" , make_document (kvp (" $literal" , 1 ))))));
1205
+ // End Aggregation Projection Example 1
1206
+
1207
+ for (auto && document : cursor) {
1208
+ check_has_no_field (document, " _id" , 1 , " aggregation projection" );
1209
+ check_has_field (document, " item" , 1 , " aggregation projection" );
1210
+ check_has_field (document, " status" , 1 , " aggregation projection" );
1211
+ check_has_no_field (document, " size" , 1 , " aggregation projection" );
1212
+ check_has_no_field (document, " instock" , 1 , " aggregation projection" );
1213
+ check_has_field (document, " area" , 1 , " aggregation projection" );
1214
+ check_has_field (document, " reportNumber" , 1 , " aggregation projection" );
1215
+ }
1216
+ }
1217
+ }
1218
+
1095
1219
void update_examples (mongocxx::database db) {
1096
1220
db[" inventory" ].drop ();
1097
1221
@@ -1467,24 +1591,6 @@ static void snapshot_example2(mongocxx::client& client) {
1467
1591
}
1468
1592
}
1469
1593
1470
- static bool version_at_least (mongocxx::database& db, int minimum_major) {
1471
- using bsoncxx::builder::basic::kvp;
1472
- using bsoncxx::builder::basic::make_document;
1473
-
1474
- auto resp = db.run_command (make_document (kvp (" buildInfo" , 1 )));
1475
- auto version = resp.find (" version" )->get_string ().value ;
1476
- std::string major_string;
1477
- for (auto i : version) {
1478
- if (i == ' .' ) {
1479
- break ;
1480
- }
1481
- major_string += i;
1482
- }
1483
- int server_major = std::stoi (major_string);
1484
-
1485
- return server_major >= minimum_major;
1486
- }
1487
-
1488
1594
// https://jira.mongodb.com/browse/CXX-2505
1489
1595
static void queryable_encryption_api (mongocxx::client& client) {
1490
1596
// Start Queryable Encryption Example
@@ -1610,14 +1716,15 @@ int main() {
1610
1716
query_array_embedded_documents_examples (db);
1611
1717
query_null_missing_fields_examples (db);
1612
1718
projection_examples (db);
1719
+ projection_with_aggregation_example (db);
1613
1720
update_examples (db);
1614
1721
delete_examples (db);
1615
- if (is_replica_set (conn) && version_at_least (db, 5 )) {
1722
+ if (is_replica_set (conn) && version_at_least (db, 5 , 0 , 0 )) {
1616
1723
snapshot_example1 (conn);
1617
1724
snapshot_example2 (conn);
1618
1725
}
1619
1726
if (should_run_client_side_encryption_test () && is_replica_set (conn) &&
1620
- version_at_least (db, 7 )) {
1727
+ version_at_least (db, 7 , 0 , 0 )) {
1621
1728
queryable_encryption_api (conn);
1622
1729
}
1623
1730
} catch (const std::logic_error& e) {
0 commit comments