File Coverage

blib/lib/Storable/CouchDB.pm
Criterion Covered Total %
statement 17 68 25.0
branch 0 34 0.0
condition 1 3 33.3
subroutine 5 12 41.6
pod 7 7 100.0
total 30 124 24.1


line stmt bran cond sub pod time code
1             package Storable::CouchDB;
2 10     10   473849 use strict;
  10         22  
  10         375  
3 10     10   56 use warnings;
  10         16  
  10         308  
4 10     10   8057 use CouchDB::Client;
  10         1168225  
  10         6741  
5              
6             our $VERSION='0.04';
7              
8             =head1 NAME
9              
10             Storable::CouchDB - Persistences for Perl data structures in Apache CouchDB
11              
12             =head1 SYNOPSIS
13              
14             use Storable::CouchDB;
15             my $s = Storable::CouchDB->new;
16             my $data = $s->retrieve('doc'); #undef if not exists
17             $s->store('doc1' => "data"); #overwrites or creates if not exists
18             $s->store('doc2' => {"my" => "data"});
19             $s->store('doc3' => ["my", "data"]);
20             $s->store('doc4' => undef);
21             $s->store('doc5' => $deepDataStructure);
22             $s->delete('doc');
23              
24             =head2 Inheritance
25              
26             package My::Storable::CouchDB;
27             use base qw{Storable::CouchDB};
28             sub db {"what-i-want"};
29             sub uri {"http://where.i.want:5984/"};
30             1;
31              
32             =head1 DESCRIPTION
33              
34             The Storable::CouchDB package brings persistence to your Perl data structures containing SCALAR, ARRAY, HASH or anything that can be serialized into JSON.
35              
36             The concept for this package is to provide similar capabilities as Storable::store and Storable::retrieve which work seamlessly with CouchDB instead of a file system.
37              
38             =head2 Storage Details
39              
40             The data is stored in the CouchDB under a key named "data", in the document named by the "doc" argument, in the database return by the "db" method, on the server returned by the "uri" method.
41              
42             In pseudo code:
43              
44             $uri . $db . $doc -> "data" = $data
45              
46             Example:
47              
48             The perl script
49              
50             perl -MStorable::CouchDB -e 'Storable::CouchDB->new->store(counter=>{key=>[1,2,3]})'
51              
52             Creates or updates this document
53              
54             http://127.0.0.1:5984/perl-storable-couchdb/counter
55              
56             Which returns this JSON structure
57              
58             {
59             "_id":"counter",
60             "_rev":"39-31732f54c3ad4f2b61c217a9a8cf6171",
61             "data":{"key":[1,2,3]}
62             }
63              
64             =head1 USAGE
65              
66             Write a Perl data structure to the database.
67              
68             use Storable::CouchDB;
69             my $s = Storable::CouchDB->new;
70             $s->store('doc' => "Hello World!");
71              
72             Read a Perl data structure from the database.
73              
74             use Storable::CouchDB;
75             my $s = Storable::CouchDB->new;
76             my $data = $s->retrieve('doc');
77             print "$data\n";
78              
79             prints "Hello World!"
80              
81             =head1 CONSTRUCTOR
82              
83             =head2 new
84              
85             my $s = Storable::CouchDB->new; #use default server and database
86              
87             my $s = Storable::CouchDB->new(
88             uri => 'http://127.0.0.1:5984/', #default
89             db => 'perl-storable-couchDB', #default
90             );
91              
92             =cut
93              
94             sub new {
95 10     10 1 118 my $this = shift();
96 10   33     72 my $class = ref($this) || $this;
97 10         26 my $self = {};
98 10         23 bless $self, $class;
99 10         58 $self->initialize(@_);
100 10         29 return $self;
101             }
102              
103             =head1 METHODS
104              
105             =head2 initialize
106              
107             =cut
108              
109             sub initialize {
110 10     10 1 19 my $self = shift();
111 10         89 %$self=@_;
112             }
113              
114             =head2 store
115              
116             $s->store('doc' => "Value");
117             $s->store('doc' => {a => 1});
118             $s->store('doc' => [1, 2, 3]);
119             my $data=$s->store('doc' => {b => 2}); #returns data that was stored
120              
121             API Difference: The L API uses the 'store data > filename' syntax which I think is counterintuitive for a document key=>value store like Apache CouchDB.
122              
123             =cut
124              
125             sub store {
126 0     0 1   my $self=shift;
127 0 0         die("Error: Wrong number of arguments.") unless @_ == 2;
128 0           my $doc=shift;
129 0 0         die("Error: Document name must be defined.") unless defined $doc;
130 0           my $data=shift; #support storing undef!
131 0           my $cdbdoc=$self->_db->newDoc($doc); #isa CouchDB::Client::Doc
132 0 0         if ($self->_db->docExists($doc)) {
133 0           $cdbdoc->retrieve; #to get revision number for object
134 0           $cdbdoc->data({data=>$data});
135 0           $cdbdoc->update;
136             } else {
137 0           $cdbdoc->data({data=>$data});
138 0           $cdbdoc->create;
139             }
140 0           return $cdbdoc->data->{"data"};
141             }
142              
143             =head2 retrieve
144              
145             my $data=$s->retrieve('doc'); #undef if not exists (but you can also store undef)
146              
147             =cut
148              
149             sub retrieve {
150 0     0 1   my $self=shift;
151 0 0         die("Error: Wrong number of arguments.") unless @_ == 1;
152 0           my $doc=shift;
153 0 0         die("Error: Document name must be defined.") unless defined $doc;
154 0 0         if ($self->_db->docExists($doc)) {
155 0           my $cdbdoc=$self->_db->newDoc($doc); #isa CouchDB::Client::Doc
156 0           $cdbdoc->retrieve;
157 0           return $cdbdoc->data->{"data"}; #This may also be undef
158             } else {
159 0           return undef;
160             }
161             }
162              
163             =head2 delete
164              
165             $s->delete('doc');
166              
167             my $data=$s->delete('doc'); #returns value from database just before delete
168              
169             =cut
170              
171             sub delete {
172 0     0 1   my $self=shift;
173 0 0         die("Error: Wrong number of arguments.") unless @_ == 1;
174 0           my $doc=shift;
175 0 0         die("Error: Document name must be defined.") unless defined $doc;
176 0 0         if ($self->_db->docExists($doc)) {
177 0           my $cdbdoc=$self->_db->newDoc($doc); #isa CouchDB::Client::Doc
178 0           $cdbdoc->retrieve; #to get revision number for object
179 0           my $data=$cdbdoc->data->{"data"}; #since we already have the data
180 0           $cdbdoc->delete;
181 0           return $data; #return what we deleted
182             } else {
183 0           return undef;
184             }
185             }
186              
187             =head1 METHODS (Properties)
188              
189             =cut
190              
191             sub _client { #isa CouchDB::Client
192 0     0     my $self=shift;
193 0 0         unless (defined $self->{"_client"}) {
194 0           $self->{"_client"}=CouchDB::Client->new(uri=>$self->uri);
195 0 0         $self->{"_client"}->testConnection or die("Error: CouchDB Server Unavailable");
196             }
197 0           return $self->{"_client"};
198             }
199              
200             sub _db { #isa CouchDB::Client::DB
201 0     0     my $self=shift;
202 0 0         unless (defined $self->{"_db"}) {
203 0           $self->{"_db"}=$self->_client->newDB($self->db);
204 0 0         $self->{"_db"}->create unless $self->_client->dbExists($self->db);
205             }
206 0           return $self->{"_db"};
207             }
208              
209             =head2 db
210              
211             Sets and retrieves the Apache CouchDB database name.
212              
213             Default: perl-storable-couchdb
214              
215             Limitation: Only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.
216              
217             =cut
218              
219             sub db {
220 0     0 1   my $self=shift;
221 0 0         $self->{"db"}=shift if @_;
222 0 0         $self->{"db"}='perl-storable-couchdb' unless defined $self->{"db"};
223 0           return $self->{"db"};
224             }
225              
226             =head2 uri
227              
228             URI of the Apache CouchDB server
229              
230             Default: http://127.0.0.1:5984/
231              
232             =cut
233              
234             sub uri {
235 0     0 1   my $self=shift;
236 0 0         $self->{"uri"}=shift if @_;
237 0 0         $self->{"uri"}='http://127.0.0.1:5984/' unless defined $self->{"uri"};
238 0           return $self->{"uri"};
239             }
240              
241             =head1 LIMITATIONS
242              
243             All I need this package for storing ASCII values so currently this package meets my requirements. But, I would like to add blessed object support. I will gladly accept patches!
244              
245             This package relies heavily on L to do the right thing. So far, I have not had any compliants other than a slightly awkard interface.
246              
247             =head1 BUGS
248              
249             Please log on RT and send an email to the author.
250              
251             =head1 SUPPORT
252              
253             DavisNetworks.com supports all Perl applications including this package.
254              
255             =head1 AUTHOR
256              
257             Michael R. Davis
258             CPAN ID: MRDVT
259             Satellite Tracking of People, LLC
260             mrdvt92
261             http://www.davisnetworks.com/
262              
263             =head1 COPYRIGHT
264              
265             Copyright (c) 2011 Michael R. Davis - MRDVT
266              
267             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
268              
269             The full text of the license can be found in the LICENSE file included with this module.
270              
271             =head1 SEE ALSO
272              
273             L, L, Apache CouchDB http://couchdb.apache.org/
274              
275             =cut
276              
277             1;