On 21/01/2008, Warren Young wrote:
> Maybe. We already hold type info from the DB, so maybe we can pull
> locale info, too. I'd rather see if we can get by with just C locale
> info first, though, before getting fancy.
It looks to me as though mysqld will always use '.' as the radix
character. So the program's current global locale should be
ignored/overridden. Using the C locale means you need to override it
globally (which would affect the locale seen by other threads in a
multi-threaded program) whereas using C++ iostreams with std::locale
allows you to set it per-stream.
The attached patch to test/string.cpp will reproduce the error. If I'm
right that mysqld always uses '.' for decimals then it shows what
happens in a program that uses ',' elsewhere.
The second patch for mystring.h demonstrates one way to fix it using a
stringstream and a std::locale. This simplifies the proxy templates to
just a typedef (so float converts as double, uchar as ulong, etc)
which (I'm pretty sure) preserves all the side-effects of the
strtol/strtoul conversions, such as allowing "42" to convert to
char(42) or "257" to silently overflow a char (both of which the
stream would handle differently by default.)
If the template partial specialisations are too fancy then conv(Type)
could just be overloaded for each builtin type, forwarding to
do_conv<something> like this:
signed char conv(signed char) const
{ return do_conv<long>("signed char"); }
float conv(float) const
{ return do_conv<double>("float"); }
That would get rid of the conv_promotion and proxy templates
completely and would also allow better names that typeid() provides on
some compilers.
btw, I noticed that with and without this patch you can convert
"1.23.00" to (double)1.23 without error. I'm not sure if that's a bug
or a feature :-)
Jon
Attachment: [text/x-patch] mysqlpp-localeconv.patch
Attachment: [text/x-patch] mysqlpp-string-conv.patch