File Coverage

blib/lib/Data/CouchDB.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Data::CouchDB;
2              
3 1     1   13041 use 5.006;
  1         2  
  1         29  
4 1     1   5 use strict;
  1         2  
  1         23  
5 1     1   3 use warnings;
  1         4  
  1         35  
6              
7             =head1 NAME
8              
9             Data::CouchDB - CouchDB document management
10              
11             =head1 VERSION
12              
13             Version 0.13
14              
15             =cut
16              
17             our $VERSION = '0.13';
18              
19             =head1 NAME
20              
21             Data::CouchDB
22              
23             =head1 SYNOPSYS
24              
25             my $couchdb = Data::CouchDB->new(
26             replica_host => 'localhost',
27             replica_port => 5432,
28             master_host => 'localhost',
29             master_port => 5432,
30             couch => 'testdb',
31             );
32              
33             =head1 DESCRIPTION
34              
35             This class represents couchdb as a datasource.
36              
37             =head1 ATTRIBUTES
38              
39             =cut
40              
41 1     1   200 use Moose;
  0            
  0            
42             use MooseX::StrictConstructor;
43             use namespace::autoclean;
44              
45             use Cache::RedisDB;
46             use Data::CouchDB::Connection;
47             use Try::Tiny;
48             use LWP::UserAgent;
49              
50             has name => (
51             is => 'ro',
52             isa => 'Str'
53             );
54              
55             =head2 db
56              
57             db with which to operate.
58              
59             =cut
60              
61             has db => (
62             is => 'ro',
63             isa => 'Str',
64             default => 'db',
65             );
66              
67             =head2 couchdb
68              
69             password for "couchdb" user
70              
71             =cut
72              
73             has couchdb => (
74             is => 'ro',
75             default => 'TESTPASS',
76             );
77              
78             =head2 replica_host
79              
80             name of the host to read from.
81              
82             =cut
83              
84             has 'replica_host' => (
85             is => 'ro',
86             default => 'localhost',
87             );
88              
89             =head2 replica_port
90              
91             port number in replica_host through which we can read.
92              
93             =cut
94              
95             has replica_port => (
96             is => 'ro',
97             default => '5984',
98             );
99              
100             =head2 replica_protocol
101              
102             protcol used to read.
103              
104             =cut
105              
106             has replica_protocol => (
107             is => 'ro',
108             isa => 'Str',
109             );
110              
111             =head2 master_host
112              
113             name of the host to write to
114              
115             =cut
116              
117             has 'master_host' => (
118             is => 'ro',
119             default => 'localhost',
120             );
121              
122             =head2 master_port
123              
124             port number in master_host through which we can write.
125              
126             =cut
127              
128             has master_port => (
129             is => 'ro',
130             default => '5984',
131             );
132              
133             =head2 master_protocol
134              
135             protocol used to write.
136              
137             =cut
138              
139             has master_protocol => (
140             is => 'ro',
141             isa => 'Str',
142             );
143              
144             =head2 replica
145              
146             The internal ds used to read from couchdb
147              
148             =cut
149              
150             has replica => (
151             is => 'ro',
152             isa => 'Data::CouchDB::Connection',
153             lazy_build => 1,
154             );
155              
156             =head2 master
157              
158             The internal ds used to write to couchdb
159              
160             =cut
161              
162             has master => (
163             is => 'ro',
164             isa => 'Data::CouchDB::Connection',
165             lazy_build => 1,
166             );
167              
168             =head2 ua
169              
170             Optionally passed ua(user_agent). If not passed the couchdb's default ua is used.
171              
172             =cut
173              
174             has ua => (
175             is => 'ro',
176             isa => 'Maybe[LWP::UserAgent]',
177             );
178              
179             =head1 METHODS
180              
181             =head2 document
182              
183             Get or set a couch document.
184              
185             Usage,
186             To get a document
187             $couchdb->document($doc_id);
188              
189             To set a document
190             $couchdb->document($doc_id, $data);
191              
192             $data is a HashRef
193              
194              
195             =cut
196              
197             my $cache_namespace = 'COUCH_DOCS';
198              
199             sub document {
200             my $self = shift;
201             my $doc = shift;
202             my $data = shift;
203              
204             my $cache_key = $self->db . '_' . $doc;
205             if ($data) {
206             Cache::RedisDB->del($cache_namespace, $cache_key) if ($self->_can_cache);
207             $data = $self->master->document($doc, $data);
208             } else {
209             $data = Cache::RedisDB->get($cache_namespace, $cache_key) if ($self->_can_cache);
210              
211             if (not $data) {
212             $data = $self->replica->document($doc);
213             Cache::RedisDB->set($cache_namespace, $cache_key, $data, 127)
214             if ($data and $self->_can_cache);
215             }
216             }
217              
218             return $data;
219             }
220              
221             =head2 view
222              
223             Query a couchdb view
224              
225             Usage,
226             Without Parameters
227             $couchdb->view($db, $viewname);
228              
229             With Parameters
230             $couchdb->view($db, $viewname, $parameters);
231              
232             $parameters is a HashRef
233              
234              
235             =cut
236              
237             sub view {
238             my $self = shift;
239             my $view = shift;
240             my $params = shift;
241              
242             return $self->replica->view($view, $params);
243             }
244              
245             =head2 document_present
246              
247             A syntatic sugar to check if a document
248              
249             Usage,
250             if ($couchdb->document_present($doc_id)) {
251             ....
252             }
253              
254             Throws,
255             Nothing
256              
257             Returns,
258             1 - if document is found.
259             undef - if document is not found.
260              
261             =cut
262              
263             sub document_present {
264             my $self = shift;
265             my $doc = shift;
266              
267             try { $self->replica->document($doc); } or return;
268              
269             return 1;
270             }
271              
272             =head2 create_document
273              
274             Creates a couch document
275              
276             Usage,
277             my $doc_id = $couchdb->create_document($doc_id);
278              
279             =cut
280              
281             sub create_document {
282             my $self = shift;
283             my $doc = shift;
284              
285             return $self->master->create_document($doc);
286             }
287              
288             =head2 delete_document
289              
290             Deletes a couch document
291              
292             Usage,
293             $couchdb->delete_document($doc_id);
294              
295             =cut
296              
297             sub delete_document {
298             my $self = shift;
299             my $doc = shift;
300              
301             return $self->master->delete_document($doc);
302             }
303              
304             =head2 create_database
305              
306             Creates a CouchDB Database.
307              
308             Usage,
309             $couchdb->create_database();
310              
311             =cut
312              
313             sub create_database {
314             my $self = shift;
315             return $self->master->create_database();
316             }
317              
318             =head2 can_read
319              
320             Confirms that you can read from this couchdb
321              
322             Usage,
323             if($couchdb->can_read) {
324             ...
325             }
326              
327             Returns,
328             1 - can read
329             undef - otherwise
330             =cut
331              
332             sub can_read {
333             my $self = shift;
334             return $self->replica->can_connect;
335             }
336              
337             =head2 can_write
338              
339             Confirms that you can write to this couchdb
340              
341             Usage,
342             if($couchdb->can_write) {
343             ...
344             }
345              
346             Returns,
347             1 - can write
348             undef - otherwise
349              
350             =cut
351              
352             sub can_write {
353             my $self = shift;
354             return $self->master->can_connect;
355             }
356              
357             sub _build_replica {
358             my $self = shift;
359             my $params = {};
360              
361             $params->{host} = $self->replica_host;
362             $params->{port} = $self->replica_port;
363             $params->{db} = $self->db;
364              
365             $params->{protocol} = $self->replica_protocol if ($self->replica_protocol);
366             $params->{couchdb} = $self->couchdb if ($self->couchdb);
367              
368             return Data::CouchDB::Connection->new(%$params);
369             }
370              
371             sub _build_master {
372             my $self = shift;
373             my $params = {};
374              
375             $params->{host} = $self->master_host;
376             $params->{port} = $self->master_port;
377             $params->{db} = $self->db;
378              
379             $params->{protocol} = $self->master_protocol if ($self->master_protocol);
380             $params->{couchdb} = $self->couchdb if ($self->couchdb);
381              
382             return Data::CouchDB::Connection->new(%$params);
383             }
384              
385             has '_can_cache' => (
386             is => 'ro',
387             lazy_build => 1,
388             );
389              
390             sub _build__can_cache {
391             return try { Cache::RedisDB::redis_connection(); 1; };
392             }
393              
394             __PACKAGE__->meta->make_immutable;
395              
396              
397             =head1 AUTHOR
398              
399             Binary.com, C<< >>
400              
401             =head1 BUGS
402              
403             Please report any bugs or feature requests to C, or through
404             the web interface at L. I will be notified, and then you'll
405             automatically be notified of progress on your bug as I make changes.
406              
407              
408              
409              
410             =head1 SUPPORT
411              
412             You can find documentation for this module with the perldoc command.
413              
414             perldoc Data::CouchDB
415              
416              
417             You can also look for information at:
418              
419             =over 4
420              
421             =item * RT: CPAN's request tracker (report bugs here)
422              
423             L
424              
425             =item * AnnoCPAN: Annotated CPAN documentation
426              
427             L
428              
429             =item * CPAN Ratings
430              
431             L
432              
433             =item * Search CPAN
434              
435             L
436              
437             =back
438              
439              
440             =head1 ACKNOWLEDGEMENTS
441              
442              
443             =head1 LICENSE AND COPYRIGHT
444              
445             Copyright 2015 Binary.com.
446              
447             This program is free software; you can redistribute it and/or modify it
448             under the terms of the the Artistic License (2.0). You may obtain a
449             copy of the full license at:
450              
451             L
452              
453             Any use, modification, and distribution of the Standard or Modified
454             Versions is governed by this Artistic License. By using, modifying or
455             distributing the Package, you accept this license. Do not use, modify,
456             or distribute the Package, if you do not accept this license.
457              
458             If your Modified Version has been derived from a Modified Version made
459             by someone other than you, you are nevertheless required to ensure that
460             your Modified Version complies with the requirements of this license.
461              
462             This license does not grant you the right to use any trademark, service
463             mark, tradename, or logo of the Copyright Holder.
464              
465             This license includes the non-exclusive, worldwide, free-of-charge
466             patent license to make, have made, use, offer to sell, sell, import and
467             otherwise transfer the Package with respect to any patent claims
468             licensable by the Copyright Holder that are necessarily infringed by the
469             Package. If you institute patent litigation (including a cross-claim or
470             counterclaim) against any party alleging that the Package constitutes
471             direct or contributory patent infringement, then this Artistic License
472             to you shall terminate on the date that such litigation is filed.
473              
474             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
475             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
476             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
477             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
478             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
479             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
480             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
481             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
482              
483              
484             =cut
485              
486             1; # End of Data::CouchDB