On Sun, 1 Jul 2012 17:47:10 -0700 Pawel Aleksander Fedorynski 
<[email protected]> wrote:

PAF> I do think that it would be a mistake to map INT UNSIGNED to a
PAF> four-byte signed int, since then we would be corrupting values larger
PAF> than 2147483647.

 I don't think we would be corrupting them. If you write an unsigned to the
database and read it back as unsigned you should -- and would, with the
patches I applied locally -- get back exactly the same value.

PAF> To answer your question about how existing application code might be
PAF> affected by these changes, consider the following example:
PAF> 
PAF> #include <exception>
PAF> #include <iostream>
PAF> #include "soci.h"
PAF> #include "soci-mysql.h"
PAF> 
PAF> using namespace soci;
PAF> using namespace std;
PAF> 
PAF> int main()
PAF> {
PAF>   session sql(mysql, "db=test user=root");
PAF> 
PAF>   sql << "drop table if exists soci_test";
PAF>   sql << "create table soci_test(val int unsigned)";
PAF>   sql << "insert into soci_test set val = 123";
PAF>   rowset<row> rs = (sql.prepare << "select val from soci_test");
PAF>   for (rowset<row>::const_iterator it = rs.begin(); it != rs.end(); ++it) {
PAF>     const row& v = *it;
PAF>     try {
PAF>       cout << v.get<long>(0) << endl;
PAF>     } catch (const exception& e) {
PAF>       cout << e.what() << endl;
PAF>     }
PAF>     try {
PAF>       cout << v.get<unsigned long>(0) << endl;
PAF>     } catch (const exception& e) {
PAF>       cout << e.what() << endl;
PAF>     }
PAF>     try {
PAF>       cout << v.get<long long>(0) << endl;
PAF>     } catch (const exception& e) {
PAF>       cout << e.what() << endl;
PAF>     }
PAF>   }
PAF> }
PAF> 
PAF> This code prints:
PAF> 
PAF> std::bad_cast
PAF> 123
PAF> std::bad_cast
PAF> 
PAF> when built against the latest version in git, but before I made the
PAF> change today it would have printed:
PAF> 
PAF> std::bad_cast
PAF> std::bad_cast
PAF> 123
PAF> 
PAF> and using soci-3.1.0 (current stable version, before I added support
PAF> for INT UNSIGNED) it the output is:
PAF> 
PAF> 123
PAF> std::bad_cast
PAF> std::bad_cast

 I really don't know what is the desired behaviour here, although all 3
above ones seem surprising to me (I'd definitely expect it to succeed for
the first two cases and either succeed or fail for the last one depending
on whether promotions are used in this API or not).

 All I do know is that doing

        unsigned x = ... whetever ...;
        sql << "insert into soci_test(val) values (:x)", use(x);
        sql << "select val from soci_test", into(x);

shouldn't throw any exceptions and should preserve the value of x (even if
it's greater than INT_MAX).

 In the current state, this is not the case for ODBC backend because it
can fail to save a LONGLONG SQL value into a column using INT type.

PAF> I think that's what Neil meant when he wrote that the code is very
PAF> fragile.  I agree with this, we should probably make row::get<> more
PAF> forgiving.

 Perhaps, but I don't see how does having x_unsigned_long (which is, again,
not used anywhere except SQLite backend anyhow) can help nor how can
removing it harm this plan.

 Maybe I should push my changes out on a separate branch so that you could
test them and let me know if you find any problems with MySQL?

 What do you think?
VZ

Attachment: pgp9yHBlGQvcZ.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