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 )