File Coverage

blib/lib/Fey/Object/Iterator/FromSelect/Caching.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Fey::Object::Iterator::FromSelect::Caching;
2             {
3             $Fey::Object::Iterator::FromSelect::Caching::VERSION = '0.46';
4             }
5              
6 1     1   26975 use strict;
  1         3  
  1         40  
7 1     1   4 use warnings;
  1         2  
  1         28  
8 1     1   922 use namespace::autoclean;
  1         22016  
  1         6  
9              
10 1     1   661 use Fey::ORM::Types qw( ArrayRef Bool );
  0            
  0            
11              
12             use Moose;
13             use MooseX::SemiAffordanceAccessor;
14             use MooseX::StrictConstructor;
15              
16             extends 'Fey::Object::Iterator::FromSelect';
17              
18             has _cached_results => (
19             traits => ['Array'],
20             is => 'ro',
21             isa => ArrayRef[ArrayRef],
22             lazy => 1,
23             default => sub { [] },
24             init_arg => undef,
25             handles => {
26             _cache_result => 'push',
27             _get_cached_result => 'get',
28             },
29              
30             # for cloning
31             writer => '_set_cached_results',
32              
33             # for testability
34             clearer => '_clear_cached_results',
35             );
36              
37             has '_sth_is_exhausted' => (
38             is => 'rw',
39             isa => Bool,
40             init_arg => undef,
41             );
42              
43             override _get_next_result => sub {
44             my $self = shift;
45              
46             my $result = $self->_get_cached_result( $self->index() );
47              
48             unless ($result) {
49             # Some drivers (DBD::Pg, at least) will blow up if we try to
50             # call a ->fetch type method on an exhausted statement
51             # handle. DBD::SQLite can handle this, so it is not tested.
52             return if $self->_sth_is_exhausted();
53              
54             $result = super();
55              
56             unless ($result) {
57             $self->_set_sth_is_exhausted(1);
58             return;
59             }
60              
61             $self->_cache_result($result);
62             }
63              
64             return $result;
65             };
66              
67             sub reset {
68             my $self = shift;
69              
70             $self->_reset_index();
71             }
72              
73             sub clone {
74             my $self = shift;
75              
76             my $clone = $self->meta()->clone_object($self);
77              
78             # It'd be nice to actually share the array reference between
79             # multiple objects, but that causes problems because the sth may
80             # not be shared (if it has not yet been created). That means that
81             # the two sth's pull the same data twice and stuff it into the
82             # same array reference, so the data ends up in there twice.
83             $clone->_set_cached_results( [ @{ $self->_cached_results() } ] );
84              
85             $clone->_set_sth( $self->sth() )
86             if $self->_has_sth();
87              
88             $clone->_set_sth_is_exhausted(1)
89             if $self->_sth_is_exhausted();
90              
91             $clone->reset();
92              
93             return $clone;
94             }
95              
96             __PACKAGE__->meta()->make_immutable();
97              
98             1;
99              
100             # ABSTRACT: A caching subclass of Fey::Object::Iterator::FromSelect
101              
102             __END__
103              
104             =pod
105              
106             =head1 NAME
107              
108             Fey::Object::Iterator::FromSelect::Caching - A caching subclass of Fey::Object::Iterator::FromSelect
109              
110             =head1 VERSION
111              
112             version 0.46
113              
114             =head1 SYNOPSIS
115              
116             use Fey::Object::Iterator::FromSelect::Caching;
117              
118             my $iter = Fey::Object::Iterator::FromSelect::Caching->new(
119             classes => 'MyApp::User',
120             select => $select,
121             dbh => $dbh,
122             bind_params => \@bind,
123             );
124              
125             print $iter->index(); # 0
126              
127             while ( my $user = $iter->next() ) {
128             print $iter->index(); # 1, 2, 3, ...
129             print $user->username();
130             }
131              
132             # will return cached objects now
133             $iter->reset();
134              
135             =head1 DESCRIPTION
136              
137             This class implements a caching subclass of
138             L<Fey::Object::Iterator::FromSelect>. This means that it caches
139             objects it creates internally. When C<< $iterator->reset() >> is
140             called it will re-use those objects before fetching more data from the
141             DBMS.
142              
143             =head1 METHODS
144              
145             This class provides the following methods:
146              
147             =head2 $iterator->reset()
148              
149             Resets the iterator so that the next call to C<< $iterator->next() >>
150             returns the first objects. Internally, this I<does not> reset the
151             L<DBI> statement handle, it simply makes the iterator use cached
152             objects.
153              
154             =head2 $iterator->clone()
155              
156             Clones the iterator while sharing its cached data with the original
157             object. This is really intended for internal use, so I<use at your own
158             risk>.
159              
160             =head1 ROLES
161              
162             This class does the L<Fey::ORM::Role::Iterator> role.
163              
164             =head1 AUTHOR
165              
166             Dave Rolsky <autarch@urth.org>
167              
168             =head1 COPYRIGHT AND LICENSE
169              
170             This software is copyright (c) 2011 by Dave Rolsky.
171              
172             This is free software; you can redistribute it and/or modify it under
173             the same terms as the Perl 5 programming language system itself.
174              
175             =cut