The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AnyEvent::CouchDB - a non-blocking CouchDB client based on jquery.couch.js

SYNOPSIS

Getting information about a CouchDB server:

  use AnyEvent::CouchDB;
  use Data::Dump 'pp';

  my $couch = couch('http://localhost:5984/');
  print pp( $couch->all_dbs->recv ), "\n";
  print pp( $couch->info->recv    ), "\n";

Get an object representing a CouchDB database:

  my $db = $couch->db('database');
  $db    = couchdb('database');
  $db    = couchdb('http://somewhere.com:7777/database/');

With authentication:

  # user is the username and s3cret is the password
  $db = couchdb('http://user:s3cret@somewhere.com:7777/database');

Work with individual CouchDB documents;

  my $user = $db->open_doc('~larry')->recv;
  $user->{name} = "larry";
  $db->save_doc($user)->recv;

Query a view:

  $db->view('users/all', { startkey => 'b', endkey => 'bZZZ' })->recv

Finally, an asynchronous example:

  # Calling cb allow you to set a callback that will run when results are available.
  $db->all_docs->cb(sub {
    my ($cv) = @_;
    print pp( $cv->recv ), "\n";
  });

  # However, you have to be in an event loop at some point in time.
  AnyEvent->condvar->recv;

DESCRIPTION

AnyEvent::CouchDB is a non-blocking CouchDB client implemented on top of the AnyEvent framework. Using this library will give you the ability to run many CouchDB requests asynchronously, and it was intended to be used within a Coro+AnyEvent environment. However, it can also be used synchronously if you want.

Its API is based on jquery.couch.js, but we've adapted the API slightly so that it makes sense in an asynchronous Perl environment.

AnyEvent condvars

The main thing you have to remember is that all the data retrieval methods return an AnyEvent condvar, $cv. If you want the actual data from the request, there are a few things you can do.

You may have noticed that many of the examples in the SYNOPSIS call recv on the condvar. You're allowed to do this under 2 circumstances:

Either you're in a main program,

Main programs are "allowed to call recv blockingly", according to the author of AnyEvent.

or you're in a Coro + AnyEvent environment.

When you call recv inside a coroutine, only that coroutine is blocked while other coroutines remain active. Thus, the program as a whole is still responsive.

If you're not using Coro, and you don't want your whole program to block, what you should do is call cb on the condvar, and give it a coderef to execute when the results come back. The coderef will be given a condvar as a parameter, and it can call recv on it to get the data. The final example in the SYNOPSIS gives a brief example of this.

Also note that recv will throw an exception if the request fails, so be prepared to catch exceptions where appropriate.

Please read the AnyEvent documentation for more information on the proper use of condvars.

The \%options Parameter

Many data retrieval methods will take an optional \%options hashref. Most of these options get turned into CGI query parameters. The standard CouchDB parameters are as follows:

key=keyvalue

This lets you pick out one document with the specified key value.

startkey=keyvalue

This makes it so that lists start with a key value that is greater than or equal to the specified key value.

startkey_docid=docid

This makes it so that lists start with a document with the specified docid.

endkey=keyvalue

This makes it so that lists end with a key value that is less than or equal to the specified key value.

count=max_rows_to_return

This limits the number of results to the specified number or less. If count is set to 0, you won't get any rows, but you will get the metadata for the request you made.

update=boolean

If you set update to false, CouchDB will skip doing any updating of a view. This will speed up the request, but you might not see all the latest data.

descending=boolean

Views are sorted by their keys in ascending order. However, if you set descending to true, they'll come back in descending order.

skip=rows_to_skip

The skip option should only be used with small values, as skipping a large range of documents this way is inefficient (it scans the index from the startkey and then skips N elements, but still needs to read all the index values to do that). For efficient paging use startkey and/or startkey_docid.

You may also put subroutine references in the success and error keys of this hashref, and they will be called upon success or failure of the request.

Documents Are Plain Hashrefs

Finally, note that the CouchDB documents you get back are plain hashrefs. They are not blessed into any kind of document class.

API

Convenience Functions

$couch = couch([ $uri ]);

This is a short-cut for:

  AnyEvent::CouchDB->new($uri)

and it is exported by default. It will return a connection to a CouchDB server, and if you don't pass it a URL, it'll assume http://localhost:5984/. Thus, you can type:

  $couch = couch;

