Hello,

 Sorry about many messages but I keep running into problems with SOCI, at
least when using ODBC backend (I really hope it's exceptional this way, I
hoped to make my life simpler by using only it for the initial development
and testing but perhaps this wasn't such a good idea...).

 The latest one is that the logic of ODBC statement preparation/execution
is simply broken for custom types. Before starting discussing it, let me
say that this clearly has come up before and a patch possibly fixing this
was even applied (c166625a). Unfortunately the patch was reverted later by
an apparently unrelated commit (e5d8124e). And I couldn't find much in a
way of discussion except for this message:

http://www.mail-archive.com/[email protected]/msg00669.html

which has some tantalizing hints but no real explanation, let alone
solution. So I'm sorry if I'm going to repeat something that was already
said before but at the very least I hope that this time this will remain in
the mailing list archives.


 Anyhow, after this long introduction here is the problem description: when
type_conversion is specialized for some type, the value to be written to
the database is actually stored in 2 places: conversion_use_type::value_
and in its base details::base_value_holder::val_. It is transformed from
the former to the latter by convert_to_base() method which is called by
standard_use_type::pre_use() itself called from statement_impl::execute().
And the problem is that this is too late for ODBC because we call
odbc_standard_use_type_backend::prepare_for_bind() before execute() (from
statement::define_and_bind()) and by this time base_value_holder::val_ is
still empty. So ODBC code calls SQLBindParameter() with size of 1 for it
(it uses for empty string, probably because of trailing NUL concerns). And
while the buffer is resized and filled with the correct value later (patch
http://www.mail-archive.com/[email protected]/msg00957.html
helps with another bug there but this isn't enough), we don't rebind the
parameter at ODBC level again so it's never used correctly.

 Now I have no idea why do we actually write some junk to the database
instead of writing a single byte but it's clear that the code simply can't
work this way. To give you a simple example, you can't do

        boost::optional<std::string> maybeStr;
        maybeStr = "Hello, SOCI";
        session << "insert into ... values(:s)", use(maybeStr);

currently, it just doesn't work correctly with the ODBC backend.


 A simple solution would seem to call pre_use() from define_and_bind()
instead of doing it from execute() -- then we'd be able to pass the proper
buffer length to SQLBindParameter(). The message from Mateusz above hints
that there are problems with doing it but doesn't say clearly what they are
so I'm a bit lost here.

 If we can't do this, perhaps we could use SQLDescribeCol() to get the max
column length and pass this length to SQLBindParameter(). I didn't test it
yet and I don't know ODBC well at all but I hope this could work. It does
feel like a bad hack though so I'd really like to know why can't we just
call pre_use() earlier. Any thoughts?


 I'm not sure if the real severity of this bug was really understood during
its previous discussions because even Ilia Barahovski who made the patch
fixing it wrote "What the patch fixes is an obscure bug" -- but it's not
obscure at all. In fact it's pretty catastrophic as it just prevents the
use of SOCI with custom types convertible to strings. To me the ease of
extending SOCI to work with custom types was one of the main reasons for
choosing it in the first place so I really, really hope that this could be
fixed. I'm prepared to spend more time myself on this (I already spent a
few hours just tracking down this bug because it was far from obvious what
exactly went wrong) but I'd really appreciate some advice from the original
library authors just to avoid wasting times on something that can't work.

 Thanks in advance,
VZ

Attachment: pgpEnOYvZAwHH.pgp
Description: PGP signature

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Soci-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/soci-users

Reply via email to