Couch-DB
view release on metacpan or search on metacpan
lib/Couch/DB/Result.pm view on Meta::CPAN
sub answer(%)
{ my ($self, %args) = @_;
return $self->{CDR_answer}
if defined $self->{CDR_answer};
$self->isReady
or error __x"document not ready: {err}", err => $self->message;
$self->{CDR_answer} = $self->couch->_extractAnswer($self->response);
}
sub values(@)
{ my $self = shift;
return $self->{CDR_values} if exists $self->{CDR_values};
my $values = $self->answer;
$values = $_->($self, $values) for reverse @{$self->{CDR_on_values}};
$self->{CDR_values} = $values;
}
#--------------------
sub rows(;$) { @{$_[0]->rowsRef($_[1])} }
sub rowsRef(;$)
{ my ($self, $qnr) = @_;
! $self->inPagingMode
or panic "Call used in paging mode, so use the page* methods.";
$self->_rowsRef($qnr // 0);
}
sub _rowsRef($)
{ my ($self, $qnr) = @_;
my $rows = $self->{CDR_rows}[$qnr] ||= [];
return $rows if $self->{CDR_rows_complete}[$qnr];
for(my $rownr = 1; $self->row($rownr, $qnr); $rownr++) { }
$self->{CDR_rows_complete}[$qnr] = 1;
$rows;
}
sub row($;$)
{ my ($self, $rownr, $qnr) = @_;
my $rows = $self->{CDR_rows}[$qnr //= 0] ||= [];
my $index = $rownr -1;
return $rows->[$index] if exists $rows->[$index];
my %data = map $_->($self, $rownr-1, column => $qnr), reverse @{$self->{CDR_on_row}};
keys %data or return ();
my $doc;
my $dp = delete $data{docparams} || {};
if(my $dd = delete $data{docdata})
{ $doc = Couch::DB::Document->fromResult($self, $dd, %$dp);
}
elsif($dd = delete $data{ddocdata})
{ $doc = Couch::DB::Design->fromResult($self, $dd, %$dp);
}
my $row = Couch::DB::Row->new(%data, result => $self, rownr => $rownr, doc => $doc);
$doc->row($row) if $doc;
$rows->[$index] = $row; # Remember partial result for rows()
}
sub numberOfRows(;$) { scalar @{$_[0]->rowsRef($_[1])} }
sub docs(;$) { map $_->doc, $_[0]->rows($_[1]) }
sub docsRef(;$) { [ map $_->doc, $_[0]->rows($_[1]) ] }
sub doc($;$)
{ my ($self, $rownr, $qnr) = @_;
my $r = $self->row($rownr, $qnr);
defined $r ? $r->doc : undef;
}
#--------------------
sub pagingState(%)
{ my ($self, %args) = @_;
my $next = $self->nextPageSettings;
$next->{harvester} = defined $next->{harvester} ? 'CODE' : 'DEFAULT';
$next->{map} = defined $next->{map} ? 'CODE' : 'NONE';
$next->{client} = $self->client->name;
if(my $maxbook = delete $args{max_bookmarks} // 10)
{ my $bookmarks = $next->{bookmarks};
$next->{bookmarks} = +{ (%$bookmarks)[0..(2*$maxbook-1)] } if keys %$bookmarks > $maxbook;
}
$next;
}
sub supportsPaging() { defined $_[0]->{CDR_page} }
sub inPagingMode() { my $r = $_[0]->{CDR_page}; $r && $r->{page_mode} }
# The next is used r/w when succeed is a result object, and when results
# have arrived.
sub _thisPage() { $_[0]->{CDR_page} or panic "Call does not support paging." }
sub nextPageSettings()
{ my $self = shift;
my %next = %{$self->_thisPage};
delete $next{harvested};
$next{start} += (delete $next{skip}) + @{$self->_rowsRef(0)};
$next{pagenr}++;
( run in 1.241 second using v1.01-cache-2.11-cpan-39bf76dae61 )