AnyEvent-CouchDB
view release on metacpan or search on metacpan
- $options{header} is not deleted anymore
- $db->view passes authentication information
1.22 2010-10-12
- Reverted a change to the exception code that serialized the exception data to JSON.
1.21 2010-09-13
- Had some problems with PAUSE. Same as 1.20. Reuploading.
1.20 2010-05-13
- a double-utf8 bug was fixed (by Stéphane)
- fetch attachments using open_attachment(). (by Michael Zedeler)
1.19 2010-05-06
- AnyEvent::CouchDB::Stream !!! (by franckcuny)
1.18 2010-04-15
- encode the exception message as json (by franckcuny)
1.17 2010-03-26
- support to continuous replication, close RT #54922 (by franckcuny)
1.15 2010-03-03
- add HEAD method; use custom http headers; add POD about the http headers (by franckcuny)
1.14 2010-02-25
- fixed a minor bug in the couchdb() function (by Michael Zedeler)
1.13 2010-01-04
- make the couchdb() function bless its URI (by Douglas Hunter)
1.12 2009-05-22
- Set utf8 flag on default JSON::XS object (by Yuval Kogman)
1.11 2009-05-08
- Implemented special case for unescaping design document ids in open_doc().
id => '_design/docs' => '/database/_design/docs' # unescape '/'
id => 'whatever/else' => '/database/whatever%2Felse' # leave '/' escaped as %2F
- bin/couchdb-push - Publish JSON-encoded documents from the filesystem to CouchDB
- filenames map to ids
- automatic ids are currently not allowed
- Arbitrary URL support
- get|put|post|delete $path, $options
lib/AnyEvent/CouchDB.pm view on Meta::CPAN
use Exporter;
use base 'Exporter';
our @EXPORT = qw(couch couchdb);
# exception class shortcuts
our $HTTPError = "AnyEvent::CouchDB::Exception::HTTPError";
our $JSONError = "AnyEvent::CouchDB::Exception::JSONError";
# default JSON encoder
our $default_json = JSON->new->allow_nonref->utf8;
# arbitrary uri support
sub _build_headers {
my ( $self, $options ) = @_;
my $headers = $options->{headers};
if ( ref($headers) ne 'HASH' ) {
$headers = {};
}
# should probably move $options->{type} to $options->{headers}
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
package AnyEvent::CouchDB::Database;
use strict;
use warnings;
no warnings 'once';
use JSON;
use AnyEvent::HTTP;
use AnyEvent::CouchDB::Exceptions;
use Data::Dump::Streamer;
use URI::Escape qw( uri_escape uri_escape_utf8 );
use IO::All;
use MIME::Base64;
our $default_json;
# manual import ;-)
*cvcb = *AnyEvent::CouchDB::cvcb;
*default_json = *AnyEvent::CouchDB::default_json;
*_build_headers = *AnyEvent::CouchDB::_build_headers;
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
my $options = shift;
my $json = $default_json;
my @buf;
if (defined($options) && keys %$options) {
for my $name (keys %$options) {
next if ($name eq 'error' || $name eq 'success' || $name eq 'headers');
my $value = $options->{$name};
if ($name eq 'key' || $name eq 'startkey' || $name eq 'endkey') {
$value = uri_escape( $json->encode($value) );
} else {
$value = uri_escape_utf8($value);
}
if ($name eq 'group' || $name eq 'reduce' || $name eq 'descending' || $name eq 'include_docs') {
$value = $value
? ( ($value eq 'false') ? 'false' : 'true' )
: 'false';
}
push @buf, "$name=$value";
}
}
(@buf)
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
}
sub open_doc {
my ( $self, $doc_id, $options ) = @_;
if ( not defined $doc_id ) {
AnyEvent::CouchDB::Exception::UndefinedDocument->throw(
"An undefined id was passed to open_doc()."
);
}
my ( $cv, $cb ) = cvcb( $options, undef, $self->json_encoder );
my $id = uri_escape_utf8($doc_id);
if ( $id =~ qr{^_design%2F} ) {
$id =~ s{%2F}{/}g;
}
http_request(
GET => $self->uri . $id . $query->($options),
headers => $self->_build_headers($options),
$cb
);
$cv;
}
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
};
}
my ( $cv, $cb ) = cvcb( $options, 201, $self->json_encoder );
my ( $method, $uri );
if ( not defined $doc->{_id} ) {
$method = 'POST';
$uri = $self->uri;
}
else {
$method = 'PUT';
$uri = $self->uri . uri_escape_utf8( $doc->{_id} );
}
http_request(
$method => $uri . $query->($options),
headers => $self->_build_headers($options),
body => $self->json($doc),
$cb
);
$cv;
}
sub remove_doc {
my ( $self, $doc, $options ) = @_;
die("Document is missing _id!") unless ( defined $doc->{_id} );
my ( $cv, $cb ) = cvcb( $options, undef, $self->json_encoder );
http_request(
DELETE => $self->uri
. uri_escape_utf8( $doc->{_id} )
. $query->( { rev => $doc->{_rev} } ),
headers => $self->_build_headers($options),
$cb
);
$cv;
}
sub attach {
my ( $self, $doc, $attachment, $options ) = @_;
my $body < io( $options->{src} );
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
$doc->{_attachments}->{$attachment} = {
'content_type' => $options->{type},
'length' => $length,
'stub' => JSON::true,
};
};
}
my ( $cv, $cb ) = cvcb( $options, 201, $self->json_encoder );
http_request(
PUT => $self->uri
. uri_escape_utf8( $doc->{_id} ) . "/"
. uri_escape_utf8($attachment)
. $query->( { rev => $doc->{_rev} } ),
headers => $self->_build_headers($options),
body => $body,
$cb
);
$cv;
}
sub open_attachment {
my ( $self, $doc, $attachment, $options ) = @_;
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
my ($body, $headers) = @_;
if ($headers->{Status} >= 200 and $headers->{Status} < 400) {
$success->(@_);
} else {
$error->($headers);
}
};
http_request(
GET => $self->uri
. uri_escape_utf8( $doc->{_id} ) . "/"
. uri_escape_utf8($attachment),
headers => $self->_build_headers($options),
$cb
);
$cv;
}
sub detach {
my ( $self, $doc, $attachment, $options ) = @_;
if ( $options->{success} ) {
my $orig = $options->{success};
lib/AnyEvent/CouchDB/Database.pm view on Meta::CPAN
$options->{success} = sub {
my ($resp) = @_;
$doc->{_id} = $resp->{id};
$doc->{_rev} = $resp->{rev};
delete $doc->{_attachments}->{$attachment};
};
}
my ( $cv, $cb ) = cvcb( $options, undef, $self->json_encoder );
http_request(
DELETE => $self->uri
. uri_escape_utf8( $doc->{_id} ) . "/"
. uri_escape_utf8($attachment)
. $query->( { rev => $doc->{_rev} } ),
headers => $self->_build_headers($options),
$cb
);
$cv;
}
sub bulk_docs {
my ( $self, $docs, $options ) = @_;
my ( $cv, $cb ) = cvcb( $options, undef, $self->json_encoder );
( run in 0.515 second using v1.01-cache-2.11-cpan-49f99fa48dc )