On Mon, Jun 08, 2015 at 01:33:22AM +0200, Vadim Zeitlin wrote:
> On Sat, 6 Jun 2015 22:46:41 +0200 Joerg Sonnenberger 
> <jo...@britannica.bec.de> wrote:
> 
> JS> one of the non-trivial issues with SOCI for me right now is the missing
> JS> support for binary strings.
> 
>  I haven't ever really worked with them, so I have a perhaps very naive
> question: what is the advantage of the binary strings compared to BLOBs
> (which SOCI already supports)?

The interface is simpler as they behave like in-band data. If you deal
with the complete data all the data, it is also faster.

> JS> While it is relatively easy to handle soci::into(s) for bytea columns
> JS> automatically, the input side is a real problem. A PoC for just the
> JS> correct encoding can be found at
> JS>   https://github.com/jsonn/soci/tree/pg_bytea
> JS> This would automatically switch std::string parameters to the bytea
> JS> encoding, if they contain NUL characters. Sadly, that's not enough. For
> JS> proper support, binary and character strings have to be distinguished as
> JS> the latter must confirm to the database encoding and the former can be
> JS> arbitrary input. std::string is the natural encoding for both, so this
> JS> is difficult.
> 
>  I'm not so sure about std::string being natural for anything except 7 bit
> ASCII. Of course, it _can_ be used for storing everything else too, but
> IMHO this is more confusing than useful. It's too late to prevent people
> from using it for non-ASCII text with SOCI, however, but I'd prefer to use
> some separate binary_string class, even if it's just a simple wrapper
> around std::string, instead of also reusing std::string itself for this.

Well, on the C++ side std::string is as near to handling binary data as
you can get. I don't think it is SOCI's business to enforce a separate
binary type (except as sugar, see below).

> JS> Python's DB API v2 solved this problem by requiring Binary() wrappers. I
> JS> think this would be appropiate as well here and slight careful coding
> JS> would mean no overhead in terms of copying for C++11.
> 
>  I have the impression that you're speaking of function wrappers and not
> object wrappers, as I do above, but please correct me if I'm wrong and
> we're actually in a violent agreement here.

No, object wrappers. The Binary() wrapping is essentially type sugar so
that the argument type matching can distinguish textish escaping from
binary escaping as needed. For the C++ use, the class would have to
support construction with a reference or rvalue and know whether it has
to free the data. This is to allow both use with literal values and
copy-free references to external storage.

> JS> Downside is that the way prepared statements are handled for PostgreSQL
> JS> doesn't work this way. At the time of prepare, the types of the
> JS> arguments are not yet known. Comments and ideas?
> 
>  The only solutions I see are to either query the database for the column
> type (which introduces some overhead, i.e. at least another round trip
> which is not insignificant when using a remote database) or to delay
> preparing the statement until the arguments are known (which breaks the
> spirit if not the letter of SOCI API).
> 
>  However I think that using a binary_string class would avoid this problem,
> which seems like another good reason to do it like this.

The binary_string class doesn't solve the problem. At the time prepare()
is called, no arguments are bound yet. Querying the database for
column types doesn't work either, since at least PostgreSQL supports
polymorphic functions as well. Delaying the preparation breaks one of
the existing test cases, but seems reasonable stable as long as types
are consistent across executions. I think that's a reasonable demand on
the interface.

Joerg

------------------------------------------------------------------------------
_______________________________________________
soci-devel mailing list
soci-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/soci-devel

Reply via email to