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 | |
5cf243f6 |
33 | Returns a new L<DBIx::Class::Storage::DBI::Cursor> object. |
34 | |
35 | =cut |
36 | |
28927b50 |
37 | sub 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, |
dbaee748 |
46 | _dbh_gen => $storage->{_dbh_gen}, |
1346e22d |
47 | }; |
48 | |
cb5f2eea |
49 | return bless ($new, $class); |
28927b50 |
50 | } |
51 | |
59af6677 |
52 | =head2 as_query |
53 | |
658fa250 |
54 | =over 4 |
55 | |
0f6fc705 |
56 | =item Arguments: See L<DBIx::Class::ResultSet/as_query> |
658fa250 |
57 | |
4dc99a01 |
58 | =item Return Value: \[ $sql, @bind ] |
658fa250 |
59 | |
60 | =back |
61 | |
59af6677 |
62 | Returns the SQL statement and bind vars associated with the invocant. |
63 | |
64 | =cut |
65 | |
66 | sub as_query { |
0f6fc705 |
67 | my ( $self, $opts ) = @_; |
68 | |
69 | $self->throw_exception( "as_query needs a hashref" ) |
70 | if defined $opts and ref $opts ne 'HASH'; |
71 | |
72 | $opts->{skip_parens} ||= 0; |
59af6677 |
73 | |
74 | my $storage = $self->{storage}; |
75 | my $sql_maker = $storage->sql_maker; |
76 | local $sql_maker->{for}; |
77 | |
78 | my @args = $storage->_select_args(@{$self->{args}}); |
79 | my ($sql, $bind) = $storage->_prep_for_execute(@args[0 .. 2], [@args[4 .. $#args]]); |
0f6fc705 |
80 | $sql = "($sql)" unless $opts->{skip_parens}; |
81 | return \[ $sql, @$bind ]; |
59af6677 |
82 | } |
83 | |
5cf243f6 |
84 | =head2 next |
85 | |
21b5c39d |
86 | =over 4 |
87 | |
ebc77b53 |
88 | =item Arguments: none |
21b5c39d |
89 | |
d601dc88 |
90 | =item Return Value: \@row_columns |
21b5c39d |
91 | |
5cf243f6 |
92 | =back |
93 | |
685dad64 |
94 | Advances the cursor to the next row and returns an array of column |
95 | values (the result of L<DBI/fetchrow_array> method). |
5cf243f6 |
96 | |
97 | =cut |
98 | |
dbaee748 |
99 | sub _dbh_next { |
100 | my ($storage, $dbh, $self) = @_; |
1346e22d |
101 | |
dbaee748 |
102 | $self->_check_dbh_gen; |
cb5f2eea |
103 | if ($self->{attrs}{rows} && $self->{pos} >= $self->{attrs}{rows}) { |
71e65b39 |
104 | $self->{sth}->finish if $self->{sth}->{Active}; |
cb5f2eea |
105 | delete $self->{sth}; |
106 | $self->{done} = 1; |
107 | } |
108 | return if $self->{done}; |
109 | unless ($self->{sth}) { |
dbaee748 |
110 | $self->{sth} = ($storage->_select(@{$self->{args}}))[1]; |
5c91499f |
111 | if ($self->{attrs}{software_limit}) { |
112 | if (my $offset = $self->{attrs}{offset}) { |
cb5f2eea |
113 | $self->{sth}->fetch for 1 .. $offset; |
5c91499f |
114 | } |
115 | } |
28927b50 |
116 | } |
cb5f2eea |
117 | my @row = $self->{sth}->fetchrow_array; |
118 | if (@row) { |
119 | $self->{pos}++; |
120 | } else { |
121 | delete $self->{sth}; |
122 | $self->{done} = 1; |
123 | } |
28927b50 |
124 | return @row; |
125 | } |
126 | |
dbaee748 |
127 | sub next { |
128 | my ($self) = @_; |
129 | $self->{storage}->dbh_do($self->can('_dbh_next'), $self); |
130 | } |
131 | |
5cf243f6 |
132 | =head2 all |
133 | |
21b5c39d |
134 | =over 4 |
135 | |
ebc77b53 |
136 | =item Arguments: none |
21b5c39d |
137 | |
d601dc88 |
138 | =item Return Value: \@row_columns+ |
21b5c39d |
139 | |
5cf243f6 |
140 | =back |
141 | |
21b5c39d |
142 | Returns a list of arrayrefs of column values for all rows in the |
143 | L<DBIx::Class::ResultSet>. |
5cf243f6 |
144 | |
145 | =cut |
146 | |
dbaee748 |
147 | sub _dbh_all { |
148 | my ($storage, $dbh, $self) = @_; |
1346e22d |
149 | |
dbaee748 |
150 | $self->_check_dbh_gen; |
cb5f2eea |
151 | $self->{sth}->finish if $self->{sth}->{Active}; |
152 | delete $self->{sth}; |
dbaee748 |
153 | my ($rv, $sth) = $storage->_select(@{$self->{args}}); |
1a14aa3f |
154 | return @{$sth->fetchall_arrayref}; |
155 | } |
156 | |
dbaee748 |
157 | sub all { |
158 | my ($self) = @_; |
6296f45b |
159 | if ($self->{attrs}{software_limit} |
160 | && ($self->{attrs}{offset} || $self->{attrs}{rows})) { |
161 | return $self->SUPER::all; |
162 | } |
dbaee748 |
163 | $self->{storage}->dbh_do($self->can('_dbh_all'), $self); |
164 | } |
165 | |
5cf243f6 |
166 | =head2 reset |
167 | |
5cf243f6 |
168 | Resets the cursor to the beginning of the L<DBIx::Class::ResultSet>. |
169 | |
170 | =cut |
171 | |
28927b50 |
172 | sub reset { |
173 | my ($self) = @_; |
1346e22d |
174 | |
dbaee748 |
175 | # No need to care about failures here |
176 | eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} }; |
1346e22d |
177 | $self->_soft_reset; |
178 | } |
179 | |
180 | sub _soft_reset { |
181 | my ($self) = @_; |
182 | |
cb5f2eea |
183 | delete $self->{sth}; |
cb5f2eea |
184 | delete $self->{done}; |
dbaee748 |
185 | $self->{pos} = 0; |
28927b50 |
186 | return $self; |
187 | } |
188 | |
dbaee748 |
189 | sub _check_dbh_gen { |
1346e22d |
190 | my ($self) = @_; |
191 | |
dbaee748 |
192 | if($self->{_dbh_gen} != $self->{storage}->{_dbh_gen}) { |
193 | $self->{_dbh_gen} = $self->{storage}->{_dbh_gen}; |
194 | $self->_soft_reset; |
1346e22d |
195 | } |
196 | } |
197 | |
28927b50 |
198 | sub DESTROY { |
199 | my ($self) = @_; |
1346e22d |
200 | |
dbaee748 |
201 | # None of the reasons this would die matter if we're in DESTROY anyways |
19fb8520 |
202 | local $@; |
dbaee748 |
203 | eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} }; |
28927b50 |
204 | } |
205 | |
206 | 1; |