'datetime' => 'datetime',
);
+
+sub preprocess_schema {
+ my ($class, $schema) = @_;
+
+ # extra->{mysql_table_type} used to be the type. It belongs in options, so
+ # move it if we find it. Return Engine type if found in extra or options
+ my $mysql_table_type_to_options = sub {
+ my ($table) = @_;
+
+ my $extra = $table->extra;
+
+ my $extra_type = delete $extra->{mysql_table_type};
+
+ # Now just to find if there is already an Engine or Type option...
+ # and lets normalize it to ENGINE since:
+ #
+ # The ENGINE table option specifies the storage engine for the table.
+ # TYPE is a synonym, but ENGINE is the preferred option name.
+ #
+
+ # We have to use the hash directly here since otherwise there is no way
+ # to remove options.
+ my $options = ( $table->{options} ||= []);
+
+ # This assumes that there isn't both a Type and an Engine option.
+ for my $idx ( 0..$#{$options} ) {
+ my ($key, $value) = %{ $options->[$idx] };
+
+ next unless uc $key eq 'ENGINE' || uc $key eq 'TYPE';
+
+ # if the extra.mysql_table_type is given, use that
+ delete $options->[$idx]{$key};
+ return $options->[$idx]{ENGINE} = $value || $extra_type;
+
+ }
+
+ if ($extra_type) {
+ push @$options, { ENGINE => $extra_type };
+ return $extra_type;
+ }
+
+ };
+
+ # Names are only specific to a given schema
+ local %used_names = ();
+
+ #
+ # Work out which tables need to be InnoDB to support foreign key
+ # constraints. We do this first as we need InnoDB at both ends.
+ #
+ foreach my $table ( $schema->get_tables ) {
+
+ $mysql_table_type_to_options->($table);
+
+ foreach my $c( $table->get_constraints ) {
+ next unless $c->type eq FOREIGN_KEY;
+
+ # Normalize constraint names here.
+ my $c_name = $c->name;
+ # Give the constraint a name if it doesn't have one, so it doens't feel
+ # left out
+ $c_name = $table->name . '_fk' unless length $c_name;
+
+ $c->name( next_unused_name($c_name) );
+
+ for my $meth (qw/table reference_table/) {
+ my $table = $schema->get_table($c->$meth) || next;
+ next if $mysql_table_type_to_options->($table);
+ $table->options( { 'ENGINE' => 'InnoDB' } );
+ }
+ }
+ }
+}
+
sub produce {
my $translator = shift;
local $DEBUG = $translator->debug;
# \todo Don't set if MySQL 3.x is set on command line
$create .= "SET foreign_key_checks=0;\n\n";
- #
- # Work out which tables need to be InnoDB to support foreign key
- # constraints. We do this first as we need InnoDB at both ends.
- #
- foreach ( map { $_->get_constraints } $schema->get_tables ) {
- next unless $_->type eq FOREIGN_KEY;
- foreach my $meth (qw/table reference_table/) {
- my $table = $schema->get_table($_->$meth) || next;
- next if $table->extra('mysql_table_type');
- $table->extra( 'mysql_table_type' => 'InnoDB');
- }
- }
+ __PACKAGE__->preprocess_schema($schema);
#
# Generate sql
if uc $key eq 'ENGINE' or uc $key eq 'TYPE';
$create .= " $key=$value";
}
+
my $mysql_table_type = $table->extra('mysql_table_type');
- $create .= " Type=$mysql_table_type"
+ $create .= " ENGINE=$mysql_table_type"
if $mysql_table_type && !$table_type_defined;
my $charset = $table->extra('mysql_charset');
my $collate = $table->extra('mysql_collate');
my $qf = $options->{quote_field_names} || '';
my $qt = $options->{quote_table_names} || '';
my $leave_name = $options->{leave_name} || undef;
- my $counter = ($options->{fk_name_counter} ||= {});
my @fields = $c->fields or next;
my $table = $c->table;
my $c_name = $c->name;
- # Give the constraint a name if it doesn't have one, so it doens't feel
- # left out
- unless ( $c_name ){
- $c_name = $table->name . '_fk';
- }
-
- $counter->{$table} ||= {};
my $def = join(' ',
map { $_ || () }
'CONSTRAINT',
- $qt . join('_', next_unused_name($c_name)
- ) . $qt,
+ $qt . $c_name . $qt,
'FOREIGN KEY'
);