Attempt to be more robust.lib/SQL/Translator/Validator.pm
Darren Chamberlain [Thu, 17 Apr 2003 13:42:48 +0000 (13:42 +0000)]
BUGS
MANIFEST
lib/SQL/Translator/Parser/Excel.pm
lib/SQL/Translator/Parser/xSV.pm
lib/SQL/Translator/Producer/MySQL.pm
lib/SQL/Translator/Validator.pm
t/10excel.t
t/data/Excel/t.xls

diff --git a/BUGS b/BUGS
index 4f59eb6..58c5954 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -5,3 +5,4 @@ datatype text needs default size in ::Parser::MySQL (comes out as size 0)
 SQL Comments (technically) begin with '-- ', not '#'
 MySQL parser misses double-quoted strings in DEFAULT sections (I think)
 MySQL parser misses primary key declarations that don't occur as part of a field definition line (I think)
+MySQL parser assumes size element of $data->{$table}->{fields}->{$fieldname}->{size} is an array.
index 10afc7b..ecf02fc 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -36,6 +36,7 @@ t/07p_args.t
 t/08postgres-to-mysql.t
 t/09auto-dia.t
 t/10excel.t
+t/11normalize.t
 t/data/Excel/t.xls
 t/data/mysql/Apache-Session-MySQL.sql
 t/data/mysql/BGEP-RE-create.sql
index e8637b2..2fb3c29 100644 (file)
@@ -41,70 +41,80 @@ turn the data into a database tables or graphs.
 =cut
 
 use strict;
-use vars qw[ $DEBUG $VERSION @EXPORT_OK ];
-$DEBUG   = 0 unless defined $DEBUG;
+use vars qw($DEBUG $VERSION @EXPORT_OK);
+$DEBUG = 0 unless defined $DEBUG;
 
-use Data::Dumper;
 use Spreadsheet::ParseExcel;
 use Exporter;
+use SQL::Translator::Utils qw(debug normalize_name);
+
 use base qw(Exporter);
 
 @EXPORT_OK = qw(parse);
 
 # -------------------------------------------------------------------
