Couch-DB/lib/Couch/DB/Result.pod
=encoding utf8
=head1 NAME
Couch::DB::Result - the reply of a CouchDB server call
=head1 SYNOPSIS
# Any call to the CouchDB server result in this object.
# But call() is for internal library use: avoid!
my $result = $couch->call($method, $path, %call_options);
if($result->isReady) { ... }
if($result) { ... } # same
$result or die;
my $data = $result->answer; # raw JSON response
my $val = $result->values; # interpreted response
# It's not always needed to inspect the document
if($result->{ok}) { ... }
=head1 DESCRIPTION
The result of a call has many faces: it can be a usage error, a server
issue, empty, paged, or even delayed. This Result object is able to
handle them all. B<Read the DETAILS chapter below, to understand them all.>
This result objects are pretty heavy: it collects request, response, and much
more. So: let them run out-of-scope once you have collected your C<values()>.
=head1 OVERLOADED
=over 4
=item overload: B<bool>
These Return objects are overloaded to return a false value when there is
any error. For delayed collection of data, this status may change after
this object is initially created.
=back
=head1 METHODS
=head2 Constructors
=over 4
=item Couch::DB::Result-E<gt>B<new>(%options)
For details on the C<on_*> event handlers, see L<Couch::DB/DETAILS>.
-Option --Default
couch <required>
on_chain [ ]
on_error [ ]
on_final [ ]
on_row [ ]
on_values [ ]
paging undef
=over 2
=item couch => L<Couch::DB|Couch::DB>-object
=item on_chain => CODE|ARRAY
When a request was completed, a new request can be made immediately. This
is especially usefull in combination with C<_delay>, and with internal
logic.
=item on_error => CODE|ARRAY
Called each time when the result CODE changes to be "not a success".
=item on_final => CODE|ARRAY
Called when the Result object has either an error or an success.
=item on_row => CODE|ARRAY
Produces a single L<Couch::DB::Row|Couch::DB::Row>-object when L<page()|Couch::DB::Result/"Paging through results"> is used.
=item on_values => CODE|ARRAY
Provide a sub which translates incoming JSON data from the server, into
pure perl.
=item paging => HASH
When a call support paging, internal information about it is passed in
this HASH.
=back
=back
=head2 Accessors
Generic accessors, not related to the Result content.
=over 4
=item $obj-E<gt>B<code>()
Returns an HTTP status code (please use HTTP::Status), which reflects
the condition of the answer.
=item $obj-E<gt>B<codeName>( [$code] )
Return a string which represents the code. For instance, code 200 will
produce string "HTTP_OK".
See CouchDB API section 1.1.4: "HTTP Status Codes" for the interpretation
of the codes.
=item $obj-E<gt>B<couch>()
=item $obj-E<gt>B<isDelayed>()
=item $obj-E<gt>B<isReady>()
=item $obj-E<gt>B<message>()
Returns C<undef>, or a message (string) which explains why the status
is as it is.
=item $obj-E<gt>B<seqnr>()
Returns the (process space) unique result object number. This may help
debugging and tracing.
=item $obj-E<gt>B<setStatus>($code, $message)
Set the $code and $message to something else. Your program should
probably not do this: it's the library which determines how the result
needs to be interpreted.
=item $obj-E<gt>B<short>()
Returns a string which contains some crucial information about this
result, which could help with debugging.
=back
=head2 When the document is collected
=over 4
=item $obj-E<gt>B<answer>(%options)
When the response was received, this returns the received json answer
as HASH of raw data: the bare result of the request.
You can better use the L<values()|Couch::DB::Result/"When the document is collected"> method, which returns the data in a far more
Perlish way: as Perl booleans, DateTime objects, and so on.
=item $obj-E<gt>B<client>()
Which client L<Couch::DB::Client|Couch::DB::Client> was used in the last action. Initially,
none. When the results are ready, the client is known.
=item $obj-E<gt>B<request>()
Returns the request (framework specific) object which was used to collect
the data.
=item $obj-E<gt>B<response>()
When the call was completed, this will return the (framework specific) object
which contains the response received.
=item $obj-E<gt>B<values>()
Each CouchDB API call knows whether it passes data types which are
(potentially) incompatible between JSON and Perl. Those types get
converted for you for convenience in your main program.
The raw data is returned with L<answer()|Couch::DB::Result/"When the document is collected">. See L</DETAILS> below.
=back
=head2 Results containing rows
When a result (potentially) contains multiple rows, then paging is supported.
But you may also wish to access the rows directly.
=over 4
=item $obj-E<gt>B<doc>( $nr, [$qnr] )
Returns the document of the indicated row. The counter is the row counter,
so starts at one.
=item $obj-E<gt>B<docs>( [$qnr] )
Return only the document information which is kept in the rows. Some
rows may contain more search information.
Returns a LIST of L<Couch::DB::Document|Couch::DB::Document>-objects.
=item $obj-E<gt>B<docsRef>( [$qnr] )
Returns a reference to the documents.
=item $obj-E<gt>B<numberOfRows>( [$qnr] )
=item $obj-E<gt>B<row>( $rownr, [$qnr] )
Returns a L<Couch::DB::Row|Couch::DB::Row> object (or an empty LIST) which represents one
row in a paging answer. Row numbers start on 1.
=item $obj-E<gt>B<rows>( [$qnr] )
Some CouchDB calls can be used with paging. In that case, the answer will
show something which reflects rows. This method wraps the values in the
rows into L<Couch::DB::Row|Couch::DB::Row>-objects.
(At least with) L<Couch::DB::Database::find()|Couch::DB::Database/"Handling documents"> you can supply multiple
queries at the same time. They will all use the same paging, usually C<_all>
records at once. In this case, you must specify the query sequence number
(starts with zero)
=item $obj-E<gt>B<rowsRef>( [$qnr] )
Returns a reference to the returned rows.
=back
=head2 Paging through results
Only when this result is produced by a call in "paging mode" (uses the C<all> or
C<page_size> parameters), then the follow C<page*> methods are available to get
the data. Otherwise, use the C<row*> and C<doc*> methods.
=over 4
=item $obj-E<gt>B<inPagingMode>()
Returns true when this call may be chained with other calls to come up to
a number of rows which match the number you desire. True when either
call parameter C<all> is true, or a C<page_size> is given.
=item $obj-E<gt>B<isLastPage>()
Returns a true value when there are no more page elements to be expected. The
L<page()|Couch::DB::Result/"Paging through results"> may already be empty.
=item $obj-E<gt>B<nextPageSettings>()
Returns the details for the next page to be collected. When you need these
details to be saved outside the program, than use L<pagingState()|Couch::DB::Result/"Paging through results">.
=item $obj-E<gt>B<page>()
Returns an ARRAY with the elements collected (harvested) for this page.
When there are less elements than the requested page size, then there
are no more elements as result of the search.
Method L<pageRows()|Couch::DB::Result/"Paging through results"> will return the rows as a LIST.
example: compare page and pageRows
my $r = $db->find(...);
foreach my $row ($r->pageRows) { ... }
foreach my $row ( @{$r->page} ) { ... }
print template($t, rows => [ $r->pageRows ]);
print template($t, rows => $r->page);
=item $obj-E<gt>B<pageDoc>($rownr)
Returns the document (L<Couch::DB::Document|Couch::DB::Document> object) on the indicated row
in the page (starts at 1).
=item $obj-E<gt>B<pageDocs>()
Returns the LIST of documents (L<Couch::DB::Document|Couch::DB::Document> objects), which are
contained in the rows.
example: of pageDocs()
my $r1 = $couch->find(...);
my @docs1 = map $_->doc, $r1->page;
my $r2 = $couch->find(..., _harvester => sub { $_[0]->docs });
my @docs2 = $r2->page;
my $r3 = $couch->find(...);
my @docs3 = $r3->pageDocs;
=item $obj-E<gt>B<pageIsPartial>()
Returns a true value when there should be made another attempt to fill the
page upto the the requested page size.
=item $obj-E<gt>B<pageNumber>()
When in paging mode, pages all have the same size. Otherwise, this will count
the number of calls made with variable number of rows.
=item $obj-E<gt>B<pageRows>()
Returns the LIST of rows (L<Couch::DB::Row|Couch::DB::Row> objects), where L<page()|Couch::DB::Result/"Paging through results"> returns it
as ARRAY (reference).
=item $obj-E<gt>B<pagingState>(%options)
Returns information about the logical next page for this response, in a format
which can be saved into a session.
-Option --Default
max_bookmarks 10
=over 2
=item max_bookmarks => INTEGER
When you save this paging information into a session cookie, you should not
store many bookmarks, because they are pretty large and do not compress. Random
bookmarks are thrown away. Set to '0' to disable this restriction.
=back
=item $obj-E<gt>B<supportsPaging>()
[0.100] Returns whether the result supports paging. Still, you may not use
this in paging mode.
=back
=head2 When the collecting is delayed
=over 4
=item $obj-E<gt>B<delayPlan>()
Returns the (framework specific) information about actions to be taken to
collect the document.
=item $obj-E<gt>B<setFinalResult>(\%data, %options)
Fill this Result object with the actual results.
=item $obj-E<gt>B<setResultDelayed>($plan, %options)
When defined, the result document is not yet collected. The C<$plan> contains
framework specific information how to realize that in a later stage.
=back
=head1 DETAILS
This Result objects have many faces. Understand them well, before you start
programming with L<Couch::DB|Couch::DB>.
=head2 Result is an error
The Result object is overloaded to produce a false value when the command did
not succeed for any reason.
B<. Example: without error handler>
my $result = $db->find(...)
or die $result->message;
B<. Example: with error handler>
my $result = $db->find(..., on_error => sub { die } );
=head2 Delay the result
When your website has only the slightest chance on having users, then
you need to use single server processes shared by many website users.
Couch::DB implementations will use event-driven programming to make this
possible, but your own program should be configured to make use of this
to benefit.
Usually, questions to the database are purely serial. This is an easy
case to handle, and totally hidden for you, as user of this module.
For instance, when you want to query in parallel, you need to prepare
multiple queries, and then start them at the same time.
B<. Example: prepare a query, delayed>
my $find1 = $db->find(..., _delay => 1)
or die $result->message; # only preparation errors
if($find1->isDelayed) ...; # true
my $result = $find1->run
or die $result->message; # network/server errors
# TODO
my $result = $couch->parallel([$find1, $find2], concurrent => 2);
=head2 Understanding values
To bridge the gap between your program and JSON data received, Couch::DB
provides templated conversions. This conversion scheme also attempts to
hide protocol changes between CouchDB server versions.
my $result = $couch->client('local')->serverInfo;
result or die;
# Try to avoid this:
print $result->answer->{version}; # string
# Use this instead:
print $result->values->{version}; # version object
In some cases, data is added or modified for convenience: to make it
compatible with the version your program has been written for. See
L<Couch::DB::new(api)|Couch::DB/"Constructors">.
=head1 SEE ALSO
This module is part of Couch-DB distribution version 0.200,
built on June 18, 2025. Website: F<http://perl.overmeer.net/CPAN/>
=head1 LICENSE
Copyrights 2024-2025 by [Mark Overmeer]. For other contributors see ChangeLog.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>