@@ -2474,6 +2474,210 @@ test_example_56 (mongoc_database_t *db)
2474
2474
}
2475
2475
2476
2476
2477
+ /* clang-format on */
2478
+
2479
+ static bool
2480
+ insert_pet (mongoc_collection_t * collection , bool is_adoptable )
2481
+ {
2482
+ bson_t * doc = NULL ;
2483
+ bson_error_t error ;
2484
+ bool rc ;
2485
+
2486
+ doc = BCON_NEW ("adoptable" , BCON_BOOL (is_adoptable ));
2487
+
2488
+ rc = mongoc_collection_insert_one (collection , doc , NULL , NULL , & error );
2489
+ if (!rc ) {
2490
+ MONGOC_ERROR ("insert into pets.%s failed: %s" ,
2491
+ mongoc_collection_get_name (collection ),
2492
+ error .message );
2493
+ goto cleanup ;
2494
+ }
2495
+
2496
+ cleanup :
2497
+ bson_destroy (doc );
2498
+ return rc ;
2499
+ }
2500
+
2501
+
2502
+ static bool
2503
+ pet_setup (mongoc_collection_t * cats_collection ,
2504
+ mongoc_collection_t * dogs_collection )
2505
+ {
2506
+ bool ok = true;
2507
+
2508
+ mongoc_collection_drop (cats_collection , NULL );
2509
+ mongoc_collection_drop (dogs_collection , NULL );
2510
+
2511
+ ok = insert_pet (cats_collection , true);
2512
+ if (!ok ) {
2513
+ goto done ;
2514
+ }
2515
+
2516
+ ok = insert_pet (dogs_collection , true);
2517
+ if (!ok ) {
2518
+ goto done ;
2519
+ }
2520
+
2521
+ ok = insert_pet (dogs_collection , false);
2522
+ if (!ok ) {
2523
+ goto done ;
2524
+ }
2525
+ done :
2526
+ return ok ;
2527
+ }
2528
+
2529
+
2530
+ /*
2531
+ * Increment 'accumulator' by the amount of adoptable pets in the given
2532
+ * collection.
2533
+ */
2534
+ static bool
2535
+ accumulate_adoptable_count (const mongoc_client_session_t * cs ,
2536
+ mongoc_collection_t * collection ,
2537
+ int64_t * accumulator /* OUT */
2538
+ )
2539
+ {
2540
+ bson_t * pipeline = NULL ;
2541
+ mongoc_cursor_t * cursor = NULL ;
2542
+ bool rc = false;
2543
+ const bson_t * doc = NULL ;
2544
+ bson_error_t error ;
2545
+ bson_iter_t iter ;
2546
+ bson_t opts = BSON_INITIALIZER ;
2547
+
2548
+ rc = mongoc_client_session_append (cs , & opts , & error );
2549
+ if (!rc ) {
2550
+ MONGOC_ERROR ("could not apply session options: %s" , error .message );
2551
+ goto cleanup ;
2552
+ }
2553
+
2554
+ pipeline = BCON_NEW ("pipeline" ,
2555
+ "[" ,
2556
+ "{" ,
2557
+ "$match" ,
2558
+ "{" ,
2559
+ "adoptable" ,
2560
+ BCON_BOOL (true),
2561
+ "}" ,
2562
+ "}" ,
2563
+ "{" ,
2564
+ "$count" ,
2565
+ BCON_UTF8 ("adoptableCount" ),
2566
+ "}" ,
2567
+ "]" );
2568
+
2569
+ cursor = mongoc_collection_aggregate (
2570
+ collection , MONGOC_QUERY_NONE , pipeline , & opts , NULL );
2571
+ bson_destroy (& opts );
2572
+
2573
+ rc = mongoc_cursor_next (cursor , & doc );
2574
+
2575
+ if (mongoc_cursor_error (cursor , & error )) {
2576
+ MONGOC_ERROR ("could not get adoptableCount: %s" , error .message );
2577
+ rc = false;
2578
+ goto cleanup ;
2579
+ }
2580
+
2581
+ if (!rc ) {
2582
+ MONGOC_ERROR ("%s" , "cursor has no results" );
2583
+ goto cleanup ;
2584
+ }
2585
+
2586
+ rc = bson_iter_init_find (& iter , doc , "adoptableCount" );
2587
+ if (rc ) {
2588
+ * accumulator += bson_iter_as_int64 (& iter );
2589
+ } else {
2590
+ MONGOC_ERROR ("%s" , "missing key: 'adoptableCount'" );
2591
+ goto cleanup ;
2592
+ }
2593
+
2594
+ cleanup :
2595
+ bson_destroy (pipeline );
2596
+ mongoc_cursor_destroy (cursor );
2597
+ return rc ;
2598
+ }
2599
+
2600
+ /*
2601
+ * JIRA: https://jira.mongodb.org/browse/DRIVERS-2181
2602
+ */
2603
+ static void
2604
+ test_example_59 (mongoc_database_t * db )
2605
+ {
2606
+ /* Start Example 59 */
2607
+ mongoc_client_t * client = NULL ;
2608
+ mongoc_client_session_t * cs = NULL ;
2609
+ mongoc_collection_t * cats_collection = NULL ;
2610
+ mongoc_collection_t * dogs_collection = NULL ;
2611
+ int64_t adoptable_pets_count = 0 ;
2612
+ bson_error_t error ;
2613
+ mongoc_session_opt_t * session_opts ;
2614
+
2615
+ client = test_framework_new_default_client ();
2616
+
2617
+ cats_collection = mongoc_client_get_collection (client , "pets" , "cats" );
2618
+ dogs_collection = mongoc_client_get_collection (client , "pets" , "dogs" );
2619
+
2620
+ /* Seed 'pets.cats' and 'pets.dogs' with example data */
2621
+ if (!pet_setup (cats_collection , dogs_collection )) {
2622
+ goto cleanup ;
2623
+ }
2624
+
2625
+ /* start a snapshot session */
2626
+ session_opts = mongoc_session_opts_new ();
2627
+ mongoc_session_opts_set_snapshot (session_opts , true);
2628
+ cs = mongoc_client_start_session (client , session_opts , & error );
2629
+ mongoc_session_opts_destroy (session_opts );
2630
+ if (!cs ) {
2631
+ MONGOC_ERROR ("Could not start session: %s" , error .message );
2632
+ goto cleanup ;
2633
+ }
2634
+
2635
+ /*
2636
+ * Perform the following aggregation pipeline, and accumulate the count in
2637
+ * `adoptable_pets_count`.
2638
+ *
2639
+ * adoptablePetsCount = db.cats.aggregate(
2640
+ * [ { "$match": { "adoptable": true } },
2641
+ * { "$count": "adoptableCatsCount" } ], session=s
2642
+ * ).next()["adoptableCatsCount"]
2643
+ *
2644
+ * adoptablePetsCount += db.dogs.aggregate(
2645
+ * [ { "$match": { "adoptable": True} },
2646
+ * { "$count": "adoptableDogsCount" } ], session=s
2647
+ * ).next()["adoptableDogsCount"]
2648
+ *
2649
+ * Remember in order to apply the client session to
2650
+ * this operation, you must append the client session to the options passed
2651
+ * to `mongoc_collection_aggregate`, i.e.,
2652
+ *
2653
+ * mongoc_client_session_append (cs, &opts, &error);
2654
+ * cursor = mongoc_collection_aggregate (
2655
+ * collection, MONGOC_QUERY_NONE, pipeline, &opts, NULL);
2656
+ */
2657
+ accumulate_adoptable_count (cs , cats_collection , & adoptable_pets_count );
2658
+ accumulate_adoptable_count (cs , dogs_collection , & adoptable_pets_count );
2659
+
2660
+ printf ("there are %" PRId64 " adoptable pets\n" , adoptable_pets_count );
2661
+
2662
+ /* End Example 59 */
2663
+
2664
+ if (adoptable_pets_count != 2 ) {
2665
+ MONGOC_ERROR (
2666
+ "there should be exatly 2 adoptable_pets_count, found: %" PRId64 ,
2667
+ adoptable_pets_count );
2668
+ }
2669
+
2670
+ /* Start Example 59 Post */
2671
+ cleanup :
2672
+ mongoc_collection_destroy (dogs_collection );
2673
+ mongoc_collection_destroy (cats_collection );
2674
+ mongoc_client_session_destroy (cs );
2675
+ mongoc_client_destroy (client );
2676
+ /* End Example 59 Post */
2677
+ }
2678
+
2679
+ /* clang-format off */
2680
+
2477
2681
typedef struct {
2478
2682
bson_mutex_t lock ;
2479
2683
mongoc_collection_t * collection ;
@@ -4000,6 +4204,7 @@ test_sample_commands (void)
4000
4204
test_sample_command (test_example_57 , 57 , db , collection , false);
4001
4205
test_sample_command (test_example_58 , 58 , db , collection , false);
4002
4206
test_sample_command (test_example_56 , 56 , db , collection , true);
4207
+ test_sample_command (test_example_59 , 59 , db , collection , true);
4003
4208
test_sample_change_stream_command (test_example_change_stream , db );
4004
4209
test_sample_causal_consistency (client );
4005
4210
test_sample_aggregation (db );
0 commit comments