Couch-DB

 view release on metacpan or  search on metacpan

ChangeLog  view on Meta::CPAN

version 0.002: Fri 31 May 10:27:47 CEST 2024

	Fixes:
	- include Couch::DB::Design
	- metacpan HTML of calls.

	Improvements:
	- implemented pagination with $result->nextPage (untested)
	- many documentation fixes
	- make cross-reference page available.
	- add cross-reference table Couch::DB -> endpoint

version 0.001: Wed 29 May 18:19:12 CEST 2024

	- initial release, interface complete but mainly untested.

bin/reference-table  view on Meta::CPAN

	foreach my $tr ($tree->elementify->find('table')->find('tr'))
	{	my (undef, $which, $what) = $tr->find('td');
		my ($a)  = $which->find('a') or next;
		my $href = $a->attr('href');
		my $call = $a->find_by_attribute(class => 'xref')->content->[0];

		# Mistake in 3.3.3 docs
		$call    = 'POST /{db}/_design/{ddoc}/_update/{func}/{docid}'
			if $call eq 'PUT /{db}/_design/{ddoc}/_update/{func}/{docid}';

		my ($http_method, $endpoint) = split " ", $call, 2;
		my $descr = $what->as_text;
	
		my %def    = (
			call        => $call,
			http_method => $http_method,
			endpoint    => $endpoint,
			doclink     => "$couchdb_api/$href",
			descr       => $descr,
		);
		$index{$call} = \%def;
	}

	# These are only described in notes in 3.3.3
	foreach my $endpoint ('/{db}/_local_docs/queries', '/{db}/_design_docs/queries')
	{	my %def = %{$index{'POST /{db}/_all_docs/queries'}};
		$def{call}     = "POST $endpoint";
		$def{endpoint} = $endpoint;
		$def{descr}    = '';
		$index{"POST $endpoint"} = \%def;
	}

	warn "Found ", scalar keys %index, " calls in the API docs\n";

}

####
###### parse the docs from implementation
####

bin/reference-table  view on Meta::CPAN

		foreach my $line (read_lines $file)
		{	$package = $1
				if $line =~ m/^package\s+([\w:]+)/;

			$last_use = "$module->{base}->$1($2)"
				if $line =~ m/^=method\s+(\w+)\s*(.*)/;

			my ($call, $status) = $line =~ /\[CouchDB API "([^"]+)".*?(|UNTESTED|TODO|UNSUPPORTED|PARTIAL)\]/
				or next;

			my ($http_method, $endpoint) = split " ", $call, 2;

			my $link = $manpage . '#' . uri_escape($last_use =~ s/.*->/\$obj->/r =~ s/\s/-/gr);
			my $use  = $status eq 'UNSUPPORTED' ? ''
			  : '<a href="' . $link . '">' . encode_entities($last_use) . '</a>';

			my %impl = (
				package     => $package,
				call        => $call,
				status      => $status || 'DONE',
				http_method => $http_method,
				endpoint    => $endpoint,
				use         => $use,
			);

			push @{$impls_by_call{$call}}, \%impl;
			push @{$impls_by_use{$use}}, \%impl if length $use;
		}
	}

	warn "Found ", scalar keys %impls_by_call, " calls implemented.\n";
}

bin/reference-table  view on Meta::CPAN

      <td>Implementation not started.</td></tr>
  <tr><td>UNSUPPORTED</td>
      <td class="count">$status_counts{UNSUPPORTED}</td>
      <td>For some reason, it seems useless to implement this.</td></tr>
  </table>
__PROGRESS
}

