{sigh}
from this end, it looks like gmail dropped the attachment
I should know better than to click Send twice when nothing seems to happen.

please, just apply it, and I can stop spamming the list ;)


On 28/03/06, Carl Franks <[EMAIL PROTECTED]> wrote:
> /me predicts mst will be annoyed with the number of revisions when he wakes up
>
> Here's the latest patch!
>
> I'm going to try and get some live db tests working, and so hopefully
> stop with the buggy nonsense.
>
Index: lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- lib/DBIx/Class/Storage/DBI.pm	(revision 1369)
+++ lib/DBIx/Class/Storage/DBI.pm	(working copy)
@@ -529,6 +529,59 @@
 
 Returns database type info for a given table columns.
 
+Keys which may be set include:
+
+=over
+
+=item C<data_type>
+
+=item C<size>
+
+=item C<default_value>
+
+=item C<is_nullable>
+
+=item C<is_unsigned> For numeric types.
+
+=item C<decimal_digits>
+
+=item C<data_set> For list types such as C<enum> and C<set>, contains
+an arrayref of valid values.
+
+=item C<range_min> For numeric types, the minimum valid value.
+
+=item C<range_max> For numeric types, the maximum valid value.
+
+=back
+
+Keys which may be set for various database's features/bugs.
+
+=over
+
+=item C<length_in_bytes> When the C<size> is a length, such as the length of
+a C<text> field, if this value is true, the length should be measured in
+bytes rather than characters.
+
+=item C<ignore_trailing_spaces> When the size is a length, such as the
+length of a C<text> field, if this value is true, trailing spaced should be
+counted.
+
+=item C<decimal_high_positive> For decimal types which, when positive,
+use the byte reserved for the sign to increase the precision by 1.
+
+For Example: The normal range of C<DECIMAL(5,2)> should be C<-999.99> to
+C<999.99>. C<decimal_high_positive> indicates that the valid range of values
+is actually C<-999.99> to C<9999.99>.
+
+=item C<decimal_literal_range> For decimal types which include the sign and
+decimal point in the precision length.
+
+For Example: The normal range of C<DECIMAL(5,2)> should be C<-999.99> to
+C<999.99>. C<decimal_literal_range> indicates that the valid range of values
+is actually C<-9.99> to C<99.99>.
+
+=back
+
 =cut
 
 sub columns_info_for {
Index: lib/DBIx/Class/Storage/DBI/mysql.pm
===================================================================
--- lib/DBIx/Class/Storage/DBI/mysql.pm	(revision 1369)
+++ lib/DBIx/Class/Storage/DBI/mysql.pm	(working copy)
@@ -2,21 +2,12 @@
 
 use strict;
 use warnings;
+use Carp::Clan qw/^DBIx::Class/;
 
 use base qw/DBIx::Class::Storage::DBI/;
 
 # __PACKAGE__->load_components(qw/PK::Auto/);
 
-sub last_insert_id {
-  return $_[0]->_dbh->{mysql_insertid};
-}
-
-sub sqlt_type {
-  return 'MySQL';
-}
-
-1;
-
 =head1 NAME
 
 DBIx::Class::Storage::DBI::mysql - Automatic primary key class for MySQL
@@ -31,6 +22,206 @@
 
 This class implements autoincrements for MySQL.
 
+=head1 METHODS
+
+=head2 columns_info_for
+
+Extends L<DBIx::Class::Storage::DBI/columns_info_for>.
+
+=cut
+
+sub columns_info_for {
+  my ($self, $table) = @_;
+
+  my $result;
+  
+  if ($self->dbh->can('column_info')) {
+    my $old_raise_err = $self->dbh->{RaiseError};
+    my $old_print_err = $self->dbh->{PrintError};
+    $self->dbh->{RaiseError} = 1;
+    $self->dbh->{PrintError} = 0;
+    eval {
+      my $sth = $self->dbh->column_info( undef, undef, $table, '%' );
+      $sth->execute();
+      while ( my $info = $sth->fetchrow_hashref() ){
+        my %column_info;
+        $column_info{data_type}     = $info->{TYPE_NAME};
+        $column_info{size}          = $info->{COLUMN_SIZE};
+        $column_info{is_nullable}   = $info->{NULLABLE} ? 1 : 0;
+        $column_info{default_value} = $info->{COLUMN_DEF};
+
+        my %info = $self->_extract_mysql_specs($info);
+        $column_info{$_} = $info{$_} for keys %info;
+
+        $result->{$info->{COLUMN_NAME}} = \%column_info;
+      }
+    };
+    $self->dbh->{RaiseError} = $old_raise_err;
+    $self->dbh->{PrintError} = $old_print_err;
+    return {} if $@;
+  }
+
+  return $result;
+}
+
+sub _extract_mysql_specs {
+  my ($self, $info) = @_;
+  
+  my $basetype   = lc($info->{TYPE_NAME});
+  my $mysql_type = lc($info->{mysql_type_name});
+  my %column_info;
+  
+  if ($basetype eq 'char') {
+    if (_version_lt($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{length_in_bytes} = 1;
+    }
+    $column_info{ignore_trailing_spaces} = 1;
+  }
+  elsif ($basetype eq 'varchar') {
+    if (_version_le($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{ignore_trailing_spaces} = 1;
+    }
+    if (_version_lt($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{length_in_bytes} = 1;
+    }
+  }
+  elsif ($basetype =~ /text$/) {
+    if ($basetype =~ /blob$/) {
+      $column_info{length_in_bytes} = 1;
+    }
+    elsif (_version_lt($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{length_in_bytes} = 1;
+    }
+  }
+  elsif ($basetype eq 'binary') {
+    $column_info{ignore_trailing_spaces} = 1;
+    $column_info{length_in_bytes}        = 1;
+  }
+  elsif ($basetype eq 'varbinary') {
+    if (_version_le($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{ignore_trailing_spaces} = 1;
+    }
+    $column_info{length_in_bytes} = 1;
+  }
+  elsif ($basetype =~ /^(enum|set)/) {
+    $column_info{data_set} = $info->{mysql_values};
+  }
+  elsif ($basetype =~ /int$/) {
+    if ($mysql_type =~ /unsigned /) {
+      my %max = (
+        tinyint   => 2**8 - 1,
+        smallint  => 2**16 - 1,
+        mediumint => 2**24 - 1,
+        int       => 2**32 - 1,
+        bigint    => 2**64 - 1,
+      );
+      $column_info{is_unsigned} = 1;
+      $column_info{range_min}   = 0;
+      $column_info{range_max}   = $max{$basetype};
+    }
+    else { # not unsigned
+      my %min = (
+        tinyint   => - 2**7,
+        smallint  => - 2**15,
+        mediumint => - 2**23,
+        int       => - 2**31,
+        bigint    => - 2**63,
+      );
+      my %max = (
+        tinyint   => 2**7 - 1,
+        smallint  => 2**15 - 1,
+        mediumint => 2**23 - 1,
+        int       => 2**31 - 1,
+        bigint    => 2**63 - 1,
+      );
+      $column_info{range_min} = $min{$basetype};
+      $column_info{range_max} = $max{$basetype};
+    }
+  }
+  elsif ($basetype =~ /^decimal/) {
+    if (_version_le($self->dbh->{mysql_serverinfo}, '4.1')) {
+      $column_info{decimal_high_positive} = 1;
+    }
+    if (_version_lt($self->dbh->{mysql_serverinfo}, '3.23')) {
+      $column_info{decimal_literal_range} = 1;
+    }
+    $column_info{decimal_digits} = $info->{DECIMAL_DIGITS};
+  }
+    
+  return %column_info;
+}
+
+sub _version_eq {
+  my ($x, $y) = @_;
+  
+  ($x, $y) = _version_normalize( @_ );
+  
+  return 1 if defined $x && $x eq $y;
+  return;
+}
+
+sub _version_lt {
+  my ($x, $y) = @_;
+  
+  ($x, $y) = _version_normalize( @_ );
+  
+  return 1 if defined $x && $x lt $y;
+  return;
+}
+
+sub _version_gt {
+  my ($x, $y) = @_;
+  
+  ($x, $y) = _version_normalize( @_ );
+  
+  return 1 if defined $x && $x gt $y;
+  return;
+}
+
+sub _version_le {
+  my ($x, $y) = @_;
+  
+  return 1 if _version_lt($x, $y) || _version_eq($x, $y);
+  return;
+}
+
+sub _version_ge {
+  my ($x, $y) = @_;
+  
+  return 1 if _version_gt($x, $y) || _version_eq($x, $y);
+  return;
+}
+
+sub _version_normalize {
+  my ($x, $y) = @_;
+  
+  my ($x1, $x2, $x3) = $x =~ /(^\d+)(?:\.(\d+))?(?:\.(\d+))?/
+    or return;
+  
+  $x2 = 0 if not defined $x2;
+  $x3 = 0 if not defined $x3;
+  
+  $x = sprintf "%03d%03d%03d", $x1, $x2, $x3;
+  
+  my ($y1, $y2, $y3) = $y =~ /(^\d+)(?:\.(\d+))?(?:\.(\d+))?/
+    or return;
+  
+  $y2 = 0 if not defined $y2;
+  $y3 = 0 if not defined $y3;
+  
+  $y = sprintf "%03d%03d%03d", $y1, $y2, $y3;
+  
+  return ($x, $y);
+}
+
+sub last_insert_id {
+  return $_[0]->_dbh->{mysql_insertid};
+}
+
+sub sqlt_type {
+  return 'MySQL';
+}
+
 =head1 AUTHORS
 
 Matt S. Trout <[EMAIL PROTECTED]>
@@ -40,3 +231,5 @@
 You may distribute this code under the same terms as Perl itself.
 
 =cut
+
+1;

_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/

Reply via email to