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
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
