
On Mon, Sep 1, 2025 at 10:13 AM Darryl Green via Boost < boost@lists.boost.org> wrote:
On Mon, 1 Sept 2025 at 05:26, Maximilian Riemensberger via Boost <boost@lists.boost.org> wrote:
On 8/31/25 18:24, Klemens Morgenstern via Boost wrote:
On Sun, Aug 31, 2025 at 8:44 AM Maximilian Riemensberger via Boost < boost@lists.boost.org> wrote:
* The connection type can be owning or non-owning. Why wouldn't one instead have distinct connection (owning) and connection_ref
(non-owning)
types?
Because otherwise the complexity goes up unnecessarily. A user can write a function just taking `connection&` and not worry about this. In the library I have the `transaction` type for example. It holds a reference to the connection - if there was a second type like `connection_ref`, now I would have a second type of a transaction.
I see this point. However, a user that writes a function that takes `connection&` as an argument likely does not care about whether the connection is owning since the general expectation would be that the connection is connected and live before the function is called and remains so until the function returns. All those functions can just take `connection_ref` by value (just like functions take a string_view or span or function_ref) and no duplication is necessary, assuming connection_ref is implicitly constructible from `connection`.
Exactly. Note this is one of the footguns I also referred to in my review and this is the type of solution/usage Id' imagine.
* The statement type can construct owning and non-owning resultsets. The former automatically finalize, the latter reset the statement. Again why are those two behaviors combined in the same type?
Same reason as above...
Similar as for the connection: If the user function `interpret_result` does not take ownership of the resultset, that is the resultset that is passed into the function must outlive the return of the function, then interpret_result should only be written once and take resultset_ref as argument. resultset is implicitly convertible to resultset_ref.
This too, is reasonable.
Not to derail this conversation - but as its the only issue I raised that Max didn't also raise:
The non-throwing throwing duality is particularly quirky in resultset, and somewhat coupled to owning resultsets - in that having a resultset that when being iterated over or otherwise used to extract rows, returns (contains) a result that is (something like) a std::expected or boost::outcome not a row (that if not there can't be returned hence the throwing behaviour of operator*).
Id' like to see some discussion on that
Can you explain a bit more what you mean? There is a non-throwing API for reading rows, but it cannot be used nicely in a ranged for-loop.
* The library is designed around unique_ptr wrapping the sqlite3 C API handles with optional ownership. In particular, this seems at times quite dangerous for the sqlite3_stmt handle which is shared by statement, resultset, field, etc. Would the library be better served by for example reference counting such handles? If not, why? There is no obvious place to put the counter. If sqlite had those, I'd use them.
Fair enough.
Is it? Why can't such reference counting be implemented in types provided by the library, not sqlite3 itself? It is not unusual to do this for other resource handles that the underlying implementation doesn't reference count or otherwise lifetime manage.
It's overhead that many users would find undesirable.
_______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/6C5SI6EZ...