Merge 'trunk' into 'DBIx-Class-current'
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Cursor.pm
CommitLineData
5cf243f6 1package DBIx::Class::Storage::DBI::Cursor;
28927b50 2
3use base qw/DBIx::Class::Cursor/;
4
5use strict;
6use warnings;
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) = @_;
28927b50 39 #use Data::Dumper; warn Dumper(@_);
cb5f2eea 40 $class = ref $class if ref $class;
28927b50 41 my $new = {
cb5f2eea 42 storage => $storage,
28927b50 43 args => $args,
44 pos => 0,
1346e22d 45 attrs => $attrs,
46 pid => $$,
47 };
48
49 $new->{tid} = threads->tid if $INC{'threads.pm'};
50
cb5f2eea 51 return bless ($new, $class);
28927b50 52}
53
5cf243f6 54=head2 next
55
21b5c39d 56=over 4
57
ebc77b53 58=item Arguments: none
21b5c39d 59
d601dc88 60=item Return Value: \@row_columns
21b5c39d 61
5cf243f6 62=back
63
21b5c39d 64Advances the cursor to the next row and returns an arrayref of column values.
5cf243f6 65
66=cut
67
28927b50 68sub next {
69 my ($self) = @_;
1346e22d 70
71 $self->_check_forks_threads;
cb5f2eea 72 if ($self->{attrs}{rows} && $self->{pos} >= $self->{attrs}{rows}) {
71e65b39 73 $self->{sth}->finish if $self->{sth}->{Active};
cb5f2eea 74 delete $self->{sth};
75 $self->{done} = 1;
76 }
77 return if $self->{done};
78 unless ($self->{sth}) {
79 $self->{sth} = ($self->{storage}->_select(@{$self->{args}}))[1];
5c91499f 80 if ($self->{attrs}{software_limit}) {
81 if (my $offset = $self->{attrs}{offset}) {
cb5f2eea 82 $self->{sth}->fetch for 1 .. $offset;
5c91499f 83 }
84 }
28927b50 85 }
cb5f2eea 86 my @row = $self->{sth}->fetchrow_array;
87 if (@row) {
88 $self->{pos}++;
89 } else {
90 delete $self->{sth};
91 $self->{done} = 1;
92 }
28927b50 93 return @row;
94}
95
5cf243f6 96=head2 all
97
21b5c39d 98=over 4
99
ebc77b53 100=item Arguments: none
21b5c39d 101
d601dc88 102=item Return Value: \@row_columns+
21b5c39d 103
5cf243f6 104=back
105
21b5c39d 106Returns a list of arrayrefs of column values for all rows in the
107L<DBIx::Class::ResultSet>.
5cf243f6 108
109=cut
110
1a14aa3f 111sub all {
112 my ($self) = @_;
1346e22d 113
114 $self->_check_forks_threads;
1a14aa3f 115 return $self->SUPER::all if $self->{attrs}{rows};
cb5f2eea 116 $self->{sth}->finish if $self->{sth}->{Active};
117 delete $self->{sth};
118 my ($rv, $sth) = $self->{storage}->_select(@{$self->{args}});
1a14aa3f 119 return @{$sth->fetchall_arrayref};
120}
121
5cf243f6 122=head2 reset
123
5cf243f6 124Resets the cursor to the beginning of the L<DBIx::Class::ResultSet>.
125
126=cut
127
28927b50 128sub reset {
129 my ($self) = @_;
1346e22d 130
131 $self->_check_forks_threads;
28927b50 132 $self->{sth}->finish if $self->{sth}->{Active};
1346e22d 133 $self->_soft_reset;
134}
135
136sub _soft_reset {
137 my ($self) = @_;
138
cb5f2eea 139 delete $self->{sth};
28927b50 140 $self->{pos} = 0;
cb5f2eea 141 delete $self->{done};
28927b50 142 return $self;
143}
144
1346e22d 145sub _check_forks_threads {
146 my ($self) = @_;
147
148 if($INC{'threads.pm'} && $self->{tid} != threads->tid) {
149 $self->_soft_reset;
150 $self->{tid} = threads->tid;
151 }
152
153 if($self->{pid} != $$) {
154 $self->_soft_reset;
155 $self->{pid} = $$;
156 }
157}
158
28927b50 159sub DESTROY {
160 my ($self) = @_;
1346e22d 161
162 $self->_check_forks_threads;
182fee36 163 $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active};
28927b50 164}
165
1661;