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