+# parse($tr, $data)
+#
+# Note that $data, in the case of this parser, is unuseful.
+# Spreadsheet::ParseExcel works on files, not data streams.
+# -------------------------------------------------------------------
 sub parse {
-    my ( $translator, $data ) = @_;
-    my $parsed        =  {
-        table1        => {
-            "type"    => undef,
-            "indices" => [ { } ],
-            "fields"  => { },
-        },
-    };
-
-    my $tr = Spreadsheet::ParseExcel->new;
-    $tr->Parse( $data ); 
-    my $r = 1; # For now we will assume all column names are in the first row 
-    my $c = 0; 
-
-    #
-    # Mikey, what's going on here?
-    #
-    my @parsed = map { return $tr->{'Cells'}[$r][$c] } ( 
-        $c  = $tr->{'MinCol'}; 
-        $c <= $tr->{'MaxCol'}; # Is "<=" right?
-        $c++;
-    );
-
-    for ( my $i = 0; $i < @parsed; $i++ ) {
-        $parsed->{'table1'}->{'fields'}->{$parsed[$i]} = {
-            type           => 'field',
-            order          => $i,
-            name           => $parsed[$i],
-
-            # Default datatype is 'char'
-            data_type      => 'char',
-
-            # default size is 8bits; something more reasonable?
-            size           => 255,
-            null           => 1,
-            default        => '',
-            is_auto_inc    => undef,
-
-            # field field is the primary key
-            is_primary_key => ($i == 0) ? 1 : undef,
+    my ($tr, $data) = @_;
+    my $filename = $tr->filename || return;
+    my $wb = Spreadsheet::ParseExcel::Workbook->Parse($filename);
+    my (%parsed, $wb_count, $num);
+    my $table_no = 0;
+
+    my $wb_count = $wb->{SheetCount};
+    for $num (0 .. $wb_count - 1) {
+        my $ws = $wb->Worksheet($num);
+        my $name = $ws->{Name} || ++$table_no;
+
+        $name = normalize_name($name);
+
+        my @cols = $ws->ColRange;
+        next unless $cols[1] > 0;
+
+        $parsed{$name} = {
+            table_name  => $name,
+            type        => undef,
+            indices     => [ {} ],
+            fields      => { },
+        };
+
+        for my $col ($cols[0] .. $cols[1]) {
+            my $cell = $ws->Cell(0, $col);
+            $parsed{$name}->{'fields'}->{$cell->{Val}} = {
+                type           => 'field',
+                order          => $col,
+                name           => $cell->{Val},
+
+                # Default datatype is 'char'
+                data_type      => ET_to_ST($cell->{Type}),
+
+                # default size is 8bits; something more reasonable?
+                size           => [ 255 ],
+                null           => 1,
+                default        => '',
+                is_auto_inc    => undef,
+
+                # field field is the primary key
+                is_primary_key => ($col == 0) ? 1 : undef,
+            }
         }
     }
 
-   
-    # Field 0 is primary key, by default, so add an index
-    for ($parsed->{'table1'}->{'indices'}->[0]) {
-        $_->{'type'} = 'primary_key';
-        $_->{'name'} = undef;
-        $_->{'fields'} = [ $parsed[0] ];
-    }
+    return \%parsed;
+}
 
-   return $parsed;
+my %ET_to_ST = (
+    'Text'    => 'VARCHAR',
+    'Date'    => 'DATETIME',
+    'Numeric' => 'DOUBLE',
+);
+sub ET_to_ST {
+    my $et = shift;
+    $ET_to_ST{$et} || $ET_to_ST{'Text'};
 }
 
 1;
@@ -114,6 +124,7 @@ sub parse {
 =head1 AUTHORS
 
 Mike Mellilo <mmelillo@users.sourceforge.net>,
+darren chamberlain E<lt>dlc@users.sourceforge.netE<gt>
 Ken Y. Clark E<lt>kclark@cpan.orgE<gt>
 
 =head1 SEE ALSO
index 46b9624..dc239ad 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Parser::xSV;
 
 # -------------------------------------------------------------------
-# $Id: xSV.pm,v 1.4 2003-01-27 17:04:46 dlc Exp $
+# $Id: xSV.pm,v 1.5 2003-04-17 13:42:45 dlc Exp $
 # -------------------------------------------------------------------
 # Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>,
 #                    darren chamberlain <darren@cpan.org>,
@@ -24,7 +24,7 @@ package SQL::Translator::Parser::xSV;
 
 use strict;
 use vars qw($VERSION @EXPORT);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/;
 
 use Exporter;
 use Text::ParseWords qw(quotewords);
@@ -60,7 +60,7 @@ sub parse {
             data_type      => "char",
 
             # default size is 8bits; something more reasonable?
-            size           => 255,
+            size           => [ 255 ],
             null           => 1,
             default        => "",
             is_auto_inc    => undef,
index 4d56f53..549378b 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Producer::MySQL;
 
 # -------------------------------------------------------------------
-# $Id: MySQL.pm,v 1.12 2003-04-14 19:20:26 kycl4rk Exp $
+# $Id: MySQL.pm,v 1.13 2003-04-17 13:42:45 dlc Exp $
 # -------------------------------------------------------------------
 # Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>,
 #                    darren chamberlain <darren@cpan.org>,
@@ -24,7 +24,7 @@ package SQL::Translator::Producer::MySQL;
 
 use strict;
 use vars qw[ $VERSION $DEBUG ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.12 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/;
 $DEBUG   = 0 unless defined $DEBUG;
 
 use Data::Dumper;
@@ -221,7 +221,7 @@ sub produce {
         # Footer
         #
         $create .= "\n)";
-        while ( my ( $key, $val ) = each %{ $table_data->{'table_options'} } ) {
+        while ( my ( $key, $val ) = each %{ $table_data->{'table_options'} ||= { } } ) {
             $create .= " $key=$val" 
         }
         $create .= ";\n\n";
index 97910e7..fe64ba7 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Validator;
 
 # ----------------------------------------------------------------------
-# $Id: Validator.pm,v 1.7 2003-01-27 17:04:45 dlc Exp $
+# $Id: Validator.pm,v 1.8 2003-04-17 13:42:44 dlc Exp $
 # ----------------------------------------------------------------------
 # Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>,
 #                    darren chamberlain <darren@cpan.org>,
@@ -24,7 +24,7 @@ package SQL::Translator::Validator;
 
 use strict;
 use vars qw($VERSION @EXPORT);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.8 $ =~ /(\d+)\.(\d+)/;
 
 use Exporter;
 use base qw(Exporter);
@@ -85,9 +85,11 @@ sub validate {
             $log .= "\n\tIndices:";
             if (@indices) {
                 for my $index (@indices) {
+                    next unless ref($index) eq 'HASH';
+                    next unless scalar keys %$index;
                     $log .= "\n\t\t" . ($index->{"name"} || "(unnamed)")
                          .  " on "
-                         .  join ", ", @{$index->{"fields"}};
+                         .  join ", ", @{$index->{"fields"} ||= []};
                 }
             } else {
                 $log .= " none defined";
index 53d90b6..17a6cec 100644 (file)
@@ -4,10 +4,20 @@
 
 use Test::More;
 use SQL::Translator;
+use SQL::Translator::Validator;
 
-plan tests => 1;
+plan tests => 6;
 
 # Basic test
 use_ok("SQL::Translator::Parser::Excel");
 
-#my $tr = SQL::Translator->new(parser => "Excel");
+my $tr = SQL::Translator->new(parser => "Excel");
+my $t = $tr->translate(filename => "t/data/Excel/t.xls");
+
+ok(scalar $tr->translate(producer => "MySQL"));
+
+ok($t->{Sheet1});
+ok(not defined $t->{Sheet2});
+ok(not defined $t->{Sheet3});
+
+ok($t->{Sheet1}->{fields}->{ID}->{is_primary_key});
index 3cc26f2..2ee268c 100644 (file)
Binary files a/t/data/Excel/t.xls and b/t/data/Excel/t.xls differ