Dominique Devienne wrote:
On Fri, Jan 5, 2024 at 2:15 PM Phil Endecott via Boost
wrote: What do you do about multi-threaded usage?
Hi. What is there to do Phil?
I mentioned this because it is something that I got burned by recently. The sqlite docs are now improved after my feedback. Having the wrapper assert() if it detects non-thread-safe usage would be useful. I don't know how feasible that is.
[...] use one connection per thread
Yes, this is likely the best approach in most cases. You might also consider a connection pool. Could a generalised connection pool be something of value in Boost? I may have mentioned this before in relation to MySQL. On another subject, I note that the proposed API extensively uses string_view as a function return type. For example, field::column_name() returns a string_view. I consider this an anti-pattern. (In case anyone doesn't understand the issue, the danger is that the view will be dangling if the caller keeps it beyond the life of... some other object; I was going to write "the field object", but I'm not sure if that's right; maybe the row? The docs don't say.) In the case of e.g. column_name(), std::string's small buffer optimisation means that returning a std::string will not involve dynamic allocation unless the column name is more than maybe 23 characters long, which surely must be sufficient in practically all cases. If you really worry about long column names, please have a separate method (e.g. column_name_view()) whose name is a warning that it returns a view. There is more justification for using view-like types for the actual data. I'd still argue that the default should be to return safe types with value semantics, with those methods that return views named to indicate that. There is a lot of criticism of C++'s memory-unsafety. Dangling views are part of that. In newly-designed APIs, we should be going out of our way to offer memory safety by default. Note how I handle this in my sqlite wrapper: Query q(db, "select a,b from t where c=?"); q("hello").foreach_row( [&](std::string a, std::string_view b) { // do something with a and b }); Note that I can use strings or string_views as the parameters to the per-row lambda. If I choose to use a string_view I have to explicitly write "string_view", making it clear what the type is. If I were writing this today, I'd investigate whether generator co-routines could be used instead of the lambda. Regards, Phil.