|
Boost : |
Subject: Re: [boost] sqlpp11, 3rd iteration
From: Roland Bock (rbock_at_[hidden])
Date: 2014-08-19 05:35:56
On 2014-08-19 09:39, Gavin Lambert wrote:
> On 19/08/2014 19:21, Roland Bock wrote:
>> On 2014-08-19 04:17, Gavin Lambert wrote:
>>> On 19/08/2014 09:55, Roland Bock wrote:
>>>> Now, this contains an int64_t value. The address of this value is
>>>> given
>>>> to the backend in the method bind() when fetching each result row (no
>>>> laziness here). It seems to me that I cannot replace int64_t by
>>>> boost::optional<int64_t>. For instance, I cannot call get() to obtain
>>>> the address of the value if the optional is not initialized (I
>>>> would run
>>>> into an assert).
> [...]
>>> Therefore it should be the backend's responsibility to fill in the
>>> optional correctly
>> If I had an optional in the result field, yes.
>>> -- ie. you should be passing an address/reference to the entire
>>> optional, not the internal integer.
>> Some backends have functions like this (simplified):
>>
>> void get_int_field(int index, int* retval);
>>
>> How would I interact with such an interface if I had an optional<int>?
>
> I think we've had a terminology clash. By "backend" I thought you
> meant "the sqlpp11 class that knows how to talk to the native driver",
> not the native driver itself. Of course the native driver probably
> won't know how to drive an optional, nor should it be expected to.
>
> There are several layers, I assume:
>
> 1. User code
> 2. sqlpp11 database-independent frontend
> 3. sqlpp11 database-specific connector
> 4. native database library
Perfectly correct :-)
>
> Between layers 3 & 4 obviously you have to use whatever the native
> library supports, which is unlikely to be boost::optional (but still
> possible in some cases). So you might have to provide a raw int64_t
> pointer to the database up front, and translate from a int64_t pointer
> and an "is this null" method call (or a bool*) to a boost::optional
> when it calls you back saying the complete row is ready. (I'm
> assuming this is asynchronous, otherwise it's easier.)
As of today, it is synchronous.
>
> But between layers 1 & 2 and 2 & 3 you'd only have boost::optionals.
I can see the reasoning for 1&2. And I understand that it can be done
with 2&3 of course, but I am not sure there is a benefit.
>
>>> Otherwise how does the backend return a NULL value?
>> The backend is called with two parameters, one pointer for the value,
>> the other for the is_null information.
>
> So once you know that those have been filled in, you can translate it
> into a boost::optional to be returned to the higher layer. It does
> mean the value has to be copied (unless boost::optional has had move
> assignment added since I last looked), but you'd be doing that anyway
> for std::string so this doesn't seem any worse than that.
I can see that for the 1&2 interface, but not necessarily for 2&3 since
then I would have two copies of the string: once when obtaining the
value from 4 and copying it into 2&3, one for copying it from 2->1.
As of now, I create a temporary string when the value is requested in
the 1&2 interface.
Regards,
Roland
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk