Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/Runtime/RowCursor.pm view on Meta::CPAN
package Alzabo::Runtime::RowCursor;
use strict;
use vars qw($VERSION);
use Alzabo::Exceptions;
use Alzabo::Runtime;
use Params::Validate qw( :all );
Params::Validate::validation_options( on_fail => sub { Alzabo::Exception::Params->throw( error => join '', @_ ) } );
use base qw( Alzabo::Runtime::Cursor );
$VERSION = 2.0;
use constant NEW_SPEC => { statement => { isa => 'Alzabo::DriverStatement' },
table => { isa => 'Alzabo::Runtime::Table' },
};
sub new
{
my $proto = shift;
my $class = ref $proto || $proto;
my %p = validate( @_, NEW_SPEC );
my $self = bless { %p,
count => 0,
}, $class;
return $self;
}
sub next
{
my $self = shift;
my $row;
# This loop is intended to allow the end caller to ignore rows
# that can't be created because they're not in the table.
#
# For example, imagine that query in the statement is looking at
# table 'foo' to get PK values for table 'bar'. If table 'foo'
# has a record indicating that there is a row in 'bar' where PK ==
# 1 but no such row actually exists then we want to skip this.
#
# If they really want to know we do save the exception.
until ( defined $row )
{
my @row = $self->{statement}->next;
last unless @row && grep { defined } @row;
my %hash;
my @pk = $self->{table}->primary_key;
@hash{ map { $_->name } @pk } = @row[0..$#pk];
my %prefetch;
if ( (my @pre = $self->{table}->prefetch) && @row > @pk )
{
@prefetch{@pre} = @row[$#pk + 1 .. $#row];
}
$row = $self->{table}->row_by_pk( @_,
pk => \%hash,
prefetch => \%prefetch,
%{ $self->{row_params} },
);
}
( run in 0.587 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )