*** Iterator.pm.003 Mon Dec 20 19:50:06 2004 --- Iterator.pm Sat Jan 08 22:04:10 2005 *************** *** 13,18 **** --- 13,19 ---- _place => 0, _mapper => [], _data => [], + _next_cache_num => $them->next_cache_num || 1000, }, $me; } *************** *** 29,58 **** sub count { my $self = shift; ! unless (exists $self->{_count}) { my $sql = $self->sql; ! $sql =~ s/^\s*(SELECT)\s+(.+?)\s+(FROM)\s+/$1 COUNT(*) $3 /si; my $sth = $self->class->db_Main->prepare($sql); $sth->execute(@{$self->{_args}}); $self->{_count} = $sth->fetch->[0]; $sth->finish; ! } $self->{_count}; } sub next { my $self = shift; ! my $sql = $self->sql . sprintf ' LIMIT 1 OFFSET %d', $self->{_place}++; ! my $sth = $self->class->db_Main->prepare($sql); ! my %data; ! $sth->execute(@{$self->{_args}}); ! $sth->bind_columns(\(@data{ @{ $sth->{NAME_lc} } })); ! $sth->fetch; ! my $use = {%data}; ! $sth->finish; my @obj = ($self->class->construct($use)); foreach my $meth ($self->mapper) { @obj = map $_->$meth(), @obj; } --- 30,73 ---- sub count { my $self = shift; ! ! return $self->{_count} if(exists $self->{_count}); ! my $sql = $self->sql; ! ! if($sql =~ /\s+GROUP\s+BY\s+(\S+)\s+/i){ # CAUTION!! use sub-select ! my $col = $1; $col =~ s/\W//g; ! my $alias = $self->{_class}->table . '_group_by_' . $col; ! $sql = 'SELECT count(*) FROM (' . $sql . ') AS ' . $alias; ! } ! else{ ! $sql =~ s/^\s*SELECT\s+.+?\s+FROM\s+/SELECT COUNT(*) FROM /si; ! $sql =~ s/ORDER\s+BY(?:\s+[.\w]+(?:\s+(?:DESC|ASC)?\s*)?,?)+//i; ! } ! my $sth = $self->class->db_Main->prepare($sql); $sth->execute(@{$self->{_args}}); $self->{_count} = $sth->fetch->[0]; $sth->finish; ! $self->{_count}; } sub next { my $self = shift; + my $cache = $self->{_next_cache_num}; + my $index = $self->{_place}++ % $cache; ! unless($index){ ! my $pos = $self->{_place} - 1; ! my $end = $pos + $cache - 1; ! my $itr = $self->slice($pos, $end); ! @{$self->{_data}}[0 .. $cache - 1] = $itr->data; ! } + my $use = $self->{_data}[$index]; my @obj = ($self->class->construct($use)); + foreach my $meth ($self->mapper) { @obj = map $_->$meth(), @obj; } *************** *** 81,86 **** --- 96,105 ---- my $class = shift; my $pkg = caller(0); no strict 'refs'; + + $pkg->mk_classdata('plugin_iterator_off'); + $pkg->mk_classdata('next_cache_num'); + *{"$pkg\::sth_to_objects"} = sub { my ($class, $sth, $args) = @_; $class->_croak("sth_to_objects needs a statement handle") unless $sth; *************** *** 89,95 **** $sth = $class->$meth(); } ! if (defined wantarray and not wantarray and $sth->{Statement} !~ /\s LIMIT \s+\S+ (\s+(,\s*|OFFSET\s+)\S+)? \s*$/ix) { return Class::DBI::Plugin::Iterator->new($class, $sth, $args); } --- 108,114 ---- $sth = $class->$meth(); } ! if (!$class->plugin_iterator_off and defined wantarray and not wantarray and $sth->{Statement} !~ /\s LIMIT \s+\S+ (\s+(,\s*|OFFSET\s+)\S+)? \s*$/ix) { return Class::DBI::Plugin::Iterator->new($class, $sth, $args); } *************** *** 104,109 **** --- 123,133 ---- if $@; return $class->_ids_to_objects(\@rows); } + } + + sub next_cache_num { + $_[0]->{_next_cache_num} = $_[1] if($_[1] and $_[1] =~ /^\d+$/); + $_[0]->{_next_cache_num}; } =head1 NAME