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