Boost logo

Boost :

Subject: Re: [boost] sqlpp11, 3rd iteration
From: Roland Bock (rbock_at_[hidden])
Date: 2014-08-19 11:46:49


On 2014-08-19 16:43, Adam Wulkiewicz wrote:
> Roland Bock wrote:
>> _NULL handling:_
>> Enabled by the restructured code and spurred by the library quince by
>> Michael Shepanski, sqlpp11 can now calculate which result fields can or
>> cannot be NULL.
>>
>> Speaking of which, handling NULL for result values has been discussed a
>> lot. The library now has compile-time configurable behavior, you can
>> choose between an std::optional-like interface and mapping NULL to the
>> trivial value of the result type, e.g. 0 for numbers or "" for strings,
>> see also https://github.com/rbock/sqlpp11/wiki/NULL
>
> The way how NULL values are handled is similar to how missing options
> are handled in ProgramOptions where if some parameter isn't passed it
> may be set to some default value which may be set by the user.
> Could it be possible to allow users to define their "trivial" values
> in sqlpp?
If result fields correspond to columns, then you could certainly define
a per column default value or even a function to be called which would
then yield the value, or throw, or assert...

In other cases, say select(t.a + t.b), you could define a per-type
default value/method in the connector.

That should be rather easy to add.
>
> I'm aware that there is a difference between the two - in sqlpp the
> structure is defined in compile-time but ProgramOptions is much more
> user friendly at the stage of defining possible options:
[...]
>
> I'm wondering, could it be possible to implement similar, compile-time
> interface in sqlpp, e.g. something similar to MPL?
> I'm asking because what the sqlpp library requires is very
> complicated: https://github.com/rbock/sqlpp11/blob/master/tests/Sample.h
> I'm aware that its purpose is to create a type reflecting required
> columns and to use them from the level of C++ but couldn't it be done
> simpler?
The crucial part is the _member_t template. I need that one. The other
stuff can be constructed whatever way you like. But if the name of the
column is `beta`, then I need a way to get this:

template<typename T>
struct _member_t
{
    T beta;
    T& operator()() { return beta; }
    const T& operator()() const { return beta; }
};

This is the magic ingredient that makes tables, result rows and
parameter sets of prepared statements to have members with a proper name.

The way it works is best to be observed in the table_t template, see
https://github.com/rbock/sqlpp11/blob/master/include/sqlpp11/table.h

template<typename Table, typename... ColumnSpec>
struct table_t
   : public table_base_t,
     public ColumnSpec::_name_t
      ::template _member_t<column_t<Table, ColumnSpec>>...

For each column, the table inherits from the column's _member_t which is
instantiated with the column itself. This adds a member of the column's
type and the column's name to the table.

I see no way to create such a template other than having it in the code.
You should of course not write it personally. You should use macros
(yuk) or code generators similar to the ddl2cpp script in the
repository. But you have to somehow create this code.

Unless you know some brilliant TMP technique for this?
Personally I think that is a missing feature in C++. I'd call it named
member mixin. Or something like that. Hmm.
Or, in addition to names and values, we should be able to declare names
in templates. That would be awesome!

Anyway, if the name thing can be solved without macros, I am all for a
terser notation :-)

Cheers,

Roland


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