From 39fe787fddfcbe04dd1135dc4a5713c95b21133a Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Mon, 20 Feb 2012 11:09:36 -0700 Subject: [PATCH] Test and quote all idents, including reserved words and those with spaces, in OSCCaptureSync.pm. --- lib/OSCCaptureSync.pm | 18 +++-- t/lib/OSCCaptureSync.t | 127 ++++++++++++++++++------------- t/lib/samples/osc/capsync001.txt | 6 +- t/lib/samples/osc/capsync002.txt | 3 + t/lib/samples/osc/capsync003.txt | 3 + t/lib/samples/osc/tbl002.sql | 13 ++++ t/lib/samples/osc/tbl003.sql | 13 ++++ 7 files changed, 120 insertions(+), 63 deletions(-) create mode 100644 t/lib/samples/osc/capsync002.txt create mode 100644 t/lib/samples/osc/capsync003.txt create mode 100644 t/lib/samples/osc/tbl002.sql create mode 100644 t/lib/samples/osc/tbl003.sql diff --git a/lib/OSCCaptureSync.pm b/lib/OSCCaptureSync.pm index eafb4e08..aa679c4e 100644 --- a/lib/OSCCaptureSync.pm +++ b/lib/OSCCaptureSync.pm @@ -37,13 +37,13 @@ use constant PTDEBUG => $ENV{PTDEBUG} || 0; # OSCCaptureSync object sub new { my ( $class, %args ) = @_; - my @required_args = qw(); + my @required_args = qw(Quoter); foreach my $arg ( @required_args ) { die "I need a $arg argument" unless $args{$arg}; } my $self = { - %args, + Quoter => $args{Quoter}, }; return bless $self, $class; @@ -73,11 +73,14 @@ sub _make_triggers { die "I need a $arg argument" unless $args{$arg}; } my ($db, $tbl, $tmp_tbl, $chunk_column) = @args{@required_args}; + my $q = $self->{Quoter}; - my $old_table = "`$db`.`$tbl`"; - my $new_table = "`$db`.`$tmp_tbl`"; - my $new_values = join(', ', map { "NEW.$_" } @{$args{columns}}); - my $columns = join(', ', @{$args{columns}}); + $chunk_column = $q->quote($chunk_column); + + my $old_table = $q->quote($db, $tbl); + my $new_table = $q->quote($db, $tmp_tbl); + my $new_values = join(', ', map { "NEW.".$q->quote($_) } @{$args{columns}}); + my $columns = join(', ', map { $q->quote($_) } @{$args{columns}}); my $delete_trigger = "CREATE TRIGGER mk_osc_del AFTER DELETE ON $old_table " . "FOR EACH ROW " @@ -113,9 +116,10 @@ sub cleanup { die "I need a $arg argument" unless $args{$arg}; } my ($dbh, $db, $msg) = @args{@required_args}; + my $q = $self->{Quoter}; foreach my $trigger ( qw(del ins upd) ) { - my $sql = "DROP TRIGGER IF EXISTS `$db`.`mk_osc_$trigger`"; + my $sql = "DROP TRIGGER IF EXISTS " . $q->quote($db, "mk_osc_$trigger"); $msg->($sql); $dbh->do($sql) unless $args{print}; } diff --git a/t/lib/OSCCaptureSync.t b/t/lib/OSCCaptureSync.t index 829ebaba..261c861e 100644 --- a/t/lib/OSCCaptureSync.t +++ b/t/lib/OSCCaptureSync.t @@ -14,6 +14,7 @@ use Test::More; use DSNParser; use Sandbox; use PerconaTest; +use Quoter; use OSCCaptureSync; use Data::Dumper; @@ -30,72 +31,92 @@ if ( !$dbh ) { } else { - plan tests => 4; + plan tests => 10; } -$sb->load_file("master", "t/lib/samples/osc/tbl001.sql"); -$dbh->do("USE osc"); - -my $osc = new OSCCaptureSync(); - +my $q = new Quoter(); +my $osc = new OSCCaptureSync(Quoter => $q); my $msg = sub { print "$_[0]\n"; }; +my $output; -my $output = output( - sub { - $osc->capture( - dbh => $dbh, - db => 'osc', - tbl => 't', - tmp_tbl => '__new_t', - columns => [qw(id c)], - chunk_column => 'id', - msg => $msg, - ) - }, -); +sub test_table { + my (%args) = @_; + my ($tbl, $col, $expect) = @args{qw(tbl col expect)}; -ok( - no_diff( - $output, - "t/lib/samples/osc/capsync001.txt", - cmd_output => 1, - ), - "SQL statments to create triggers" -); + $sb->load_file("master", "t/lib/samples/osc/$tbl"); + PerconaTest::wait_for_table($dbh, "osc.t", "id=5"); + $dbh->do("USE osc"); -$dbh->do('insert into t values (6, "f")'); -$dbh->do('update t set c="z" where id=1'); -$dbh->do('delete from t where id=3'); - -my $rows = $dbh->selectall_arrayref("select id, c from __new_t order by id"); -is_deeply( - $rows, - [ - [1, 'z'], # update t set c="z" where id=1 - [6, 'f'], # insert into t values (6, "f") - ], - "Triggers work" -) or print Dumper($rows); - -output(sub { - $osc->cleanup( - dbh => $dbh, - db => 'osc', - msg => $msg, + ok( + no_diff( + sub { + $osc->capture( + dbh => $dbh, + db => 'osc', + tbl => 't', + tmp_tbl => '__new_t', + columns => ['id', $col], + chunk_column => 'id', + msg => $msg, + ) + }, + "t/lib/samples/osc/$expect", + stderr => 1, + ), + "$tbl: SQL statments to create triggers" ); -}); -$rows = $dbh->selectall_arrayref("show triggers from `osc` like 't'"); -is_deeply( - $rows, - [], - "Cleanup removes the triggers" + $dbh->do("insert into t values (6, 'f')"); + $dbh->do("update t set `$col`='z' where id=1"); + $dbh->do("delete from t where id=3"); + + my $rows = $dbh->selectall_arrayref("select id, `$col` from __new_t order by id"); + is_deeply( + $rows, + [ + [1, 'z'], # update t set c="z" where id=1 + [6, 'f'], # insert into t values (6, "f") + ], + "$tbl: Triggers work" + ) or print Dumper($rows); + + output(sub { + $osc->cleanup( + dbh => $dbh, + db => 'osc', + msg => $msg, + ); + }); + + $rows = $dbh->selectall_arrayref("show triggers from `osc` like 't'"); + is_deeply( + $rows, + [], + "$tbl: Cleanup removes the triggers" + ); +} + +test_table( + tbl => "tbl001.sql", + col => "c", + expect => "capsync001.txt", +); + +test_table( + tbl => "tbl002.sql", + col => "default", + expect => "capsync002.txt", +); + +test_table( + tbl => "tbl003.sql", + col => "space col", + expect => "capsync003.txt", ); # ############################################################################# # Done. # ############################################################################# -$output = ''; { local *STDERR; open STDERR, '>', \$output; diff --git a/t/lib/samples/osc/capsync001.txt b/t/lib/samples/osc/capsync001.txt index 8f16663e..8dd2c941 100644 --- a/t/lib/samples/osc/capsync001.txt +++ b/t/lib/samples/osc/capsync001.txt @@ -1,3 +1,3 @@ -CREATE TRIGGER mk_osc_del AFTER DELETE ON `osc`.`t` FOR EACH ROW DELETE IGNORE FROM `osc`.`__new_t` WHERE `osc`.`__new_t`.id = OLD.id -CREATE TRIGGER mk_osc_upd AFTER UPDATE ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (id, c) VALUES (NEW.id, NEW.c) -CREATE TRIGGER mk_osc_ins AFTER INSERT ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (id, c) VALUES(NEW.id, NEW.c) +CREATE TRIGGER mk_osc_del AFTER DELETE ON `osc`.`t` FOR EACH ROW DELETE IGNORE FROM `osc`.`__new_t` WHERE `osc`.`__new_t`.`id` = OLD.`id` +CREATE TRIGGER mk_osc_upd AFTER UPDATE ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `c`) VALUES (NEW.`id`, NEW.`c`) +CREATE TRIGGER mk_osc_ins AFTER INSERT ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `c`) VALUES(NEW.`id`, NEW.`c`) diff --git a/t/lib/samples/osc/capsync002.txt b/t/lib/samples/osc/capsync002.txt new file mode 100644 index 00000000..846c074d --- /dev/null +++ b/t/lib/samples/osc/capsync002.txt @@ -0,0 +1,3 @@ +CREATE TRIGGER mk_osc_del AFTER DELETE ON `osc`.`t` FOR EACH ROW DELETE IGNORE FROM `osc`.`__new_t` WHERE `osc`.`__new_t`.`id` = OLD.`id` +CREATE TRIGGER mk_osc_upd AFTER UPDATE ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `default`) VALUES (NEW.`id`, NEW.`default`) +CREATE TRIGGER mk_osc_ins AFTER INSERT ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `default`) VALUES(NEW.`id`, NEW.`default`) diff --git a/t/lib/samples/osc/capsync003.txt b/t/lib/samples/osc/capsync003.txt new file mode 100644 index 00000000..e971e4e0 --- /dev/null +++ b/t/lib/samples/osc/capsync003.txt @@ -0,0 +1,3 @@ +CREATE TRIGGER mk_osc_del AFTER DELETE ON `osc`.`t` FOR EACH ROW DELETE IGNORE FROM `osc`.`__new_t` WHERE `osc`.`__new_t`.`id` = OLD.`id` +CREATE TRIGGER mk_osc_upd AFTER UPDATE ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `space col`) VALUES (NEW.`id`, NEW.`space col`) +CREATE TRIGGER mk_osc_ins AFTER INSERT ON `osc`.`t` FOR EACH ROW REPLACE INTO `osc`.`__new_t` (`id`, `space col`) VALUES(NEW.`id`, NEW.`space col`) diff --git a/t/lib/samples/osc/tbl002.sql b/t/lib/samples/osc/tbl002.sql new file mode 100644 index 00000000..075823b5 --- /dev/null +++ b/t/lib/samples/osc/tbl002.sql @@ -0,0 +1,13 @@ +DROP DATABASE IF EXISTS osc; +CREATE DATABASE osc; +USE osc; + +CREATE TABLE t ( + id INT UNSIGNED PRIMARY KEY, + `default` VARCHAR(16) +) ENGINE=InnoDB; + +CREATE TABLE __new_t LIKE t; + +INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'); + diff --git a/t/lib/samples/osc/tbl003.sql b/t/lib/samples/osc/tbl003.sql new file mode 100644 index 00000000..b0085f42 --- /dev/null +++ b/t/lib/samples/osc/tbl003.sql @@ -0,0 +1,13 @@ +DROP DATABASE IF EXISTS osc; +CREATE DATABASE osc; +USE osc; + +CREATE TABLE t ( + id INT UNSIGNED PRIMARY KEY, + `space col` VARCHAR(16) +) ENGINE=InnoDB; + +CREATE TABLE __new_t LIKE t; + +INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'); +