Simplify NibbleIterator callbacks. Pass args to init callback so caller can check ub_sth.

This commit is contained in:
Daniel Nichter
2011-09-27 08:21:34 -06:00
parent c9e8444166
commit 83bbe45187
2 changed files with 61 additions and 45 deletions

View File

@@ -64,8 +64,7 @@ sub new {
# Get an index to nibble by. We'll order rows by the index's columns.
my $index = _find_best_index(%args);
if ( !$index && !$one_nibble ) {
die "Cannot chunk table $tbl->{db}.$tbl->{tbl} because there is "
. "no good index and the table is oversized.";
die "There is no good index and the table is oversized.";
}
my $self;
@@ -101,9 +100,6 @@ sub new {
limit => 0,
nibble_sql => $nibble_sql,
explain_nibble_sql => $explain_nibble_sql,
nibbleno => 0,
have_rows => 0,
rowno => 0,
};
}
else {
@@ -196,32 +192,45 @@ sub new {
$self = {
%args,
index => $index,
limit => $limit,
first_lb_sql => $first_lb_sql,
last_ub_sql => $last_ub_sql,
ub_sql => $ub_sql,
nibble_sql => $nibble_sql,
explain_nibble_sql => $explain_nibble_sql,
nibbleno => 0,
have_rows => 0,
rowno => 0,
index => $index,
limit => $limit,
first_lb_sql => $first_lb_sql,
last_ub_sql => $last_ub_sql,
ub_sql => $ub_sql,
nibble_sql => $nibble_sql,
explain_ub_sql => "EXPLAIN $ub_sql",
explain_nibble_sql => $explain_nibble_sql,
};
}
$self->{nibbleno} = 0;
$self->{have_rows} = 0;
$self->{rowno} = 0;
return bless $self, $class;
}
sub next {
my ($self) = @_;
my %callback_args = (
dbh => $self->{dbh},
tbl => $self->{tbl},
NibbleIterator => $self,
);
# First call, init everything. This could be done in new(), but
# all work is delayed until actually needed.
if ($self->{nibbleno} == 0) {
$self->_prepare_sths();
$self->_get_bounds();
if ( my $callback = $self->{callbacks}->{init} ) {
$callback->();
my $oktonibble = $callback->(%callback_args);
MKDEBUG && _d('init callback returned', $oktonibble);
if ( !$oktonibble ) {
$self->{no_more_boundaries} = 1;
return;
}
}
}
@@ -235,16 +244,7 @@ sub next {
MKDEBUG && _d($self->{nibble_sth}->{Statement}, 'params:',
join(', ', (@{$self->{lb}}, @{$self->{ub}})));
if ( my $callback = $self->{callbacks}->{exec_nibble} ) {
$self->{have_rows} = $callback->(
dbh => $self->{dbh},
tbl => $self->{tbl},
sth => $self->{nibble_sth},
lb => $self->{lb},
ub => $self->{ub},
nibbleno => $self->{nibbleno},
explain_sth => $self->{explain_sth},
NibbleIterator => $self,
);
$self->{have_rows} = $callback->(%callback_args);
}
else {
$self->{nibble_sth}->execute(@{$self->{lb}}, @{$self->{ub}});
@@ -268,13 +268,7 @@ sub next {
MKDEBUG && _d('No rows in nibble or nibble skipped');
if ( my $callback = $self->{callbacks}->{after_nibble} ) {
$callback->(
dbh => $self->{dbh},
tbl => $self->{tbl},
nibbleno => $self->{nibbleno},
explain_sth => $self->{explain_sth},
NibbleIterator => $self,
);
$callback->(%callback_args);
}
$self->{rowno} = 0;
$self->{have_rows} = 0;
@@ -282,11 +276,9 @@ sub next {
MKDEBUG && _d('Done nibbling');
if ( my $callback = $self->{callbacks}->{done} ) {
$callback->(
dbh => $self->{dbh},
tbl => $self->{tbl},
);
$callback->(%callback_args);
}
return;
}
@@ -300,9 +292,25 @@ sub nibble_index {
return $self->{index};
}
sub statements {
my ($self) = @_;
return {
nibble => $self->{nibble_sth},
explain_nibble => $self->{explain_nibble_sth},
upper_boundary => $self->{ub_sth},
explain_upper_boundary => $self->{explain_ub_sth},
}
}
sub boundaries {
my ($self) = @_;
return $self->{lb}, $self->{ub}, $self->{next_lb};
return {
first_lower => $self->{first_lb},
lower => $self->{lb},
next_lower => $self->{next_lb},
upper => $self->{ub},
last_upper => $self->{last_ub},
};
}
sub one_nibble {
@@ -312,6 +320,7 @@ sub one_nibble {
sub set_chunk_size {
my ($self, $limit) = @_;
return if $self->{one_nibble};
MKDEBUG && _d('Setting new chunk size (LIMIT):', $limit);
die "Chunk size must be > 0" unless $limit;
$self->{limit} = $limit - 1;
@@ -410,11 +419,14 @@ sub _can_nibble_once {
sub _prepare_sths {
my ($self) = @_;
MKDEBUG && _d('Preparing statement handles');
$self->{nibble_sth}
= $self->{dbh}->prepare($self->{nibble_sql});
$self->{explain_nibble_sth}
= $self->{dbh}->prepare($self->{explain_nibble_sql});
if ( !$self->{one_nibble} ) {
$self->{ub_sth} = $self->{dbh}->prepare($self->{ub_sql});
$self->{explain_ub_sth} = $self->{dbh}->prepare($self->{explain_ub_sql});
}
$self->{nibble_sth} = $self->{dbh}->prepare($self->{nibble_sql});
$self->{explain_sth} = $self->{dbh}->prepare($self->{explain_nibble_sql});
return;
}
@@ -422,7 +434,8 @@ sub _get_bounds {
my ($self) = @_;
return if $self->{one_nibble};
$self->{next_lb} = $self->{dbh}->selectrow_arrayref($self->{first_lb_sql});
$self->{first_lb} = $self->{dbh}->selectrow_arrayref($self->{first_lb_sql});
$self->{next_lb} = $self->{first_lb};
MKDEBUG && _d('First lower boundary:', Dumper($self->{next_lb}));
$self->{last_ub} = $self->{dbh}->selectrow_arrayref($self->{last_ub_sql});

View File

@@ -361,9 +361,12 @@ SKIP: {
callbacks => {
exec_nibble => sub {
my (%args) = @_;
my ($expl_sth, $lb, $ub) = @args{qw(explain_sth lb ub)};
$expl_sth->execute(@$lb, @$ub);
push @expl, $expl_sth->fetchrow_hashref();
my $nibble_iter = $args{NibbleIterator};
my $sth = $nibble_iter->statements();
my $boundary = $nibble_iter->boundaries();
$sth->{explain_nibble}->execute(
@{$boundary->{lower}}, @{$boundary->{upper}});
push @expl, $sth->{explain_nibble}->fetchrow_hashref();
return 0;
},
},
@@ -400,7 +403,7 @@ SKIP: {
},
],
'exec_nibble callbackup and explain_sth'
);
) or print STDERR Dumper(\@expl);
# #########################################################################
# film_actor, multi-column pk