X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FTranslator%2FParser%2FMySQL.pm;h=a25de2d38c8d4afb59ceb7c5e2936db0c0646ff0;hb=782b5a43519d2713171767f74a544fe9892542ea;hp=967176abfa99187f5b805875d81a0654bf99a37b;hpb=bb4c66d1b6c76b02227f963a1d801d52d53eaf3e;p=dbsrgits%2FSQL-Translator.git diff --git a/lib/SQL/Translator/Parser/MySQL.pm b/lib/SQL/Translator/Parser/MySQL.pm index 967176a..a25de2d 100644 --- a/lib/SQL/Translator/Parser/MySQL.pm +++ b/lib/SQL/Translator/Parser/MySQL.pm @@ -1,9 +1,9 @@ package SQL::Translator::Parser::MySQL; # ------------------------------------------------------------------- -# $Id: MySQL.pm,v 1.58 2007-03-19 17:15:24 duality72 Exp $ +# $Id$ # ------------------------------------------------------------------- -# Copyright (C) 2002-4 SQLFairy Authors +# Copyright (C) 2002-2009 SQLFairy Authors # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -134,11 +134,22 @@ A subset of INSERT that we ignore: INSERT anything +=head1 ARGUMENTS + +This parser takes a single optional parser_arg C, which +provides the desired version for the target database. Any statement in the processed +dump file, that is commented with a version higher than the one supplied, will be stripped. + +Valid version specifiers for C are listed L + +More information about the MySQL comment-syntax: L + + =cut use strict; use vars qw[ $DEBUG $VERSION $GRAMMAR @EXPORT_OK ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.58 $ =~ /(\d+)\.(\d+)/; +$VERSION = '1.99'; $DEBUG = 0 unless defined $DEBUG; use Data::Dumper; @@ -148,6 +159,8 @@ use Storable qw(dclone); use DBI qw(:sql_types); use base qw(Exporter); +use SQL::Translator::Utils qw/parse_mysql_version/; + our %type_mapping = ( ); @@ -300,7 +313,7 @@ create : CREATE UNIQUE(?) /(index|key)/i index_name /on/i table_name '(' field_n push @{ $tables{ $item{'table_name'} }{'indices'} }, { name => $item[4], - type => $item[2] ? 'unique' : 'normal', + type => $item[2][0] ? 'unique' : 'normal', fields => $item[8], } ; @@ -521,6 +534,7 @@ reference_option: /restrict/i | index : normal_index | fulltext_index + | spatial_index | table_name : NAME @@ -583,7 +597,7 @@ unsigned : /unsigned/i { $return = 0 } default_val : /default/i 'CURRENT_TIMESTAMP' { - $return = $item[2]; + $return = \$item[2]; } | /default/i /'(?:.*?\\')*.*?'|(?:')?[\w\d:.-]*(?:')?/ @@ -667,10 +681,20 @@ fulltext_index : /fulltext/i KEY(?) index_name(?) '(' name_with_opt_paren(s /,/) } } +spatial_index : /spatial/i KEY(?) index_name(?) '(' name_with_opt_paren(s /,/) ')' + { + $return = { + supertype => 'index', + type => 'spatial', + name => $item{'index_name(?)'}[0], + fields => $item[5], + } + } + name_with_opt_paren : NAME parens_value_list(s?) { $item[2][0] ? "$item[1]($item[2][0][0])" : $item[1] } -UNIQUE : /unique/i { 1 } +UNIQUE : /unique/i KEY : /key/i | /index/i @@ -689,6 +713,10 @@ table_option : /comment/i /=/ /'.*?'/ { $return = { 'COLLATE' => $item[2] } } + | /union/i /\s*=\s*/ '(' table_name(s /,/) ')' + { + $return = { $item[1] => $item[4] }; + } | WORD /\s*=\s*/ WORD { $return = { $item[1] => $item[3] }; @@ -714,7 +742,7 @@ COMMA : ',' BACKTICK : '`' -NAME : BACKTICK /\w+/ BACKTICK +NAME : BACKTICK /[^`]+/ BACKTICK { $item[2] } | /\w+/ { $item[1] } @@ -741,7 +769,6 @@ END_OF_GRAMMAR sub parse { my ( $translator, $data ) = @_; my $parser = Parse::RecDescent->new($GRAMMAR); - local $::RD_TRACE = $translator->trace ? 1 : undef; local $DEBUG = $translator->debug; @@ -751,7 +778,9 @@ sub parse { } # Preprocess for MySQL-specific and not-before-version comments from mysqldump - my $parser_version = $translator->parser_args->{mysql_parser_version} || DEFAULT_PARSER_VERSION; + my $parser_version = + parse_mysql_version ($translator->parser_args->{mysql_parser_version}, 'mysql') + || DEFAULT_PARSER_VERSION; while ( $data =~ s#/\*!(\d{5})?(.*?)\*/#($1 && $1 > $parser_version ? '' : $2)#es ) {} my $result = $parser->startrule($data); @@ -836,7 +865,19 @@ sub parse { } if ( my @options = @{ $tdata->{'table_options'} || [] } ) { - $table->options( \@options ) or die $table->error; + my @cleaned_options; + my @ignore_opts = $translator->parser_args->{ignore_opts}?split(/,/,$translator->parser_args->{ignore_opts}):(); + if (@ignore_opts) { + my $ignores = { map { $_ => 1 } @ignore_opts }; + foreach my $option (@options) { + # make sure the option isn't in ignore list + my ($option_key) = keys %$option; + push(@cleaned_options, $option) unless (exists $ignores->{$option_key}); + } + } else { + @cleaned_options = @options; + } + $table->options( \@cleaned_options ) or die $table->error; } for my $cdata ( @{ $tdata->{'constraints'} || [] } ) {