DBIx::Class::Storage::DBI::Cursor - Object representing a query cursor on a


DBIx-Class documentation Contained in the DBIx-Class distribution.

Index


Code Index:

NAME

Top

DBIx::Class::Storage::DBI::Cursor - Object representing a query cursor on a resultset.

SYNOPSIS

Top

  my $cursor = $schema->resultset('CD')->cursor();
  my $first_cd = $cursor->next;

DESCRIPTION

Top

A Cursor represents a query cursor on a DBIx::Class::ResultSet object. It allows for traversing the result set with next, retrieving all results with all and resetting the cursor with reset.

Usually, you would use the cursor methods built into DBIx::Class::ResultSet to traverse it. See next in DBIx::Class::ResultSet, reset in DBIx::Class::ResultSet and all in DBIx::Class::ResultSet for more information.

METHODS

Top

new

Returns a new DBIx::Class::Storage::DBI::Cursor object.

next

Arguments: none
Return Value: \@row_columns

Advances the cursor to the next row and returns an array of column values (the result of fetchrow_array in DBI method).

all

Arguments: none
Return Value: \@row_columns+

Returns a list of arrayrefs of column values for all rows in the DBIx::Class::ResultSet.

reset

Resets the cursor to the beginning of the DBIx::Class::ResultSet.


DBIx-Class documentation Contained in the DBIx-Class distribution.
package DBIx::Class::Storage::DBI::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 pos attrs _dbh_gen/
);

sub new {
  my ($class, $storage, $args, $attrs) = @_;
  $class = ref $class if ref $class;

  my $new = {
    storage => $storage,
    args => $args,
    pos => 0,
    attrs => $attrs,
    _dbh_gen => $storage->{_dbh_gen},
  };

  return bless ($new, $class);
}

sub _dbh_next {
  my ($storage, $dbh, $self) = @_;

  $self->_check_dbh_gen;
  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]);
    if ($self->{attrs}{software_limit}) {
      if (my $offset = $self->{attrs}{offset}) {
        $self->sth->fetch for 1 .. $offset;
      }
    }
  }
  my @row = $self->sth->fetchrow_array;
  if (@row) {
    $self->{pos}++;
  } else {
    $self->sth(undef);
    $self->{done} = 1;
  }
  return @row;
}

sub next {
  my ($self) = @_;
  $self->{storage}->dbh_do($self->can('_dbh_next'), $self);
}

sub _dbh_all {
  my ($storage, $dbh, $self) = @_;

  $self->_check_dbh_gen;
  $self->sth->finish if $self->sth && $self->sth->{Active};
  $self->sth(undef);
  my ($rv, $sth) = $storage->_select(@{$self->{args}});
  return @{$sth->fetchall_arrayref};
}

sub all {
  my ($self) = @_;
  if ($self->{attrs}{software_limit}
        && ($self->{attrs}{offset} || $self->{attrs}{rows})) {
    return $self->next::method;
  }

  $self->{storage}->dbh_do($self->can('_dbh_all'), $self);
}

sub reset {
  my ($self) = @_;

  # No need to care about failures here
  try { $self->sth->finish }
    if $self->sth && $self->sth->{Active};
  $self->_soft_reset;
  return undef;
}

sub _soft_reset {
  my ($self) = @_;

  $self->sth(undef);
  delete $self->{done};
  $self->{pos} = 0;
}

sub _check_dbh_gen {
  my ($self) = @_;

  if($self->{_dbh_gen} != $self->{storage}->{_dbh_gen}) {
    $self->{_dbh_gen} = $self->{storage}->{_dbh_gen};
    $self->_soft_reset;
  }
}

sub DESTROY {
  # None of the reasons this would die matter if we're in DESTROY anyways
  if (my $sth = $_[0]->sth) {
    try { $sth->finish } if $sth->FETCH('Active');
  }
}

1;