From: Peter Rabbitson Date: Sun, 3 May 2009 02:18:28 +0000 (+0000) Subject: Teach sqlite how to deal with multi-event triggers X-Git-Tag: v0.11008~177 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=410d4a4252243e6679a9303fbcb7a94e5e1588d1;p=dbsrgits%2FSQL-Translator.git Teach sqlite how to deal with multi-event triggers --- diff --git a/lib/SQL/Translator/Producer/SQLite.pm b/lib/SQL/Translator/Producer/SQLite.pm index 567db85..64f0bfb 100644 --- a/lib/SQL/Translator/Producer/SQLite.pm +++ b/lib/SQL/Translator/Producer/SQLite.pm @@ -365,43 +365,53 @@ sub create_trigger { my ($trigger, $options) = @_; my $add_drop = $options->{add_drop_trigger}; - my $name = $trigger->name; - my @create; - - push @create, "DROP TRIGGER IF EXISTS $name" if $add_drop; + my @statements; + my $trigger_name = $trigger->name; my $events = $trigger->database_events; - die "Can't handle multiple events in triggers" if @{ $events || [] } > 1; + for my $evt ( @$events ) { - my $action = ""; + my $trig_name = $trigger_name; + if (@$events > 1) { + $trig_name .= "_$evt"; - $DB::single = 1; - unless (ref $trigger->action) { - $action .= "BEGIN " . $trigger->action . " END"; - } else { - $action = $trigger->action->{for_each} . " " - if $trigger->action->{for_each}; + warn "Multiple database events supplied for trigger '$trigger_name', ", + "creating trigger '$trig_name' for the '$evt' event.\n" if $WARN; + } - $action = $trigger->action->{when} . " " - if $trigger->action->{when}; + push @statements, "DROP TRIGGER IF EXISTS $trig_name" if $add_drop; - my $steps = $trigger->action->{steps} || []; - $action .= "BEGIN "; - for (@$steps) { - $action .= $_ . "; " + $DB::single = 1; + my $action = ""; + if (not ref $trigger->action) { + $action .= "BEGIN " . $trigger->action . " END"; } - $action .= "END"; - } + else { + $action = $trigger->action->{for_each} . " " + if $trigger->action->{for_each}; + + $action = $trigger->action->{when} . " " + if $trigger->action->{when}; - push @create, "CREATE TRIGGER $name " . - $trigger->perform_action_when . " " . - $events->[0] . - " on " . $trigger->on_table . " " . - $action; + my $steps = $trigger->action->{steps} || []; + + $action .= "BEGIN "; + $action .= $_ . "; " for (@$steps); + $action .= "END"; + } + + push @statements, sprintf ( + 'CREATE TRIGGER %s %s %s on %s %s', + $trig_name, + $trigger->perform_action_when, + $evt, + $trigger->on_table, + $action + ); + } - return @create; - + return @statements; } sub alter_table { } # Noop diff --git a/t/48xml-to-sqlite.t b/t/48xml-to-sqlite.t index 4dd1da7..427f0d2 100644 --- a/t/48xml-to-sqlite.t +++ b/t/48xml-to-sqlite.t @@ -71,6 +71,14 @@ DROP TRIGGER IF EXISTS foo_trigger; CREATE TRIGGER foo_trigger after insert on Basic BEGIN update modified=timestamp(); END; +DROP TRIGGER IF EXISTS bar_trigger_insert; + +CREATE TRIGGER bar_trigger_insert before insert on Basic BEGIN update modified2=timestamp(); END; + +DROP TRIGGER IF EXISTS bar_trigger_update; + +CREATE TRIGGER bar_trigger_update before update on Basic BEGIN update modified2=timestamp(); END; + COMMIT; SQL @@ -108,7 +116,12 @@ CREATE VIEW email_list AS SELECT email FROM Basic WHERE email IS NOT NULL', 'DROP TRIGGER IF EXISTS foo_trigger', 'CREATE TRIGGER foo_trigger after insert on Basic BEGIN update modified=timestamp(); END', - 'COMMIT' + 'DROP TRIGGER IF EXISTS bar_trigger_insert', + 'CREATE TRIGGER bar_trigger_insert before insert on Basic BEGIN update modified2=timestamp(); END', + 'DROP TRIGGER IF EXISTS bar_trigger_update', + 'CREATE TRIGGER bar_trigger_update before update on Basic BEGIN update modified2=timestamp(); END', + 'COMMIT', + ], 'SQLite translate in list context matches');