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