Added mysql extra attribs for charset and collation.
Mark Addison [Wed, 8 Jun 2005 14:44:08 +0000 (14:44 +0000)]
Changes
lib/SQL/Translator/Producer/MySQL.pm
t/38-mysql-producer.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index ed19340..90e7f5b 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,5 @@
+*   YAML parser supports extra attributes on tables.
+
 *   All schema objects now support the extra attribute, so can
     have arbitary name/value data attached to them.
 
@@ -21,6 +23,7 @@
 *   MySQL Producer
     - Added 'mysql_table_type' extra attribute on tables.
     - Works out InnoDB tables from constraints.
+    - mysql_charset and mysql_collate extra attributes for tables and fiels.
 
 
 # -----------------------------------------------------------
index 5a5bba5..001e8fa 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Producer::MySQL;
 
 # -------------------------------------------------------------------
-# $Id: MySQL.pm,v 1.42 2005-01-13 11:50:23 grommit Exp $
+# $Id: MySQL.pm,v 1.43 2005-06-08 14:44:07 grommit Exp $
 # -------------------------------------------------------------------
 # Copyright (C) 2002-4 SQLFairy Authors
 #
@@ -63,19 +63,27 @@ Set the list of allowed values for Enum fields.
 
 Set the MySQL field options of the same name.
 
-=item mysql_table_type
+=item table.mysql_table_type
 
 Set the type of the table e.g. 'InnoDB', 'MyISAM'. This will be
 automatically set for tables involved in foreign key constraints if it is
 not already set explicitly. See L<"Table Types">.
 
+=item table.mysql_charset table.mysql_collate
+
+Set the tables default charater set and collation order.
+
+=item field.mysql_charset field.mysql_collate
+
+Set the fields charater set and collation order.
+
 =back
 
 =cut
 
 use strict;
 use vars qw[ $VERSION $DEBUG ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.42 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.43 $ =~ /(\d+)\.(\d+)/;
 $DEBUG   = 0 unless defined $DEBUG;
 
 use Data::Dumper;
@@ -167,6 +175,8 @@ sub produce {
             my $list      = $extra{'list'} || [];
             # \todo deal with embedded quotes
             my $commalist = join( ', ', map { qq['$_'] } @$list );
+            my $charset = $extra{'mysql_charset'};
+            my $collate = $extra{'mysql_collate'};
 
             #
             # Oracle "number" type -- figure best MySQL type
@@ -211,7 +221,7 @@ sub produce {
             }
 
             $field_def .= " $data_type";
-            
+
             if ( lc $data_type eq 'enum' ) {
                 $field_def .= '(' . $commalist . ')';
                        } 
@@ -219,6 +229,10 @@ sub produce {
                 $field_def .= '(' . join( ', ', @size ) . ')';
             }
 
+            # char sets
+            $field_def .= " CHARACTER SET $charset" if $charset;
+            $field_def .= " COLLATE $collate" if $collate;
+
             # MySQL qualifiers
             for my $qual ( qw[ binary unsigned zerofill ] ) {
                 my $val = $extra{ $qual || uc $qual } or next;
@@ -337,7 +351,11 @@ sub produce {
         #
         $create .= "\n)";
         my $mysql_table_type = $table->extra('mysql_table_type');
+        my $charset          = $table->extra('mysql_charset');
+        my $collate          = $table->extra('mysql_collate');
         $create .= " Type=$mysql_table_type" if $mysql_table_type;
+        $create .= " DEFAULT CHARACTER SET $charset" if $charset;
+        $create .= " COLLATE $collate" if $collate;
         $create .= ";\n\n";
     }
 
diff --git a/t/38-mysql-producer.t b/t/38-mysql-producer.t
new file mode 100644 (file)
index 0000000..a6ed999
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/perl -w 
+# vim:filetype=perl
+
+#
+# Note that the bulk of the testing for the mysql producer is in
+# 08postgres-to-mysql.t. This test is for additional stuff that can't be tested
+# using an Oracle schema as source e.g. extra attributes.
+#
+
+use strict;
+use Test::More;
+use Test::Exception;
+use Test::SQL::Translator qw(maybe_plan);
+
+use Data::Dumper;
+use FindBin qw/$Bin/;
+
+# Testing 1,2,3,4...
+#=============================================================================
+
+BEGIN {
+    maybe_plan(2,
+        'YAML',
+        'SQL::Translator::Producer::MySQL',
+        'Test::Differences',
+    )
+}
+use Test::Differences;
+use SQL::Translator;
+
+# Main test.
+{
+my $yaml_in = <<EOSCHEMA;
+---
+schema:
+  tables:
+    thing:
+      name: thing
+      extra:
+        mysql_charset: latin1 
+        mysql_collate: latin1_danish_ci 
+      order: 1
+      fields:
+        name:
+          name: name
+          data_type: varchar
+          size:
+            - 32
+          order: 1
+        swedish_name:
+          name: swedish_name
+          data_type: varchar
+          size: 32
+          extra:
+            mysql_charset: swe7
+          order: 2
+        description:
+          name: description
+          data_type: text
+          extra:
+            mysql_charset: utf8
+            mysql_collate: utf8_general_ci
+          order: 3
+EOSCHEMA
+
+my $mysql_out = <<EOSQL;
+SET foreign_key_checks=0;
+
+CREATE TABLE thing (
+  name varchar(32),
+  swedish_name varchar(32) CHARACTER SET swe7,
+  description text CHARACTER SET utf8 COLLATE utf8_general_ci
+) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
+
+EOSQL
+
+    my $sqlt;
+    $sqlt = SQL::Translator->new(
+        show_warnings  => 1,
+        no_comments    => 1,
+        from           => "YAML",
+        to             => "MySQL",
+    );
+
+    my $out;
+    $yaml_in = do {
+        local $/ = undef;
+        open(FILE, "/home/grommit/src/sqlfairy/test.yml") or die "$!";
+        <FILE>
+    };
+    $mysql_out = do {
+        local $/ = undef;
+        open(FILE, "/home/grommit/src/sqlfairy/test.sql") or die "$!";
+        <FILE>
+    };
+
+    $out = $sqlt->translate(\$yaml_in) or die "Translate error:".$sqlt->error;
+    ok $out ne ""                 ,"Produced something!";
+    eq_or_diff $out, $mysql_out   ,"Output looks right";
+}