File Coverage

blib/lib/CouchDB/Client.pm
Criterion Covered Total %
statement 54 78 69.2
branch 7 18 38.8
condition 3 14 21.4
subroutine 13 17 76.4
pod 9 9 100.0
total 86 136 63.2


line stmt bran cond sub pod time code
1              
2             package CouchDB::Client;
3              
4 3     3   72001 use strict;
  3         8  
  3         149  
5 3     3   14 use warnings;
  3         7  
  3         143  
6              
7             our $VERSION = '0.09';
8              
9 3     3   4097 use JSON::Any qw(XS JSON DWIW);
  3         91991  
  3         21  
10 3     3   87121 use LWP::UserAgent qw();
  3         209135  
  3         91  
11 3     3   33 use HTTP::Request qw();
  3         7  
  3         59  
12 3     3   8030 use Encode qw(encode);
  3         52869  
  3         310  
13 3     3   31 use Carp qw(confess);
  3         6  
  3         142  
14              
15 3     3   1255 use CouchDB::Client::DB;
  3         9  
  3         2453  
16              
17             sub new {
18 2     2 1 27 my $class = shift;
19 2 50       14 my %opt = @_ == 1 ? %{$_[0]} : @_;
  0         0  
20              
21 2         4 my %self;
22 2 50       7 if ($opt{uri}) {
23 2         6 $self{uri} = $opt{uri};
24 2 50       16 $self{uri} .= '/' unless $self{uri} =~ m{/$};
25             }
26             else {
27 0   0     0 $self{uri} = ($opt{scheme} || 'http') . '://' .
      0        
      0        
28             ($opt{host} || 'localhost') . ':' .
29             ($opt{port} || '5984') . '/';
30             }
31 2   33     23 $self{json} = ($opt{json} || JSON::Any->new(utf8 => 1, allow_blessed => 1));
32 2   33     218 $self{ua} = ($opt{ua} || LWP::UserAgent->new(agent => "CouchDB::Client/$VERSION"));
33              
34 2         7519 return bless \%self, $class;
35             }
36              
37             sub testConnection {
38 2     2 1 18 my $self = shift;
39 2         5 eval { $self->serverInfo; };
  2         10  
40 2 50       287 return 0 if $@;
41 0         0 return 1;
42             }
43              
44             sub serverInfo {
45 2     2 1 4 my $self = shift;
46 2         11 my $res = $self->req('GET');
47 2 50       11 return $res->{json} if $res->{success};
48 2         441 confess("Connection error: $res->{msg}");
49             }
50              
51             sub newDB {
52 0     0 1 0 my $self = shift;
53 0         0 my $name = shift;
54 0         0 return CouchDB::Client::DB->new(name => $name, client => $self);
55             }
56              
57             sub listDBNames {
58 0     0 1 0 my $self = shift;
59 0         0 my $res = $self->req('GET', '_all_dbs');
60 0 0       0 return $res->{json} if $res->{success};
61 0         0 confess("Connection error: $res->{msg}");
62             }
63              
64             sub listDBs {
65 0     0 1 0 my $self = shift;
66 0         0 return [ map { $self->newDB($_) } @{$self->listDBNames} ];
  0         0  
  0         0  
67             }
68              
69             sub dbExists {
70 0     0 1 0 my $self = shift;
71 0         0 my $name = shift;
72 0         0 $name =~ s{/$}{};
73 0 0       0 return (grep { $_ eq $name } @{$self->listDBNames}) ? 1 : 0;
  0         0  
  0         0  
74             }
75              
76             # --- CONNECTION HANDLING ---
77             sub req {
78 2     2 1 5 my $self = shift;
79 2         4 my $meth = shift;
80 2         4 my $path = shift;
81 2         6 my $content = shift;
82 2         3 my $headers = undef;
83              
84 2 50       10 if (ref $content) {
85 0         0 $content = encode('utf-8', $self->{json}->encode($content));
86 0         0 $headers = HTTP::Headers->new('Content-Type' => 'application/json');
87             }
88 2         19 my $res = $self->{ua}->request( HTTP::Request->new($meth, $self->uriForPath($path), $headers, $content) );
89 2         197585 my $ret = {
90             status => $res->code,
91             msg => $res->status_line,
92             success => 0,
93             };
94 2 50       53 if ($res->is_success) {
95 0         0 $ret->{success} = 1;
96 0         0 $ret->{json} = $self->{json}->decode($res->content);
97             }
98 2         70 return $ret;
99             }
100              
101             # --- HELPERS ---
102             sub uriForPath {
103 2     2 1 5 my $self = shift;
104 2   50     15 my $path = shift() || '';
105 2         24 return $self->{uri} . $path;
106             }
107              
108              
109             1;
110              
111             =pod
112              
113             =head1 NAME
114              
115             CouchDB::Client - Simple, correct client for CouchDB
116              
117             =head1 SYNOPSIS
118              
119             use CouchDB::Client;
120             my $c = CouchDB::Client->new(uri => 'https://dbserver:5984/');
121             $c->testConnection or die "The server cannot be reached";
122             print "Running version " . $c->serverInfo->{version} . "\n";
123             my $db = $c->newDB('my-stuff')->create;
124              
125             # listing databases
126             $c->listDBs;
127             $c->listDBNames;
128              
129              
130             =head1 DESCRIPTION
131              
132             This module is a client for the CouchDB database.
133              
134             =head1 METHODS
135              
136             =over 8
137              
138             =item new
139              
140             Constructor. Takes a hash or hashref of options: C which specifies the server's URI;
141             C, C, C which are used if C isn't provided and default to 'http',
142             'localhost', and '5984' respectively; C which defaults to a JSON::Any object with
143             utf8 and allow_blessed turned on but can be replaced with anything with the same interface;
144             and C which is a LWP::UserAgent object and can also be replaced.
145              
146             =item testConnection
147              
148             Returns true if a connection can be made to the server, false otherwise.
149              
150             =item serverInfo
151              
152             Returns a hashref of the server metadata, typically something that looks like
153             C<<< { couchdb => "Welcome", version => "0.8.0-incubating"} >>>. It throws
154             an exception if it can't connect.
155              
156             =item newDB $NAME
157              
158             Returns a new C object for a database of that name. Note that the DB
159             does not need to exist yet, and will not be created if it doesn't.
160              
161             =item listDBNames
162              
163             Returns an arrayref of all the database names that the server knows of. Throws an exception
164             if it cannot connect.
165              
166             =item listDBs
167              
168             Same as above but returns an arrayref of C objects instead.
169              
170             =item dbExists $NAME
171              
172             Returns true if a database of that name exists, false otherwise.
173              
174             =back
175              
176             =head1 INTERNAL METHODS
177              
178             You will use these at your own risk
179              
180             =over 8
181              
182             =item req $METHOD, $PATH, $CONTENT
183              
184             $METHOD is the HTTP method to use; $PATH the part of the path that follows C;
185             and $CONTENT a Perl data structure. The latter, if present, is encoded to JSON and the request
186             is made using the given method and path. The return value is a hash containing a boolean indicating
187             C, a C being the HTTP response code, a descriptive C, and a C field
188             containing the response JSON.
189              
190             =item uriForPath $PATH
191              
192             Gets a path and returns the complete URI.
193              
194             =back
195              
196             =head1 AUTHOR
197              
198             Robin Berjon,
199             Maverick Edwards, (current maintainer)
200              
201             =head1 BUGS
202              
203             Please report any bugs or feature requests to bug-couchdb-client at rt.cpan.org, or through the
204             web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CouchDB-Client.
205              
206             =head1 COPYRIGHT & LICENSE
207              
208             Copyright 2008 Robin Berjon, all rights reserved.
209              
210             This library is free software; you can redistribute it and/or modify it under the same terms as
211             Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may
212             have available.
213              
214             =cut