$db = couchdb($name_or_uri);

This function will construct an AnyEvent::CouchDB::Database object for you. If you only give it a name, it'll assume that the CouchDB server is at http://localhost:5984/. You may also give it a full URL to a CouchDB database to connect to.

This function is also exported by default.

Object Construction

$couch = AnyEvent::CouchDB->new([ $uri ])

This method will instantiate an object that represents a CouchDB server. By default, it connects to http://localhost:5984/, but you may explicitly give it another URL if you want to connect to a CouchDB server on another server or a non-default port.

$db = $couch->db($name)

This method takes a name and returns an AnyEvent::CouchDB::Database object. This is the object that you'll use to work with CouchDB documents.

Queries and Actions

$cv = $couch->all_dbs()

This method requests an arrayref that contains the names of all the databases hosted on the current CouchDB server. It returns an AnyEvent condvar that you'll be expected to call recv on to get the data back.

$cv = $couch->info()

This method requests a hashref of info about the current CouchDB server and returns a condvar that you should call recv on. The hashref that's returned looks like this:

  {
    couchdb => 'Welcome',
    version => '0.7.3a658574'
  }

$cv = $couch->config()

This method requests a hashref of info regarding the configuration of the current CouchDB server. It returns a condvar that you should call recv on.

$cv = $couch->replicate($source, $target, [ \%options ])

This method requests that a $source CouchDB database be replicated to a $target CouchDB database. To represent a local database, pass in just the name of the database. To represent a remote database, pass in the URL to that database. Note that both databases must already exist for the replication to work. To create a continuous replication, set the continuous option to true.

Examples:

  # local to local
  $couch->replicate('local_db', 'local_db_backup')->recv;

  # local to remote
  $couch->replicate('local_db', 'http://elsewhere/remote_db')->recv

  # remote to local
  $couch->replicate('http://elsewhere/remote_db', 'local_db')->recv

  # local to remote with continuous replication
  $couch->replicate('local_db', 'http://elsewhere/remote_db', {continuous => 1})->recv

As usual, this method returns a condvar that you're expected to call recv on. Doing this will return a hashref that looks something like this upon success:

  {
    history => [
      {
        docs_read       => 0,
        docs_written    => 0,
        end_last_seq    => 149,
        end_time        => "Thu, 17 Jul 2008 18:08:13 GMT",
        missing_checked => 44,
        missing_found   => 0,
        start_last_seq  => 0,
        start_time      => "Thu, 17 Jul 2008 18:08:13 GMT",
      },
    ],
    ok => bless(do { \(my $o = 1) }, "JSON::XS::Boolean"),
    session_id      => "cac3c6259b452c36230efe5b41259c04",
    source_last_seq => 149,
  }

SEE ALSO

Scripts

couchdb-push

Push documents from the filesystem to CouchDB

AnyEvent::CouchDB::Database, AnyEvent::CouchDB::Exceptions, AnyEvent::HTTP, AnyEvent, Exception::Class

Client Libraries

Net::CouchDb, CouchDB::Client, POE::Component::CouchDB::Client, DB::CouchDB

View Servers

CouchDB::View - This lets you write your map/reduce functions in Perl instead of JavaScript.

The Original JavaScript Version

http://svn.apache.org/repos/asf/couchdb/trunk/share/www/script/jquery.couch.js

The GitHub Repository

http://github.com/beppu/anyevent-couchdb/tree/master

The Antepenultimate CouchDB Reference Card

http://blog.fupps.com/2010/04/20/the-antepenultimate-couchdb-reference-card/

The Reason for Existence

AnyEvent::CouchDB exists, because I needed a non-blocking CouchDB client that I could use within Continuity and Squatting.

AUTHOR

John BEPPU <beppu@cpan.org>

SPECIAL THANKS

Jan-Felix Wittman (for bug fixes, feature enhancements, and interesting couchdb discussion)

Yuval Kogman (for bug fixes)

Michael Zedeler (for bug fixes)

franck [http://github.com/franckcuny] (for feature enhancements)

Luke Closs (for bug fixes)

Michael Henson (bug fixes)

James Howe (bug reports)

Dave Williams (bug fixes)

Walter Werner (buf fixes)

COPYRIGHT

Copyright (c) 2008-2011 John BEPPU <beppu@cpan.org>.

The "MIT" License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.