mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-11 13:40:07 +00:00
Resume for SchemaIterator. Use only next_lb; don't need first_lb in NibbleIterator.
This commit is contained in:
@@ -305,10 +305,9 @@ sub statements {
|
||||
sub boundaries {
|
||||
my ($self) = @_;
|
||||
return {
|
||||
first_lower => $self->{first_lb},
|
||||
lower => $self->{lb},
|
||||
next_lower => $self->{next_lb},
|
||||
upper => $self->{ub},
|
||||
next_lower => $self->{next_lb},
|
||||
last_upper => $self->{last_ub},
|
||||
};
|
||||
}
|
||||
@@ -439,8 +438,7 @@ sub _get_bounds {
|
||||
my ($self) = @_;
|
||||
return if $self->{one_nibble};
|
||||
|
||||
$self->{first_lb} = $self->{dbh}->selectrow_arrayref($self->{first_lb_sql});
|
||||
$self->{next_lb} = $self->{first_lb};
|
||||
$self->{next_lb} = $self->{dbh}->selectrow_arrayref($self->{first_lb_sql});
|
||||
MKDEBUG && _d('First lower boundary:', Dumper($self->{next_lb}));
|
||||
|
||||
$self->{last_ub} = $self->{dbh}->selectrow_arrayref($self->{last_ub_sql});
|
||||
|
@@ -60,6 +60,7 @@ my $tbl_name = qr{
|
||||
# Schema - <Schema> object to initialize while iterating.
|
||||
# TableParser - <TableParser> object to parse CREATE TABLE for tbl_struct.
|
||||
# keep_ddl - Keep CREATE TABLE (default false)
|
||||
# resume - Skip tables so first call to <next()> returns this "db.table".
|
||||
#
|
||||
# Returns:
|
||||
# SchemaIterator object
|
||||
@@ -75,8 +76,17 @@ sub new {
|
||||
die "I need either a dbh or file_itr argument"
|
||||
if (!$dbh && !$file_itr) || ($dbh && $file_itr);
|
||||
|
||||
my %resume;
|
||||
if ( my $table = $args{resume} ) {
|
||||
MKDEBUG && _d('Will resume from', $table);
|
||||
my ($db, $tbl) = $args{Quoter}->split_unquote($table);
|
||||
$resume{db} = $db;
|
||||
$resume{tbl} = $tbl;
|
||||
}
|
||||
|
||||
my $self = {
|
||||
%args,
|
||||
resume => \%resume,
|
||||
filters => _make_filters(%args),
|
||||
};
|
||||
|
||||
@@ -166,7 +176,7 @@ sub _make_filters {
|
||||
return \%filters;
|
||||
}
|
||||
|
||||
# Sub: next_schema_object
|
||||
# Sub: next
|
||||
# Return the next schema object or undef when no more schema objects.
|
||||
# Only filtered schema objects are returned. If iterating dump files
|
||||
# (i.e. the obj was created with a file_itr arg), then the returned
|
||||
@@ -186,7 +196,7 @@ sub _make_filters {
|
||||
# }
|
||||
# (end code)
|
||||
# The ddl is suitable for <TableParser::parse()>.
|
||||
sub next_schema_object {
|
||||
sub next {
|
||||
my ( $self ) = @_;
|
||||
|
||||
my $schema_obj;
|
||||
@@ -242,7 +252,8 @@ sub _iterate_files {
|
||||
my $db = $1; # XXX
|
||||
$db =~ s/^`//; # strip leading `
|
||||
$db =~ s/`$//; # and trailing `
|
||||
if ( $self->database_is_allowed($db) ) {
|
||||
if ( $self->database_is_allowed($db)
|
||||
&& $self->_resume_from_database($db) ) {
|
||||
$self->{db} = $db;
|
||||
}
|
||||
}
|
||||
@@ -261,7 +272,8 @@ sub _iterate_files {
|
||||
my ($tbl) = $chunk =~ m/$tbl_name/;
|
||||
$tbl =~ s/^\s*`//;
|
||||
$tbl =~ s/`\s*$//;
|
||||
if ( $self->table_is_allowed($self->{db}, $tbl) ) {
|
||||
if ( $self->table_is_allowed($self->{db}, $tbl)
|
||||
&& $self->_resume_from_table($tbl) ) {
|
||||
my ($ddl) = $chunk =~ m/^(?:$open_comment)?(CREATE TABLE.+?;)$/ms;
|
||||
if ( !$ddl ) {
|
||||
warn "Failed to parse CREATE TABLE from\n" . $chunk;
|
||||
@@ -308,7 +320,9 @@ sub _iterate_dbh {
|
||||
}
|
||||
|
||||
if ( !$self->{db} ) {
|
||||
$self->{db} = shift @{$self->{dbs}};
|
||||
do {
|
||||
$self->{db} = shift @{$self->{dbs}};
|
||||
} until $self->_resume_from_database($self->{db});
|
||||
MKDEBUG && _d('Next database:', $self->{db});
|
||||
return unless $self->{db};
|
||||
}
|
||||
@@ -330,6 +344,7 @@ sub _iterate_dbh {
|
||||
}
|
||||
|
||||
while ( my $tbl = shift @{$self->{tbls}} ) {
|
||||
next unless $self->_resume_from_table($tbl);
|
||||
my $engine;
|
||||
if ( $self->{filters}->{'engines'}
|
||||
|| $self->{filters}->{'ignore-engines'} ) {
|
||||
@@ -489,6 +504,36 @@ sub engine_is_allowed {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _resume_from_database {
|
||||
my ($self, $db) = @_;
|
||||
|
||||
# "Resume" from any db if we're not, in fact, resuming.
|
||||
return 1 unless $self->{resume}->{db};
|
||||
|
||||
if ( $db eq $self->{resume}->{db} ) {
|
||||
MKDEBUG && _d('At resume db', $db);
|
||||
delete $self->{resume}->{db};
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub _resume_from_table {
|
||||
my ($self, $tbl) = @_;
|
||||
|
||||
# "Resume" from any table if we're not, in fact, resuming.
|
||||
return 1 unless $self->{resume}->{tbl};
|
||||
|
||||
if ( $tbl eq $self->{resume}->{tbl} ) {
|
||||
MKDEBUG && _d('At resume table', $tbl);
|
||||
delete $self->{resume}->{tbl};
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub _d {
|
||||
my ($package, undef, $line) = caller 0;
|
||||
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
|
||||
|
@@ -9,7 +9,7 @@ BEGIN {
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More tests => 29;
|
||||
use Test::More tests => 30;
|
||||
|
||||
use SchemaIterator;
|
||||
use FileIterator;
|
||||
@@ -56,6 +56,7 @@ sub test_so {
|
||||
$si = new SchemaIterator(
|
||||
file_itr => $file_itr,
|
||||
keep_ddl => defined $args{keep_ddl} ? $args{keep_ddl} : 1,
|
||||
resume => $args{resume},
|
||||
OptionParser => $o,
|
||||
Quoter => $q,
|
||||
TableParser => $tp,
|
||||
@@ -65,6 +66,7 @@ sub test_so {
|
||||
$si = new SchemaIterator(
|
||||
dbh => $dbh,
|
||||
keep_ddl => defined $args{keep_ddl} ? $args{keep_ddl} : 1,
|
||||
resume => $args{resume},
|
||||
OptionParser => $o,
|
||||
Quoter => $q,
|
||||
TableParser => $tp,
|
||||
@@ -77,7 +79,7 @@ sub test_so {
|
||||
|
||||
my $res = "";
|
||||
my @objs;
|
||||
while ( my $obj = $si->next_schema_object() ) {
|
||||
while ( my $obj = $si->next() ) {
|
||||
if ( $args{return_objs} ) {
|
||||
push @objs, $obj;
|
||||
}
|
||||
@@ -222,7 +224,7 @@ SKIP: {
|
||||
unless @{$dbh->selectcol_arrayref('SHOW DATABASES LIKE "sakila"')};
|
||||
|
||||
test_so(
|
||||
filteres => [qw(-d sakila)],
|
||||
filters => [qw(-d sakila)],
|
||||
result => "", # hack; uses unlike instead
|
||||
unlike => qr/
|
||||
actor_info
|
||||
@@ -411,6 +413,21 @@ is(
|
||||
'DDL deleted unless keep_ddl'
|
||||
);
|
||||
|
||||
# ############################################################################
|
||||
# Resume
|
||||
# ############################################################################
|
||||
SKIP: {
|
||||
skip 'Sandbox master does not have the sakila database', 1
|
||||
unless @{$dbh->selectcol_arrayref('SHOW DATABASES LIKE "sakila"')};
|
||||
|
||||
test_so(
|
||||
filters => [qw(-d sakila)],
|
||||
result => "$out/resume-from-sakila-payment.txt",
|
||||
resume => 'sakila.payment',
|
||||
test_name => "Resume"
|
||||
);
|
||||
};
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
|
@@ -0,0 +1,4 @@
|
||||
sakila.payment
|
||||
sakila.rental
|
||||
sakila.staff
|
||||
sakila.store
|
Reference in New Issue
Block a user