On 18/07/2014 5:00 PM, Roland Bock wrote:
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.
Sometimes the burden of selecting just the needed part of the output is not so great in quince, where you can work in multi-column types. E.g.: for (const address &addr: employees.select(employees->home_address)) might retrieve five columns at once.
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 :-)
The collector class aspect is a bit of sugar that I added because it turned out to be easy. On the other hand, having user-defined structs as mapped types (as in the example above) was always a core feature in my mind. I guess I see the ascent from SQL syntax to C++ syntax, and the ascent from SQL types to C++ types, as two aspects of the same ascent.
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.
Funnily enough, one of my pre-quince attempts at a DAL *did* provide something similar to an untyped version of a quince query. If you executed it you would get row objects, and you'd have to figure out how to use something a bit like mappers to extract values from them. That was all because I hadn't figured out how to use tuples to provide type-safety without table-based value types. That product even had a with() method, which was like a widening select (because my thoughts about compositionality weren't so firm then). With quince, I thought the move to full static typing was pure forward progress -- but maybe not.
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
The thing that amazes me most is that we are such a small club. When I read things online about how ORM is "the Vietnam of computer science", and the way people seemed to have coined the phrase "impedance mismatch" specifically to mean "I'm sad because I can't write queries in my programming language", I wonder why everyone isn't attempting this. Cheers, --- Michael