Hello Tommi,
Thanks very much for reviewing this.
> >
> > I've tweaked it to try to detect overflow errors, and re-ran
> > the tests with the 4 databases.
> >
> > Also I tweaked it to use std::iostream::peek() in order to
> > try to avoid reading eof().
> >
> > I wasn't sure if we should throw std::overflow_error
> > when reading Decimals from an std::istream, instead
> > I just set the fail bit.
> >
>
> On Sun, 2 Sep 2007 18:26:05 +0200
> Tommi Mäkitalo <[EMAIL PROTECTED]> wrote:
> Setting fail bit in istream is the right thing to do.
Great, thanks.
> But tntdb::Decimal::getInteger<IntegerType>() should throw an
> overflow_error.
I try to do that in the svn_diff_tntdb_decimal_sep_2_2007_2.txt
diffs I emailed you, however in the next update I will change
it to also throw std::overflow_error if (flags & (infinity | NaN)).
> But I would like to strip down the class a little. Do a database
> library really need input and output operators for iostream for the
> Decimal-type?
I think the answer is yes, as:
- SQLite, MySQL and PostgreSQL require the decimal number to be
written to a string in order to write it into the database.
- SQLite, MySQL and PostgreSQL require the decimal number to be
read from a string in order to write it into the database.
So the only choice to make is whether to only perform input and
output from strings, or from iostreams. I was of course trying
to write code to fit into the existing tntdb library code.
The other number types are read and written from iostreams, so
I coded Decimal to use iostreams.
For example, for PostgreSQL the decimal numbers are read from the
database along with the other number types in:
template <typename T>
T getValue(const std::string& s, const char* tname)
{
std::istringstream in(s);
T ret;
in >> ret;
if (in.eof() || !in.fail())
return ret;
std::ostringstream msg;
msg << "can't convert \"" << s << "\" to " << tname;
throw TypeError(msg.str());
}
The lines:
if (in.eof() || !in.fail())
return ret;
can probably be changed back to (I will run tests to check):
if (in)
return ret;
Since I tweeked Decimal::read() to use peek() to avoid reading eof.
> tntdb::Date, tntdb::Time and tntdb::DateTime are just
> very simple data holder. I would prefer that for tntdb::Decimal too.
I noticed that tntdb::Date, tntdb::Time and tntdb::DateTime instead
perform intput and output from strings. I considered doing that
for Decimal, but:
- it seemed that it would be almost as difficult as reading and
writing from iostreams.
- Using iostreams fits in better with the code for reading and writing
numbers and other types to and from the databases.
- providing iostreams input and output operators is more flexible than
reading and writing from strings.
> It is not that easy to do that iostream-stuff right. What about
> decimal point? In germany we use a decimal comma. You don't use the
> locale correctly.
Thanks for pointing out that bug, I can try to fix that.
However I ran a few tests with MySQL 5.21 beta 21 and
PostgreSQL 8.2.4 with the environment settings:
goanna% env | egrep "(LC_|LANG)"
LANG=de_DE
LC_MONETARY=de_DE
LC_TIME=de_DE
LC_MESSAGES=de_DE
LC_CTYPE=de_DE
LC_COLLATE=de_DE
LC_NUMERIC=de_DE
goanna% date
Montag, 3. September 2007, 21:03:46 Uhr EST
goanna%
and mysql and psql both still print output in English
and numeric/decimal values with . as the decimal point.
> Why do I need print flags in the decimal class?
> Tntdb does not need that. It is useless.
The print flags:
enum
{
infinityShort, // Affects output only, print Inf or -Inf.
infinityLong, // Affects output only, print Infinity or -Infinity
instead of Inf or -Inf. infinityTilde // Affects output only, print
~ or -~ (as used in Oracle) instead of Inf or -Inf. };
are for an obscure feature, the proposed ANSI C decimal
type can represent the values:
+Inf - positive infinity
-Inf - negative infinity
NaN - not a number
And some of the databases have limited support for some
of these.
The different databases and the C++ iostreams print out the
infinity values in different ways:
Oracle: -~ and +~
iostreams: -Inf and +Inf
It is easy when reading, just accept any of these formats.
However when outputing decimal values to the database, I was
trying to figure out how to output these values in the correct
formats. Running some tests though I see that Oracle 10g r2,
MySQL 5.1 beta 21 and PostgreSQL 8.2.4 seem to have lots of
bugs with these values. So maybe it is useless. I can remove
it if you like, and always print out these values as:
+Inf
-Inf
NaN
I wonder if I should just ignore any setting of ostream::width()
when outputting decimal numbers. It seems difficult to figure
out what to do if the width is set, it may be too small.
> tntdb::Decimal::getBool does not make any sense. A decimal has
> nothing to do with bool. Why should a decimal has some special value,
> which is interpreted as false? You may do something like:
>
> tntdb::Decimal d = ...;
> if (d == tntdb::Decimal(0, 0))
> {
> // d is zero
> }
>
> This is more readable than:
>
> tntdb::Decimal d = ...;
> if (d.getBool())
> {
> }
OK we can remove getBool().
> I still like your idea with getInteger and getFloatingPoint as
> templates, but let us remove these iostream-stuff from tntdb.
It is probably not so easy to remove the iostream stuff as it
is being used to read and write the decimals from/to the database.
> There may be something like tntdbx::Decimal, which adds all that
> nifty things. You may then write:
>
> tntdb::Value v = ...;
> std::cout << tntdbx::Decimal(v.getDecimal()) << std::endl;
>
> The tntdb::Decimal will be very lightweight then.
>
> Tommi
We can do that if you like, but you may have second thoughts
since the iostream stuff is used to read and write the
decimal numbers from/to the database.
I can modify it however you like.
Thanks very much.
Regards, Mark
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Tntnet-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tntnet-general