[CXX-643] Beginner problems learning new v3 C++ driver API Created: 30/Jul/15  Updated: 07/Apr/23  Resolved: 10/Jan/16

Status: Closed
Project: C++ Driver
Component/s: API
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: Eloise Destelle Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

ubuntu (14.04 current; standard g++)


Attachments: File main.cpp    
Issue Links:
Related
is related to CXX-1202 Document how to build array in a loop... Closed

 Description   

I have had quite a few problems learning to use the new C++ driver. It's things like an apparent inconsistency in bsoncxx/builder/stream/document's handling of open/close document and open/close array, maybe missing overloaded append functions in stream-core, and a lack of clarity about handling types. I've found that I am having to use instances of type::b_document and types::b_array in ways that seem unnatural - but I couldn't find another way to get things to work.
Attached file has my example program with comments identifying difficulties.
Are there alternative ways of doing the things where I had problems?



 Comments   
Comment by Mira Carey [ 28/Aug/15 ]

Sorry for the slow turn around on this.

It seems like the main problem you've run into is how to programatically manipulate the stream within one expression (as you've noted, ending the statement loses the type information and leads to slightly obtuse type errors). The stream interface is probably a bit too clever for it's own good here, but the solution is that a variety of callables can be passed.

Consider the bsoncxx builder test:

 TEST_CASE("builder appends lambdas", "[bsoncxx::builder::stream]") {
      builder::stream::document expected;
      builder::stream::document stream;
  
      {
          using namespace builder::stream;
          expected << "a"
                   << "single"
                   << "b" << open_document << "key1"
                   << "value1"
                   << "key2"
                   << "value2" << close_document << "c" << open_array << 1 << 2 << 3 << close_array;
  
          stream << "a" << [](single_context s) { s << "single"; } << "b" << open_document <<
              [](key_context<> k) {
                  k << "key1"
                    << "value1"
                    << "key2"
                    << "value2";
              } << close_document << "c" << open_array << [](array_context<> a) { a << 1 << 2 << 3; }
                 << close_array;
      }
  
      viewable_eq_viewable(expected, stream);
  }

Note that you can use Callable's that take a:

  • single_context anywhere a value would go
  • key_context<> anywhere some number of key + values go
  • array_context<> anywhere some number of values in an array would go

So, looking at your examples:

doc << "stats" << open_array <<
  [](array_context<> a){ for(auto n: stats) { a << n; } } <<
doc << close_array;

Considering finalize, what you're getting there is a conversion to a document::value, which is an owned buffer. Generally speaking, getting views of subdocs during construction is only sort of supported (views are invalidated by any operations and the bytes aren't really consistent depending on if subdocs are currently opened)

The other thing you were seeing, where b_array and b_document show up, is mostly geared around aligning types with the reading api. It's for copying bytes in, rather than contiguously building in a reallocing buffer.

Hope that helps,
Jason

Generated at Wed Feb 07 21:59:50 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.