Merge branch 'master' into topic/constructor_rewrite
[dbsrgits/DBIx-Class-Historic.git] / lib / DBIx / Class / Storage / DBI / Cursor.pm
index 5800113..a71036e 100644 (file)
@@ -1,10 +1,17 @@
 package DBIx::Class::Storage::DBI::Cursor;
 
-use base qw/DBIx::Class::Cursor/;
-
 use strict;
 use warnings;
 
+use base qw/DBIx::Class::Cursor/;
+
+use Try::Tiny;
+use namespace::clean;
+
+__PACKAGE__->mk_group_accessors('simple' =>
+    qw/sth storage args attrs/
+);
+
 =head1 NAME
 
 DBIx::Class::Storage::DBI::Cursor - Object representing a query cursor on a
@@ -13,7 +20,12 @@ resultset.
 =head1 SYNOPSIS
 
   my $cursor = $schema->resultset('CD')->cursor();
-  my $first_cd = $cursor->next;
+
+  # raw values off the database handle in resultset columns/select order
+  my @next_cd_column_values = $cursor->next;
+
+  # list of all raw values as arrayrefs
+  my @all_cds_column_values = $cursor->all;
 
 =head1 DESCRIPTION
 
@@ -41,40 +53,15 @@ sub new {
   my $new = {
     storage => $storage,
     args => $args,
-    pos => 0,
     attrs => $attrs,
     _dbh_gen => $storage->{_dbh_gen},
+    _pos => 0,
+    _done => 0,
   };
 
   return bless ($new, $class);
 }
 
-=head2 as_query
-
-=over 4
-
-=item Arguments: none
-
-=item Return Value: \[ $sql, @bind ]
-
-=back
-
-Returns the SQL statement and bind vars associated with the invocant.
-
-=cut
-
-sub as_query {
-  my $self = shift;
-
-  my $storage = $self->{storage};
-  my $sql_maker = $storage->sql_maker;
-  local $sql_maker->{for};
-
-  my @args = $storage->_select_args(@{$self->{args}});
-  my ($sql, $bind)  = $storage->_prep_for_execute(@args[0 .. 2], [@args[4 .. $#args]]);
-  return \[ "($sql)", @{ $bind || [] }];
-}
-
 =head2 next
 
 =over 4
@@ -94,26 +81,32 @@ sub _dbh_next {
   my ($storage, $dbh, $self) = @_;
 
   $self->_check_dbh_gen;
-  if ($self->{attrs}{rows} && $self->{pos} >= $self->{attrs}{rows}) {
-    $self->{sth}->finish if $self->{sth}->{Active};
-    delete $self->{sth};
-    $self->{done} = 1;
+  if (
+    $self->{attrs}{software_limit}
+      && $self->{attrs}{rows}
+        && $self->{_pos} >= $self->{attrs}{rows}
+  ) {
+    $self->sth->finish if $self->sth->{Active};
+    $self->sth(undef);
+    $self->{_done} = 1;
   }
-  return if $self->{done};
-  unless ($self->{sth}) {
-    $self->{sth} = ($storage->_select(@{$self->{args}}))[1];
+
+  return if $self->{_done};
+
+  unless ($self->sth) {
+    $self->sth(($storage->_select(@{$self->{args}}))[1]);
     if ($self->{attrs}{software_limit}) {
       if (my $offset = $self->{attrs}{offset}) {
-        $self->{sth}->fetch for 1 .. $offset;
+        $self->sth->fetch for 1 .. $offset;
       }
     }
   }
-  my @row = $self->{sth}->fetchrow_array;
+  my @row = $self->sth->fetchrow_array;
   if (@row) {
-    $self->{pos}++;
+    $self->{_pos}++;
   } else {
-    delete $self->{sth};
-    $self->{done} = 1;
+    $self->sth(undef);
+    $self->{_done} = 1;
   }
   return @row;
 }
@@ -142,8 +135,8 @@ sub _dbh_all {
   my ($storage, $dbh, $self) = @_;
 
   $self->_check_dbh_gen;
-  $self->{sth}->finish if $self->{sth}->{Active};
-  delete $self->{sth};
+  $self->sth->finish if $self->sth && $self->sth->{Active};
+  $self->sth(undef);
   my ($rv, $sth) = $storage->_select(@{$self->{args}});
   return @{$sth->fetchall_arrayref};
 }
@@ -154,6 +147,7 @@ sub all {
         && ($self->{attrs}{offset} || $self->{attrs}{rows})) {
     return $self->next::method;
   }
+
   $self->{storage}->dbh_do($self->can('_dbh_all'), $self);
 }
 
@@ -167,17 +161,18 @@ sub reset {
   my ($self) = @_;
 
   # No need to care about failures here
-  eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
+  try { $self->sth->finish }
+    if $self->sth && $self->sth->{Active};
   $self->_soft_reset;
+  return undef;
 }
 
 sub _soft_reset {
   my ($self) = @_;
 
-  delete $self->{sth};
-  delete $self->{done};
-  $self->{pos} = 0;
-  return $self;
+  $self->sth(undef);
+  $self->{_done} = 0;
+  $self->{_pos} = 0;
 }
 
 sub _check_dbh_gen {
@@ -190,11 +185,11 @@ sub _check_dbh_gen {
 }
 
 sub DESTROY {
-  my ($self) = @_;
-
   # None of the reasons this would die matter if we're in DESTROY anyways
-  local $@;
-  eval { $self->{sth}->finish if $self->{sth} && $self->{sth}->{Active} };
+  if (my $sth = $_[0]->sth) {
+    local $SIG{__WARN__} = sub {};
+    try { $sth->finish } if $sth->FETCH('Active');
+  }
 }
 
 1;