Boost logo

Boost :

From: Ruben Perez (rubenperez038_at_[hidden])
Date: 2022-05-15 16:25:51


> > I'm not really getting the interface that your input/output
> > transformers would expose, though. Let's take this one, for example:
> >
> > template <>
> > struct OutputTransformer<NullAsEmptyString>
> > {
> > using value_type = std::string;
> >
> > static std::string get_value( int /*index_*/ )
> > {
> > static std::string x = "hello";
> > return x;
> > };
> > static void get_value( int index_, std::string& value_ )
> > {
> > value_ = get_value( index_ );
> > };
> > };
> >
> > I assume this is user-provided code. Where does the user get the
> > string value from? What does index_ mean in this context?
>
>
> sorry for beeing not clear (and sending a not directly fitting example)
>
> that code should be library code - more a less a collection of
> base-mysql concepts
> that can be used - this sample transformer lets you act empty strings as
> null in mysql
> - the implementation is a dummy - only to get a feeling how the data-flow is
>
> my adaption is used with SQLite and the index is the parameter index
> that would then map to SQLite bind functions or as in this case checks
> if the
> value is null and returns ""
>
> plus serveral other "typical" helper for adaption problems

What kind of transformers do you propose? For instance, something to make a NULL
string be treated as empty is a pattern I don't especially like. I
guess string-to-json
parsing is the obvious one. That would end up having the form of
custom types that
can be specified in the tuple/struct representing a row, so something like:

tuple<int, std::string, null_as_empty_string> row;
resultset.read_one(row);

>
> to know as much as possible before-hand - allows maybe deeper
> optimization etc. for example the my_select instance
> can use prepared statements per default (and this is connection oriented
> with sqlite)

I'd say you know at compile-time as much in both cases.

>
> // return value tuple
> const auto [ein_int2, ein_float2, ein_string2] = my_select( { 123 } );

I'd suggest something like

struct my_row {
    int ein_int2;
    float ein_float2;
    string ein_string2;
};
BOOST_DESCRIBE_STRUCT(my_row);
resultset.read_one(row);

Returning it by value works great for sync ops but can have bad implications
in async ops.

> // multi row fetch
> using My_select = Prepared_fetch<std::tuple<int>, std::tuple<int, float,
> NullAsEmptyString>>;
> My_select my_select( db_connection, "select a, b from test where c == ?1" );
>
> std::vector<Result2> result;
> my_select.fetch_copy( std::back_inserter( result ), 34 );
> my_select.fetch_copy( result, 34 );
>
> auto fetch_func = []( const int& /*ein_int_*/, const float& /*ein_float_*/,
> const std::string& /*ein_string_*/ ) {};
> my_select.fetch_func( fetch_func, 34 );
> auto fetch_func_cancel = []( const int& /*ein_int_*/, const float&
> /*ein_float_*/,
> const std::string& /*ein_string_*/ ) {
> return false; };
> my_select.fetch_func_with_cancel( fetch_func_cancel, 34 );

I can see something like fetch_copy, as a generalization of
resultset::read_many.
Other users have also brought it up.
https://github.com/anarthal/mysql/issues/58 tracks it.
It can be extended to work with tuples or structs.

>
> Boost does only provide low level stuff for real low level concepts
> (smart-pointer, maps etc.-)
> but most other libraries are always introducing very high level concepts
>

As Mateusz pointed out, I think there is room for everything - Beast has very
low level stuff, too.

Thanks,
Ruben.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk