From: Jess Robinson Date: Tue, 19 Aug 2008 15:14:43 +0000 (+0000) Subject: Add views to mysql producer, thanks groditi X-Git-Tag: v0.11008~307 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d28afa66ea307053994416db5f869c9e1afb5be0;p=dbsrgits%2FSQL-Translator.git Add views to mysql producer, thanks groditi --- diff --git a/Changes b/Changes index b76a343..7174cdf 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,5 @@ +* Added support for CREATE VIEW + tests in the mysql producer (groditi) * Added support for SET fields in the mysql producer + test (groditi) * Added support for proper booleans in the mysql producer, when a mysql version of at least 4.x is supplied * Added support for proper enums under pg (as of 8.3), with pg version check, and deferrable constraints diff --git a/lib/SQL/Translator/Producer/MySQL.pm b/lib/SQL/Translator/Producer/MySQL.pm index 0ec71f1..7cf24c0 100644 --- a/lib/SQL/Translator/Producer/MySQL.pm +++ b/lib/SQL/Translator/Producer/MySQL.pm @@ -286,12 +286,69 @@ sub produce { }); } + for my $view ( $schema->get_views ) { +# print $view->name, "\n"; + push @table_defs, create_view($view, + { add_replace_view => $add_drop_table, + show_warnings => $show_warnings, + no_comments => $no_comments, + quote_table_names => $qt, + quote_field_names => $qf, + max_id_length => $max_id_length, + mysql_version => $mysql_version + }); + } + + # print "@table_defs\n"; push @table_defs, "SET foreign_key_checks=1;\n\n"; return wantarray ? ($create, @table_defs) : $create . join ('', @table_defs); } +sub create_view { + my ($view, $options) = @_; + my $qt = $options->{quote_table_names} || ''; + my $qf = $options->{quote_field_names} || ''; + + my $view_name = $view->name; + debug("PKG: Looking at view '${view_name}'\n"); + + # Header. Should this look like what mysqldump produces? + my $create = ''; + $create .= "--\n-- View: ${qt}${view_name}${qt}\n--\n" unless $options->{no_comments}; + $create .= 'CREATE'; + $create .= ' OR REPLACE' if $options->{add_replace_view}; + $create .= "\n"; + + my $extra = $view->extra; + # ALGORITHM + if( exists($extra->{mysql_algorithm}) && defined(my $algorithm = $extra->{mysql_algorithm}) ){ + $create .= " ALGORITHM = ${algorithm}\n" if $algorithm =~ /(?:UNDEFINED|MERGE|TEMPTABLE)/i; + } + # DEFINER + if( exists($extra->{mysql_definer}) && defined(my $user = $extra->{mysql_definer}) ){ + $create .= " DEFINER = ${user}\n"; + } + # SECURITY + if( exists($extra->{mysql_security}) && defined(my $security = $extra->{mysql_security}) ){ + $create .= " SQL SECURITY ${security}\n" if $security =~ /(?:DEFINER|INVOKER)/i; + } + + #Header, cont. + $create .= " VIEW ${qt}${view_name}${qt}"; + + if( my @fields = $view->fields ){ + my $list = join ', ', map { "${qf}${_}${qf}"} @fields; + $create .= " ( ${list} )"; + } + if( my $sql = $view->sql ){ + $create .= " AS (\n ${sql}\n )"; + } + $create .= ";\n\n"; + return $create; +} + sub create_table { my ($table, $options) = @_; diff --git a/t/38-mysql-producer.t b/t/38-mysql-producer.t index 39b127e..50eb682 100644 --- a/t/38-mysql-producer.t +++ b/t/38-mysql-producer.t @@ -19,7 +19,7 @@ use FindBin qw/$Bin/; #============================================================================= BEGIN { - maybe_plan(14, + maybe_plan(16, 'YAML', 'SQL::Translator::Producer::MySQL', 'Test::Differences', @@ -261,3 +261,39 @@ $field3_sql = SQL::Translator::Producer::MySQL::create_field($field3, { mysql_ve is($field3_sql, "myfield enum('0','1') NOT NULL", 'For Mysql < 4, use enum for boolean type'); $field3_sql = SQL::Translator::Producer::MySQL::create_field($field3,); is($field3_sql, "myfield enum('0','1') NOT NULL", 'When no version specified, use enum for boolean type'); + +{ + my $view1 = SQL::Translator::Schema::View->new( name => 'view_foo', + fields => [qw/id name/], + sql => 'SELECT id, name FROM thing', + extra => { + mysql_definer => 'CURRENT_USER', + mysql_algorithm => 'MERGE', + mysql_security => 'DEFINER', + }); + my $create_opts = { add_replace_view => 1, no_comments => 1 }; + my $view1_sql1 = SQL::Translator::Producer::MySQL::create_view($view1, $create_opts); + + my $view_sql_replace = "CREATE OR REPLACE + ALGORITHM = MERGE + DEFINER = CURRENT_USER + SQL SECURITY DEFINER + VIEW view_foo ( id, name ) AS ( + SELECT id, name FROM thing + );\n\n"; + is($view1_sql1, $view_sql_replace, 'correct "CREATE OR REPLACE VIEW" SQL'); + + + my $view2 = SQL::Translator::Schema::View->new( name => 'view_foo', + fields => [qw/id name/], + sql => 'SELECT id, name FROM thing',); + my $create2_opts = { add_replace_view => 0, no_comments => 1 }; + my $view1_sql2 = SQL::Translator::Producer::MySQL::create_view($view2, $create2_opts); + my $view_sql_noreplace = "CREATE + VIEW view_foo ( id, name ) AS ( + SELECT id, name FROM thing + );\n\n"; + is($view1_sql2, $view_sql_noreplace, 'correct "CREATE VIEW" SQL'); +} + +