On 30/07/13 21:30, H.Merijn Brand wrote:
On Tue, 30 Jul 2013 20:23:50 +0100, "Martin J. Evans"
<martin.ev...@easysoft.com> wrote:
On 30/07/2013 10:53, H.Merijn Brand wrote:
The TYPE attribute is defined to be NUMERIC. Several databases do not
follow that definition, like SQLite and CSV
Luckily, we control both DBD::CSV and the underlying DBD::File, se I
can "fix" that for at least DBD::CSV and probably all DBD's using the
DBD::File layer. I propose this change:
--8<---
diff --git a/lib/DBD/File.pm b/lib/DBD/File.pm
index 444c4d4..ffc5e84 100644
--- a/lib/DBD/File.pm
+++ b/lib/DBD/File.pm
@@ -280,6 +280,7 @@ my %supported_attrs = (
PRECISION => 1,
NULLABLE => 1,
);
+my $type_map;
sub FETCH
{
@@ -306,8 +307,23 @@ sub FETCH
my @colnames = $sth->sql_get_colnames ();
+ unless ($type_map) {
+ $type_map = { # Minimal type set (like CSV)
+ BLOB => -4,
+ TEXT => -1,
+ CHAR => 1,
+ INTEGER => 4,
+ REAL => 7,
+ VARCHAR => 12,
+ };
+ my $tia = $sth->{Database}->type_info_all ();
+ # TYPE_NAME => DATA_TYPE
+ $type_map->{$_->[0]} = $_->[1] for grep { ref $_ eq "ARRAY" }
@$tia;
I have not looked at this in context but it seems to me this code is
assuming element 0 and element 1 are TYPE_NAME and DATA_TYPE whereas
type_info_all starts with a map which describes the columns in the
result.
Yes, «grep { ref $_ eq "ARRAY" }» filters that out
It is a pseudo-hash, which I don't like, but it is unlikely to ever
change. Would you be more comfortable with this?
unless ($type_map) {
# TYPE_NAME => DATA_TYPE
$type_map = { # Minimal type set (like CSV)
BLOB => -4,
TEXT => -1,
CHAR => 1,
INTEGER => 4,
REAL => 7,
VARCHAR => 12,
};
if (my $tia = $sth->{Database}->type_info_all ()) {
my $tiah = shift @$tia;
my %tiah = map { uc ($_) => $tiah->{$_} } keys %$tiah;
my ($tni, $dti) = map {$tiah->{$_}} "TYPE_NAME",
"DATA_TYPE";
$type_map->{$_->[$tni]} = $_->[$dti] for @$tia;
}
}
works just as well for me
Yes.
+ }
+
$attr eq "TYPE" and
- return [ map { $sth->{f_overall_defs}{$_}{data_type} ||
"CHAR" }
+ return [ map { $type_map->{$_} || $_ }
+ map { $sth->{f_overall_defs}{$_}{data_type} ||
"VARCHAR" }
@colnames ];
$attr eq "PRECISION" and
-->8---
All DBI tests still pass, and several TODO tests in DBD::CSV now pass
If DBD::xxx provides GetInfo.pm and TypeInfo.pm, the conversions will
automatically be updated (once).
It will work as it stands so long as type_info_all maps type_name and
data_type as indexes 0 and 1. If that changes it looks like it will
break.
The chances that will ever change are ZERO
True but how many times have I fixed a bug because some coder made the same
assumption.
However, I might have misread this as I did not follow the context.
Martin
Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com