Skip Menu |

This queue is for tickets about the SQL-Translator CPAN distribution.

Report information
The Basics
Id: 63452
Status: resolved
Priority: 0/
Queue: SQL-Translator

People
Owner: Nobody in particular
Requestors: ilmari [...] ilmari.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 0.11007



Subject: [PATCH 2/2] Add support for triggers in the MySQL producer
Date: Mon, 29 Nov 2010 23:54:15 +0000
To: bug-SQL-Translator [...] rt.cpan.org
From: Dagfinn Ilmari Mannsåker <ilmari [...] ilmari.org>
--- Changes | 1 + lib/SQL/Translator/Producer/MySQL.pm | 50 ++++++++++++++++++ t/64xml-to-mysql.t | 95 ++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 0 deletions(-) create mode 100644 t/64xml-to-mysql.t diff --git a/Changes b/Changes index 7fb442c..fdcbb23 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,7 @@ * Some minor fixes to squash warnings on new perls * Support a custom_type_name hint when creating enum types in PostgreSQL * Fix sqlt options/pod mismatch (RT#58318) +* Add support for triggers in the MySQL producer # ---------------------------------------------------------- # 0.11006 2010-06-03 diff --git a/lib/SQL/Translator/Producer/MySQL.pm b/lib/SQL/Translator/Producer/MySQL.pm index db7f7c8..bfa1da6 100644 --- a/lib/SQL/Translator/Producer/MySQL.pm +++ b/lib/SQL/Translator/Producer/MySQL.pm @@ -320,6 +320,20 @@ sub produce { } } + if ($mysql_version >= 5.000002) { + for my $trigger ( $schema->get_triggers ) { + push @table_defs, create_trigger($trigger, + { add_drop_trigger => $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"; @@ -327,6 +341,42 @@ sub produce { return wantarray ? ($create ? $create : (), @create, @table_defs) : ($create . join('', map { $_ ? "$_;\n\n" : () } (@create, @table_defs))); } +sub create_trigger { + my ($trigger, $options) = @_; + my $qt = $options->{quote_table_names} || ''; + my $qf = $options->{quote_field_names} || ''; + + my $trigger_name = $trigger->name; + debug("PKG: Looking at trigger '${trigger_name}'\n"); + + my @statements; + + my $events = $trigger->database_events; + for my $event ( @$events ) { + my $name = $trigger_name; + if (@$events > 1) { + $name .= "_$event"; + + warn "Multiple database events supplied for trigger '${trigger_name}', ", + "creating trigger '${name}' for the '${event}' event\n" + if $options->{show_warnings}; + } + + my $action = $trigger->action; + $action .= ";" unless $action =~ /;\s*\z/; + + push @statements, "DROP TRIGGER IF EXISTS ${qt}${name}${qt}" if $options->{add_drop_trigger}; + push @statements, sprintf( + "CREATE TRIGGER ${qt}%s${qt} %s %s ON ${qt}%s${qt}\n FOR EACH ROW BEGIN %s END", + $name, $trigger->perform_action_when, $event, $trigger->on_table, $action, + ); + + } + # Tack the comment onto the first statement + $statements[0] = "--\n-- Trigger ${qt}${trigger_name}${qt}\n--\n" . $statements[0] unless $options->{no_comments}; + return @statements; +} + sub create_view { my ($view, $options) = @_; my $qt = $options->{quote_table_names} || ''; diff --git a/t/64xml-to-mysql.t b/t/64xml-to-mysql.t new file mode 100644 index 0000000..fea07b0 --- /dev/null +++ b/t/64xml-to-mysql.t @@ -0,0 +1,95 @@ +#!/usr/bin/perl +use strict; + +use FindBin qw/$Bin/; +use Test::More; +use Test::SQL::Translator; +use Test::Exception; +use Test::Differences; +use Data::Dumper; +use SQL::Translator; +use SQL::Translator::Schema::Constants; + + +BEGIN { + maybe_plan(2, 'SQL::Translator::Parser::XML::SQLFairy', + 'SQL::Translator::Producer::MySQL'); +} + +my $xmlfile = "$Bin/data/xml/schema.xml"; + +my $sqlt; +$sqlt = SQL::Translator->new( + no_comments => 1, + show_warnings => 0, + add_drop_table => 1, + producer_args => { + mysql_version => 5.005, + }, +); + +die "Can't find test schema $xmlfile" unless -e $xmlfile; + +my @want = ( + q[SET foreign_key_checks=0], + + q[DROP TABLE IF EXISTS `Basic`], + q[CREATE TABLE `Basic` ( + `id` integer(10) zerofill NOT NULL auto_increment, + `title` varchar(100) NOT NULL DEFAULT 'hello', + `description` text DEFAULT '', + `email` varchar(500), + `explicitnulldef` varchar(255), + `explicitemptystring` varchar(255) DEFAULT '', + `emptytagdef` varchar(255) DEFAULT '' comment 'Hello emptytagdef', + `another_id` integer(10) DEFAULT 2, + `timest` timestamp, + INDEX `titleindex` (`title`), + INDEX (`another_id`), + PRIMARY KEY (`id`), + UNIQUE `emailuniqueindex` (`email`), + UNIQUE `very_long_index_name_on_title_field_which_should_be_tru_14b59999` (`title`), + CONSTRAINT `Basic_fk` FOREIGN KEY (`another_id`) REFERENCES `Another` (`id`) +) ENGINE=InnoDB], + + q[DROP TABLE IF EXISTS `Another`], + q[CREATE TABLE `Another` ( + `id` integer(10) NOT NULL auto_increment, + `num` numeric(10, 2), + PRIMARY KEY (`id`) +) ENGINE=InnoDB], + q[CREATE OR REPLACE + VIEW `email_list` ( `email` ) AS + SELECT email FROM Basic WHERE (email IS NOT NULL) +], + + q[DROP TRIGGER IF EXISTS `foo_trigger`], + q[CREATE TRIGGER `foo_trigger` after insert ON `Basic` + FOR EACH ROW BEGIN update modified=timestamp(); END], + + q[DROP TRIGGER IF EXISTS `bar_trigger_insert`], + q[CREATE TRIGGER `bar_trigger_insert` before insert ON `Basic` + FOR EACH ROW BEGIN update modified2=timestamp(); END], + + q[DROP TRIGGER IF EXISTS `bar_trigger_update`], + q[CREATE TRIGGER `bar_trigger_update` before update ON `Basic` + FOR EACH ROW BEGIN update modified2=timestamp(); END], + + q[SET foreign_key_checks=1], +); + +my $sql = $sqlt->translate( + from => 'XML-SQLFairy', + to => 'MySQL', + filename => $xmlfile, +) or die $sqlt->error; + +eq_or_diff($sql, join("", map { "$_;\n\n" } @want)); + +my @sql = $sqlt->translate( + from => 'XML-SQLFairy', + to => 'MySQL', + filename => $xmlfile, +) or die $sqlt->error; + +is_deeply(\@sql, \@want); -- 1.7.1