Boost logo

Boost :

Subject: Re: [boost] quince: queries in C++ expressions
From: Roland Bock (rbock_at_[hidden])
Date: 2014-07-18 03:00:18


On 2014-07-18 03:05, Michael Shepanski wrote:
> On 18/07/2014 2:26 AM, Roland Bock wrote:
>> On 2014-07-17 15:34, Michael Shepanski wrote:
>>> On 17/07/2014 10:48 PM, Roland Bock wrote:
>>>> Shouldn't collections be mentioned on that page, too?
>>> I'm not sure I understand. Do you mean STL containers? Then no,
>>> these are not mapped types (except for the special cases std::string
>>> and std::vector<uint8_t>). You can't have a table<std::list<float>>.
>> No, sorry for the confusion, I meant the usage of collector classes.
>
> Oh but they are mentioned! They are in the category of "user-defined
> class".
OK, I missed that.
>
> Just as a std::tuple can be used to represent data in a table, and can
> also be put together _ad hoc_ by quince to deliver results of a join()
> or select(), the same can be said of user-defined classes (after they
> have been processed with QUINCE_MAP_CLASS).
Thinking about this, I just realized why I might have such a hard time
with those user-defined classes: In a earlier version (still in C++03),
I used something similar to tuples to define the results of a select.
That often led to inefficient code. Instead of writing a type that
represented just the n columns they actually needed, people tended to
use all columns all the time, just because they were too lazy to write
this extra class.

I therefore wanted the library to calculate the result types based on
what is selected, which never was a big deal, but required the auto
keyword to be usable.

That's why in sqlpp11 you don't have to write such classes. You declare
what you want to be selected inside the expression.

On the other hand, of course, it is a neat feature to be able to map
directly to user-defined structs. Maybe I'll find a way to do that in
sqlpp11, too :-)

>
>> Say I have two conditions, userWantsBlob and userWantsOther. I would
>> want to have everything in one loop.
>>
>> In sqlpp11 I could say something like:
>>
>> auto query = dynamic_select(db, t.meta)...;
>> if (userWantsBlob)
>> query.add_column(t.blob);
>> if (userWantsOther)
>> query.add_column(t.other);
>>
>> for (const auto& row : db(query))
>> {
>> std::cout << t.meta << '\n';
>> if (userWantsBlob)
>> std::cout << t.at("blob") << '\n';
>> if (userWantsOther)
>> std::cout << t.at("other") << '\n';
>> };
>>
>> How would you do that in quince?
>
> Ah, no, quince's static typing forbids anything like that. If I
> wanted to provide it, that would be a matter of exposing type-unsafe
> code that I currently keep hidden.
You lose on type-safety in sqlpp11, too, when doing something like this,
but in several of our projects, such dynamic parts are a hard
requirement. And it was quite painful to learn that because the
type-safety was one of the main drivers for developing the library in
the first place.

It's been quite an interesting comparison/discussion so far. I think we
shed some light on differences and similarities of quince and sqlpp11. I
certainly got a some ideas for improving sqlpp11 (e.g. table definitions
and mapping to user-defined structs) and stuff to think about (e.g
quince's way of composing queries).

Cheers,

Roland


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