sub cdb2mod()
{	print <<__HEADER;
  <h2 name="cdb2mod">CouchDB endpoint &rarr; Couch::DB method</h2>
  <ul>
  <li><a href="#mod2cdb">Couch::DB method &rarr; CouchDB endpoint</a></li>
  </ul>

  <table id="cdb2mod">
  <tr><th style="width: 50%"><a href="https://docs.couchdb.org/en/stable/">CouchDB API "stable"</a> and official summary</th>
      <th>impl status</th>
      <th>Couch::DB use</th></tr>

__HEADER

	foreach my $index (sort { $a->{endpoint} cmp $b->{endpoint} || $a->{http_method} cmp $b->{http_method}} values %index)
	{	my @impls = @{$impls_by_call{$index->{call}} || [ ]};
		@impls <= 2 or die $index->{call};  # CSS descr issue

		my $first = shift @impls || { status => 'MISSING', use => '' };

		print <<__ROW1;
  <tr class="first">
      <td class="api"><a href="$index->{doclink}">$index->{call}</a></td>
      <td class="status">$first->{status}</td>
      <td class="use">$first->{use}</td></tr>

bin/reference-table  view on Meta::CPAN


	print <<__FOOTER;
  </table>
__FOOTER
}


sub mod2cdb()
{
	print <<__HEADER;
  <h2 name="mod2cdb">Couch::DB method &rarr; CouchDB endpoint</h2>
  <ul>
  <li><a href="#cdb2mod">CouchDB endpoint &rarr; Couch::DB method</a></li>
  </ul>

  <table id="mod2cdb">
  <tr><th>Couch::DB use</th>
      <th>impl status</th>
      <th style="width: 50%"><a href="https://docs.couchdb.org/en/stable/">CouchDB API "stable"</a></th></tr>

__HEADER

	foreach my $use (sort keys %impls_by_use)

lib/Couch/DB.pod  view on Meta::CPAN


Also, open F<https://perl.overmeer.net/couch-db/reference.html>
in a browser window, as useful cross-reference: parameters for CouchDB
are not documented in this Perl documentation!

B<Please read> the L</DETAILS> section, further down, at least once
before you start!

=head2 Early adopters

B<Be warned> that this module is really new.  The 127 different endpoints
that the CouchDB 3.3.3 API defines, are grouped and combined.  The result
is often not tested, and certainly not battle ready.  Please, report
the result of calls which which are currently flagged "UNTESTED".

B<Please help> me fix issues by reporting them.  Bugs will be solved within
a day.  Please, contribute ideas to make the use of the module lighter.
Together, we can make the quality grow fast.

=head2 Integration with your framework

lib/Couch/DB.pod  view on Meta::CPAN

Mojo::UserAgent, Mojo::IOLoop, and many other.

=back

Other extensions are hopefully added in the future.  Preferrably as part
of this release so it gets maintained together.  The extensions are not
too difficult to create and certainly quite small.

=head2 Where can I find what?

The CouchDB API lists all endpoints as URLs.  This library, however,
creates an Object Oriented interface around these calls: you do not
see the internals in the resulting code.  Knowing the CouchDB API,
it is usually immediately clear where to find a certain end-point:
C<< /{db} >> will be in L<Couch::DB::Database|Couch::DB::Database>.  A major exception is
anything what has to do with replication and sharding: this is bundled
in L<Couch::DB::Cluster|Couch::DB::Cluster>.

Have a look at F<https://perl.overmeer.net/couch-db/reference.html>.
Keep that page open in your browser while developing.

lib/Couch/DB.pod  view on Meta::CPAN

=item $obj-E<gt>B<addClient>($client)

Add a L<Couch::DB::Client|Couch::DB::Client>-object to be used to contact the CouchDB
cluster.  Returned is the couch object, so these calls are stackable.

=item $obj-E<gt>B<call>($method, $path, %options)

Call some couchDB server, to get work done.  This is the base for any
interaction with the server.

B<Note:> you should probably not use this method yourself: all endpoint of
CouchDB are available via a nice, abstract wrapper.

 -Option   --Default
  client     undef
  clients    undef
  delay      false
  on_chain   undef
  on_values  undef
  paging     {}
  query      undef

lib/Couch/DB.pod  view on Meta::CPAN


A function (sub) which transforms the data of the CouchDB answer into
useful Perl values and objects.  See L<Couch::DB::toPerl()|Couch::DB/"Processing">.
The function is called with the result and a partially or unprocessed
reponse (answer).  That data shall not be modified.  Return a new
data-structure which contains the processed information, which may
reuse parts which are not modified.

=item paging => HASH

When the endpoint support paging, then its needed configuration
data has been collected in here.  This enables the use of C<_succeed>,
C<_page>, C<skip>, and friends.  See examples in section L</Pagination>.

=item query => HASH

Query parameters for the request.

=item send => HASH

The content to be sent with POST and PUT methods.

lib/Couch/DB.pod  view on Meta::CPAN


The Perl programming language works with functions, methods, and
objects, so why would your libary require you to play with URLs?
So, C<Couch::DB> has the following extra features:

=over 4

=item *

Calls have a functional name, and are grouped into classes: the
endpoint URL processing is totally abstracted away;

=item *

Define multiple clients at the same time, for automatic fail-over,
read, write, and permission separation, or parallellism;

=item *

Resolving differences between CouchDB-server versions.  You may
even run different CouchDB versions on your nodes;

lib/Couch/DB.pod  view on Meta::CPAN

All these API methods return a L<Couch::DB::Result|Couch::DB::Result> object, which can tell
you how the call worked, and the results.  The resulting object is overloaded
boolean to produce C<false> in case of an error.  So typically:

  my $couch  = Couch::DB::Mojolicious->new(version => '3.3.3');
  my $result = $couch->requestUUIDs(100);
  $result or die;

  my $uuids  = $result->values->{uuids};

This CouchDB library hides the fact that endpoint C</_uuids> has been called.
It also hides the client (UserAgent) which was used to collect the data.

You could also write

  my $uuids  = $couch->requestUUIDs(100)->values->{uuids};

because "values()" will terminate when the database call did not result
in a successful answer.  Last alternative:

   my @uuids = $couch->freshUUIDs(100);

lib/Couch/DB/Database.pod  view on Meta::CPAN


 [CouchDB API "GET /{db}/_all_docs"]
 [CouchDB API "POST /{db}/_all_docs"]
 [CouchDB API "POST /{db}/_all_docs/queries", UNTESTED]
 [CouchDB API "GET /{db}/_local_docs", UNTESTED]
 [CouchDB API "POST /{db}/_local_docs", UNTESTED]
 [CouchDB API "POST /{db}/_local_docs/queries", UNTESTED]
 [CouchDB API "GET /{db}/_partition/{partition}/_all_docs", UNTESTED]

Get the documents, optionally limited by a view.  If there are queries,
then C<POST> is used, otherwise the C<GET> endpoint.

The returned structure depends on the C<%query> and the number of
C<@queries> (an ARRAY of query HASHes).  This method support pagination,
but only when a single query is given.

The preferred way to use this method with a C<view>, is by calling
L<Couch::DB::Design::viewSearch()|Couch::DB::Design/"Views"> on its C<design> object.

 -Option   --Default
  design     undef

reference.html  view on Meta::CPAN

  <tr><td>UNTESTED</td>
      <td class="count">77</td>
      <td>Implemented but never tried.</td></tr>
  <tr><td>TODO</td>
      <td class="count">2</td>
      <td>Implementation not started.</td></tr>
  <tr><td>UNSUPPORTED</td>
      <td class="count">5</td>
      <td>For some reason, it seems useless to implement this.</td></tr>
  </table>
  <h2 name="cdb2mod">CouchDB endpoint &rarr; Couch::DB method</h2>
  <ul>
  <li><a href="#mod2cdb">Couch::DB method &rarr; CouchDB endpoint</a></li>
  </ul>

  <table id="cdb2mod">
  <tr><th style="width: 50%"><a href="https://docs.couchdb.org/en/stable/">CouchDB API "stable"</a> and official summary</th>
      <th>impl status</th>
      <th>Couch::DB use</th></tr>

  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/server/common.html#get--">GET /</a></td>
      <td class="status">DONE</td>

reference.html  view on Meta::CPAN

      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/server/authn.html#post--_session">POST /_session</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Client.pod#%24obj-%3Elogin%28%25options%29">$client-&gt;login(%options)</a></td></tr>
  <tr><td class="descr"><p>Authenticates user by Cookie-based user login</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/server/common.html#get--_up">GET /_up</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Client.pod#%24obj-%3EserverStatus%28%25options%29">$client-&gt;serverStatus(%options)</a></td></tr>
  <tr><td class="descr"><p>Health check endpoint</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/server/common.html#get--_utils">GET /_utils</a></td>
      <td class="status">UNSUPPORTED</td>
      <td class="use"></td></tr>
  <tr><td class="descr"><p>Redirects to /_utils/</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">

reference.html  view on Meta::CPAN

      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#get--db-_design-ddoc-_list-func-other-ddoc-view">GET /{db}/_design/{ddoc}/_list/{func}/{other-ddoc}/{view}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Elist%28%24function%2C-%24view%2C-%25options%29">$ddoc-&gt;list($function, $view, %options)</a></td></tr>
  <tr><td class="descr"><p>Executes a list function against the view from other design document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#post--db-_design-ddoc-_list-func-other-ddoc-view">POST /{db}/_design/{ddoc}/_list/{func}/{other-ddoc}/{view}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Elist%28%24function%2C-%24view%2C-%25options%29">$ddoc-&gt;list($function, $view, %options)</a></td></tr>
  <tr><td class="descr"><p>Same as GET method for the related endpoint</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#get--db-_design-ddoc-_list-func-view">GET /{db}/_design/{ddoc}/_list/{func}/{view}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Elist%28%24function%2C-%24view%2C-%25options%29">$ddoc-&gt;list($function, $view, %options)</a></td></tr>
  <tr><td class="descr"><p>Executes a list function against the view from the same design document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#post--db-_design-ddoc-_list-func-view">POST /{db}/_design/{ddoc}/_list/{func}/{view}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Elist%28%24function%2C-%24view%2C-%25options%29">$ddoc-&gt;list($function, $view, %options)</a></td></tr>
  <tr><td class="descr"><p>Same as GET method for the related endpoint</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/rewrites.html#any--db-_design-ddoc-_rewrite-path">ANY /{db}/_design/{ddoc}/_rewrite/{path}</a></td>
      <td class="status">UNSUPPORTED</td>
      <td class="use"></td></tr>
  <tr><td class="descr"><p>Rewrites HTTP request for the specified path by using stored array of routing rules or JavaScript function</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">

reference.html  view on Meta::CPAN

      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#get--db-_design-ddoc-_show-func">GET /{db}/_design/{ddoc}/_show/{func}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Eshow%28%24function%2C-%5B%24doc%7C%24docid%7Cundef%2C-%25options%5D%29">$ddoc-&gt;show($function, [$doc|$docid|undef, %options])</a></td></tr>
  <tr><td class="descr"><p>Executes a show function against null document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#post--db-_design-ddoc-_show-func">POST /{db}/_design/{ddoc}/_show/{func}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Eshow%28%24function%2C-%5B%24doc%7C%24docid%7Cundef%2C-%25options%5D%29">$ddoc-&gt;show($function, [$doc|$docid|undef, %options])</a></td></tr>
  <tr><td class="descr"><p>Same as GET method for the related endpoint</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#get--db-_design-ddoc-_show-func-docid">GET /{db}/_design/{ddoc}/_show/{func}/{docid}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Eshow%28%24function%2C-%5B%24doc%7C%24docid%7Cundef%2C-%25options%5D%29">$ddoc-&gt;show($function, [$doc|$docid|undef, %options])</a></td></tr>
  <tr><td class="descr"><p>Executes a show function against the specified document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#post--db-_design-ddoc-_show-func-docid">POST /{db}/_design/{ddoc}/_show/{func}/{docid}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3Eshow%28%24function%2C-%5B%24doc%7C%24docid%7Cundef%2C-%25options%5D%29">$ddoc-&gt;show($function, [$doc|$docid|undef, %options])</a></td></tr>
  <tr><td class="descr"><p>Same as GET method for the related endpoint</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/ddoc/render.html#post--db-_design-ddoc-_update-func">POST /{db}/_design/{ddoc}/_update/{func}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Design.pod#%24obj-%3EapplyUpdate%28%24function%2C-%5B%24doc%7C%24docid%7Cundef%2C-%25options%5D%29">$ddoc-&gt;applyUpdate($function, [$doc|$docid|undef, %options])</a...
  <tr><td class="descr"><p>Executes an update function against the null document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">

reference.html  view on Meta::CPAN

      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/database/bulk-api.html#post--db-_all_docs-queries">POST /{db}/_design_docs/queries</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Database.pod#%24obj-%3Edesigns%28%5B%5C%25search%7C%5C%40%25search%2C-%25options%5D%29">$db-&gt;designs([\%search|\@%search, %options])</a></td></tr>
  <tr><td class="descr"><p></p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/database/compact.html#post--db-_ensure_full_commit">POST /{db}/_ensure_full_commit</a></td>
      <td class="status">DONE</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Database.pod#%24obj-%3EensureFullCommit%28%25options%29">$db-&gt;ensureFullCommit(%options)</a></td></tr>
  <tr><td class="descr"><p>Deprecated endpoint to support CouchDB versions < 3.0 replicators.</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_explain">POST /{db}/_explain</a></td>
      <td class="status">DONE</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Database.pod#%24obj-%3EfindExplain%28%5C%25search%2C-%25options%29">$db-&gt;findExplain(\%search, %options)</a></td></tr>
  <tr><td class="descr"><p>Identify which index is being used by a particular query.</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">

reference.html  view on Meta::CPAN

      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  <tr class="first">
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/document/attachments.html#put--db-docid-attname">PUT /{db}/{docid}/{attname}</a></td>
      <td class="status">UNTESTED</td>
      <td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB/Document.pod#%24obj-%3EattSave%28%24name%2C-%24data%2C-%25options%29">$doc-&gt;attSave($name, $data, %options)</a></td></tr>
  <tr><td class="descr"><p>Adds an attachment of a document</p></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td></tr>
  </table>
  <h2 name="mod2cdb">Couch::DB method &rarr; CouchDB endpoint</h2>
  <ul>
  <li><a href="#cdb2mod">CouchDB endpoint &rarr; Couch::DB method</a></li>
  </ul>

  <table id="mod2cdb">
  <tr><th>Couch::DB use</th>
      <th>impl status</th>
      <th style="width: 50%"><a href="https://docs.couchdb.org/en/stable/">CouchDB API "stable"</a></th></tr>

  <tr><td class="use"><a href="https://metacpan.org/dist/Couch-DB/view/lib/Couch/DB.pod#%24obj-%3ErequestUUIDs%28%24count%2C-%25options%29">$couch-&gt;requestUUIDs($count, %options)</a></td>
      <td class="status">DONE</td>
      <td class="api"><a href="https://docs.couchdb.org/en/stable/api/server/common.html#get--_uuids">GET /_uuids</a></td></tr>



( run in 0.316 second using v1.01-cache-2.11-cpan-cc502c75498 )