The real fix
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Cursor.pm
CommitLineData
5cf243f6 1package DBIx::Class::Storage::DBI::Cursor;
28927b50 2
28927b50 3use strict;
4use warnings;
5
2ad62d97 6use base qw/DBIx::Class::Cursor/;
7
5cf243f6 8=head1 NAME
9
10DBIx::Class::Storage::DBI::Cursor - Object representing a query cursor on a
11resultset.
12
13=head1 SYNOPSIS
14
15 my $cursor = $schema->resultset('CD')->cursor();
16 my $first_cd = $cursor->next;
17
18=head1 DESCRIPTION
19
20A Cursor represents a query cursor on a L<DBIx::Class::ResultSet> object. It
21allows for traversing the result set with L</next>, retrieving all results with
22L</all> and resetting the cursor with L</reset>.
23
24Usually, you would use the cursor methods built into L<DBIx::Class::ResultSet>
25to traverse it. See L<DBIx::Class::ResultSet/next>,
26L<DBIx::Class::ResultSet/reset> and L<DBIx::Class::ResultSet/all> for more
27information.
28
29=head1 METHODS
30
31=head2 new
32
5cf243f6 33Returns a new L<DBIx::Class::Storage::DBI::Cursor> object.
34
35=cut
36
28927b50 37sub new {
cb5f2eea 38 my ($class, $storage, $args, $attrs) = @_;
cb5f2eea 39 $class = ref $class if ref $class;
2007929b 40
28927b50 41 my $new = {
cb5f2eea 42 storage => $storage,
28927b50 43 args => $args,
44 pos => 0,
1346e22d 45 attrs => $attrs,
dbaee748 46 _dbh_gen => $storage->{_dbh_gen},
1346e22d 47 };
48
cb5f2eea 49 return bless ($new, $class);
28927b50 50}
51
5cf243f6 52=head2 next
53
21b5c39d 54=over 4
55
ebc77b53 56=item Arguments: none
21b5c39d 57
d601dc88 58=item Return Value: \@row_columns
21b5c39d 59
5cf243f6 60=back
61
685dad64 62Advances the cursor to the next row and returns an array of column
63values (the result of L<DBI/fetchrow_array> method).
5cf243f6 64
65=cut
66
dbaee748 67sub _dbh_next {
68 my ($storage, $dbh, $self) = @_;
1346e22d 69
dbaee748 70 $self->_check_dbh_gen;
22ed9526 71 if (
72 $self->{attrs}{software_limit}
73 && $self->{attrs}{rows}
74 && $self->{pos} >= $self->{attrs}{rows}
75 ) {
71e65b39 76 $self->{sth}->finish if $self->{sth}->{Active};
cb5f2eea 77 delete $self->{sth};
78 $self->{done} = 1;
79 }
80 return if $self->{done};
81 unless ($self->{sth}) {
dbaee748 82 $self->{sth} = ($storage->_select(@{$self->{args}}))[1];
5c91499f 83 if ($self->{attrs}{software_limit}) {
84 if (my $offset = $self->{attrs}{offset}) {
cb5f2eea 85 $self->{sth}->fetch for 1 .. $offset;
5c91499f 86 }
87 }
28927b50 88 }
cb5f2eea 89 my @row = $self->{sth}->fetchrow_array;
90 if (@row) {
91 $self->{pos}++;
92 } else {
93 delete $self->{sth};
94 $self->{done} = 1;
95 }
28927b50 96 return @row;
97}
98
dbaee748 99sub next {
100 my ($self) = @_;
101 $self->{storage}->dbh_do($self->can('_dbh_next'), $self);
102}
103
5cf243f6 104=head2 all
105
21b5c39d 106=over 4
107
ebc77b53 108=item Arguments: none
21b5c39d 109
d601dc88 110=item Return Value: \@row_columns+
21b5c39d 111
5cf243f6 112=back
113
21b5c39d 114Returns a list of arrayrefs of column values for all rows in the
115L<DBIx::Class::ResultSet>.
5cf243f6 116
117=cut
118
dbaee748 119sub _dbh_all {
120 my ($storage, $dbh, $self) = @_;
1346e22d 121
dbaee748 122 $self->_check_dbh_gen;
cb5f2eea 123 $self->{sth}->finish if $self->{sth}->{Active};
124 delete $self->{sth};
dbaee748 125 my ($rv, $sth) = $storage->_select(@{$self->{args}});
1a14aa3f 126 return @{$sth->fetchall_arrayref};
127}
128
dbaee748 129sub all {
130 my ($self) = @_;
6296f45b 131 if ($self->{attrs}{software_limit}
132 && ($self->{attrs}{offset} || $self->{attrs}{rows})) {
c3515436 133 return $self->next::method;
6296f45b 134 }
22ed9526 135
dbaee748 136 $self->{storage}->dbh_do($self->can('_dbh_all'), $self);
137}
138
5cf243f6 139=head2 reset
140
5cf243f6 141Resets the cursor to the beginning of the L<DBIx::Class::ResultSet>.
142
143=cut
144
28927b50 145sub reset {
146 my ($self) = @_;
1346e22d 147
dbaee748 148 # No need to care about failures here
149 eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
1346e22d 150 $self->_soft_reset;
b7c79955 151 return undef;
1346e22d 152}
153
154sub _soft_reset {
155 my ($self) = @_;
156
cb5f2eea 157 delete $self->{sth};
cb5f2eea 158 delete $self->{done};
dbaee748 159 $self->{pos} = 0;
28927b50 160}
161
dbaee748 162sub _check_dbh_gen {
1346e22d 163 my ($self) = @_;
164
dbaee748 165 if($self->{_dbh_gen} != $self->{storage}->{_dbh_gen}) {
166 $self->{_dbh_gen} = $self->{storage}->{_dbh_gen};
167 $self->_soft_reset;
1346e22d 168 }
169}
170
28927b50 171sub DESTROY {
172 my ($self) = @_;
1346e22d 173
dbaee748 174 # None of the reasons this would die matter if we're in DESTROY anyways
19fb8520 175 local $@;
dbaee748 176 eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
28927b50 177}
178
1791;