simple CouchDB API for storage and reporting
[pxelator] / lib / PXElator / CouchDB.pm
diff --git a/lib/PXElator/CouchDB.pm b/lib/PXElator/CouchDB.pm
new file mode 100644 (file)
index 0000000..4f8aa29
--- /dev/null
@@ -0,0 +1,90 @@
+package CouchDB;
+
+# http://wiki.apache.org/couchdb/Getting_started_with_Perl
+
+use strict;
+use warnings;
+
+use LWP::UserAgent;
+use JSON;
+use Data::Dump qw/dump/;
+
+sub new {
+       my ($class, $host, $port, $options) = @_;
+
+       my $ua = LWP::UserAgent->new;
+       $ua->timeout(10);
+       $ua->env_proxy;
+
+       $host ||= 'localhost';
+       $port ||= 5984;
+
+       return bless {
+               ua                       => $ua,
+               host             => $host,
+               port             => $port,
+               base_uri => "http://$host:$port/",
+       }, $class;
+}
+
+sub ua { shift->{ua} }
+sub base { shift->{base_uri} }
+
+sub request {
+       my ($self, $method, $uri, $content) = @_;
+
+       my $full_uri = $self->base . $uri;
+       my $req;
+
+       if (defined $content) {
+               #Content-Type: application/json
+
+               $req = HTTP::Request->new( $method, $full_uri, undef, $content );
+               $req->header('Content-Type' => 'application/json');
+       } else {
+               $req = HTTP::Request->new( $method, $full_uri );
+       }
+
+       my $response = $self->ua->request($req);
+
+       if ($response->is_success) {
+               return $response->content;
+       } else {
+               die($response->status_line . ":" . $response->content);
+       }
+}
+
+our $rev;
+
+sub delete {
+       my ($self, $url) = @_;
+
+       $self->request(DELETE => $url);
+}
+
+sub get {
+       my ($self, $url) = @_;
+
+       from_json $self->request(GET => $url);
+}
+
+sub put {
+       my ($self, $url, $json) = @_;
+       warn "put $url ",dump($json);
+
+       $rev->{$url} ||= eval { $self->get( $url )->{_rev} };
+
+       $json->{_rev} = $rev->{$url} if $rev->{$url};
+
+       $json = to_json $json if $json;
+
+       $self->request(PUT => $url, $json);
+}
+
+sub post {
+       my ($self, $url, $json) = @_;
+
+       $self->request(POST => $url, $json);
+}
+
+1;