Boost logo

Boost :

Subject: Re: [boost] sqlpp11, 3rd iteration
From: Roland Bock (rbock_at_[hidden])
Date: 2014-08-20 14:21:40


On 2014-08-20 19:21, Adam Wulkiewicz wrote:
> Roland Bock wrote:
>> On 2014-08-20 00:34, Adam Wulkiewicz wrote:
>>> Roland Bock wrote:
>>>> But thats manageable. And yes, the code would be shorter, although not
>>>> that much, I suspect. The only problem I have with it is that now the
>>>> column types are going to be about a hundred characters long. And
>>>> users
>>>> are going to operate on columns all the time. So error message have to
>>>> be short.
>>> Do you have in mind the code of the library or user's code?
>> User's code:
>>
>> * You have the member template which must be defined outside.
>> * You have the get_name method which should be defined outside the
>> member template since I have no instance of that template where I
>> need the name (you still cant use a string literal as template
>> parameter directly, right? Like table_t<"sample">?)
>> * You need to group the member template and the get_name method since
>> they are always used in combination
>> * You need a struct or class to hold the default value or function
>>
>> And if you don't want to have all this flying around as individual
>> pieces with individual names, then you will group it into a class. And
>> you're back to where you started.
> Yes, passing a string literal isn't possible unfortunately.
>
> So the member and a name must be bound together somehow but the rest
> could still be automatically generated. In particular, IMHO the
> specification of a default value should be optional (e.g. passed as
> yet another trait). The library shouldn't require defining it each
> time, even as some dummy function if a user wanted to use exceptions.
> Besides, defining the default value generator as external to the
> member-"name" binding would probably be preferable because the same
> generator could be reused for many columns. However I don't expect
> that the generator would do something complicated, rather just return
> a value. But for integral members it could be predefined in the sqlpp
> and it could be passed as just 1 additional type.
Right.
>
>>
>>> I expect that the user's code, even not using defaults, would be a lot
>>> shorter.
>>> But the most important is that the definition of a table would
>>> probably be more clear, in one place, etc.
>>> Or am I wrong?
>> I think you're wrong, although I'd love to be wrong about that :-)
[...]
> Hmm, is the member template used in many places? AFAIU it must be used
> at least 2 times, to define columns, tables, etc. and later to
> construct a row.
- Tables,
- subqueries used as tables (basically tables again),
- result rows
- parameter sets for prepared queries

> Well, it isn't that important.
:-)
>
> If you write it this way:
>
> struct Alpha
> {
> static constexpr const char* _get_name() { return "alpha"; }
> template<typename T>
> struct _member_t
> {
> T alpha;
> T& operator()() { return alpha; }
> const T& operator()() const { return alpha; }
> };
> };
>
> struct alpha: public column_t<MyTable, Alpha,
> sqlpp::make_traits<sqlpp::integral,
> sqlpp::trivial_integral<42>, ...>>;
>
> it's shorter :)
>
> The above assuming that sqlpp::trivial_integral<> is a
> default-constructible functor returning a value convertible to
> int64_t. So basically trivial_t but with operator() instead of
> get_trivial_value().
Nice! I like it :-)

I will definitely experiment with that as soon as I find the time
(probably after CppCon).

>
> <snip>
>
> It could be convenient to generate a type of a non-parameter lambda
> expression in unevaluated context, something like:
>
> sqlpp::make_traits<sqlpp::trivial_value<decltype([](){return 0;})>>
>
>
> but this is not possible too.

Yeah, tried that too :-)

Cheers,

Roland


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