Boost logo

Boost :

From: Marcelo Zimbres Silva (mzimbres_at_[hidden])
Date: 2022-04-01 10:32:02

Hi Ruben,

>> The handler signature for this operation is
>> void(boost::mysql::error_code, boost::mysql::resultset<Stream>)
>> Hier the completion handler is returning an io object i.e.
>> boost::mysql::resultset, which is also unusual as far as I
>> can see. Does that play nice with executors? I would
>> prefer having the completion handler return config
>> parameters with which I can instantiate a
>> boost::mysql::resultset myself in my desired executor.
> The three I/O objects this library provides (connection,
> resultset and prepared_statement) are just proxies for the
> underlying Stream I/O object in terms of the executor (i.e.
> they just return the underlying Stream::get_executor()
> value).

My expectation is that the communication with the mysql server occurs
only through the connection class. It feels awkward to me that I need
these proxy objects when there is a connection object around, the
lifetime of these proxies are bound to it for example.

Some further points:

- A row in your library is basically std::vector<value>, which means
std::vector<row> is pessimized storage for rows with same length.
Aren't rows always equal in length for a table?

- Your value class is a variant behind the scenes i.e.

  boost::variant2::variant<null_t, std::int64_t, std::uint64_t,
boost::string_view, float, double, date, datetime, time>;

  I would like to understand what is the lifetime of the string_view.
Is it pointing to some kind of internal buffer? I expect all data to
be owned by the client class after the completion of an async
operation. Having pointers pointing to the connection internal state
feels bad.

- There one further point that doesn't seem to play well with this
variant design. Some people may store some kind of serialized data in
the database e.g. json strings. It would be nice if it were possible
to read those values avoiding temporaries, that is important to reduce
latency and memory usage on large payloads. It would look something

  struct mydata1, mydata2;
  using myrow = std::tuple<std::string, ..., mydata2, ..., mydata, ...>

  myrow row;

  In this case, the parser would have to call user code every time it
reads user data in the socket buffer, instead of copying to additional
buffers ( in order to hand it to user later when parsing is done).


Boost list run by bdawes at, gregod at, cpdaniel at, john at