Fey::Object::Iterator::FromSelect::Caching - A caching subclass of Fey::Object::Iterator::FromSelect


Fey-ORM documentation Contained in the Fey-ORM distribution.

Index


Code Index:

NAME

Top

Fey::Object::Iterator::FromSelect::Caching - A caching subclass of Fey::Object::Iterator::FromSelect

VERSION

Top

version 0.43

SYNOPSIS

Top

  use Fey::Object::Iterator::FromSelect::Caching;

  my $iter = Fey::Object::Iterator::FromSelect::Caching->new(
      classes     => 'MyApp::User',
      select      => $select,
      dbh         => $dbh,
      bind_params => \@bind,
  );

  print $iter->index();    # 0

  while ( my $user = $iter->next() ) {
      print $iter->index();    # 1, 2, 3, ...
      print $user->username();
  }

  # will return cached objects now
  $iter->reset();

DESCRIPTION

Top

This class implements a caching subclass of Fey::Object::Iterator::FromSelect::FromSelect. This means that it caches objects it creates internally. When $iterator->reset() is called it will re-use those objects before fetching more data from the DBMS.

METHODS

Top

This class provides the following methods:

$iterator->reset()

Resets the iterator so that the next call to $iterator->next() returns the first objects. Internally, this does not reset the DBI statement handle, it simply makes the iterator use cached objects.

$iterator->clone()

Clones the iterator while sharing its cached data with the original object. This is really intended for internal use, so use at your own risk.

ROLES

Top

This class does the Fey::ORM::Role::Iterator role.

AUTHOR

Top

Dave Rolsky <autarch@urth.org>

COPYRIGHT AND LICENSE

Top


Fey-ORM documentation Contained in the Fey-ORM distribution.

package Fey::Object::Iterator::FromSelect::Caching;
BEGIN {
  $Fey::Object::Iterator::FromSelect::Caching::VERSION = '0.43';
}

use strict;
use warnings;
use namespace::autoclean;

use Fey::ORM::Types qw( ArrayRef Bool );

use Moose;
use MooseX::SemiAffordanceAccessor;
use MooseX::StrictConstructor;

extends 'Fey::Object::Iterator::FromSelect';

has _cached_results => (
    traits   => ['Array'],
    is       => 'ro',
    isa      => ArrayRef[ArrayRef],
    lazy     => 1,
    default  => sub { [] },
    init_arg => undef,
    handles  => {
        _cache_result      => 'push',
        _get_cached_result => 'get',
    },

    # for cloning
    writer => '_set_cached_results',

    # for testability
    clearer => '_clear_cached_results',
);

has '_sth_is_exhausted' => (
    is       => 'rw',
    isa      => Bool,
    init_arg => undef,
);

override _get_next_result => sub {
    my $self = shift;

    my $result = $self->_get_cached_result( $self->index() );

    unless ($result) {
        # Some drivers (DBD::Pg, at least) will blow up if we try to
        # call a ->fetch type method on an exhausted statement
        # handle. DBD::SQLite can handle this, so it is not tested.
        return if $self->_sth_is_exhausted();

        $result = super();

        unless ($result) {
            $self->_set_sth_is_exhausted(1);
            return;
        }

        $self->_cache_result($result);
    }

    return $result;
};

sub reset {
    my $self = shift;

    $self->_reset_index();
}

sub clone {
    my $self = shift;

    my $clone = $self->meta()->clone_object($self);

    # It'd be nice to actually share the array reference between
    # multiple objects, but that causes problems because the sth may
    # not be shared (if it has not yet been created). That means that
    # the two sth's pull the same data twice and stuff it into the
    # same array reference, so the data ends up in there twice.
    $clone->_set_cached_results( [ @{ $self->_cached_results() } ] );

    $clone->_set_sth( $self->sth() )
        if $self->_has_sth();

    $clone->_set_sth_is_exhausted(1)
        if $self->_sth_is_exhausted();

    $clone->reset();

    return $clone;
}

__PACKAGE__->meta()->make_immutable();

1;

# ABSTRACT: A caching subclass of Fey::Object::Iterator::FromSelect




__END__