- Timestamp:
- 09/02/08 21:43:53 (5 years ago)
- Location:
- lang/perl/CouchDB-Object/trunk
- Files:
-
- 7 added
- 3 removed
- 10 modified
- 1 moved
-
Makefile.PL (modified) (2 diffs)
-
lib/CouchDB/Object.pm (modified) (3 diffs)
-
lib/CouchDB/Object/Database.pm (modified) (7 diffs)
-
lib/CouchDB/Object/Document.pm (modified) (2 diffs)
-
lib/CouchDB/Object/Documents.pm (modified) (3 diffs)
-
lib/CouchDB/Object/Response.pm (modified) (2 diffs)
-
lib/CouchDB/Object/Role (added)
-
lib/CouchDB/Object/Role/Client.pm (added)
-
lib/CouchDB/Object/Server.pm (deleted)
-
lib/CouchDB/Object/UserAgent.pm (modified) (3 diffs)
-
lib/CouchDB/Object/Utils.pm (deleted)
-
t/01_server.t (modified) (1 diff)
-
t/02_database.t (modified) (2 diffs)
-
t/03_document.t (deleted)
-
t/03_save_doc.t (added)
-
t/04_open_doc.t (added)
-
t/05_remove_doc.t (added)
-
t/06_all_docs.t (moved) (moved from lang/perl/CouchDB-Object/trunk/t/04_all_docs.t) (1 diff)
-
t/07_query.t (added)
-
t/CouchDB.pm (modified) (1 diff)
-
t/docs.json (added)
Legend:
- Unmodified
- Added
- Removed
-
lang/perl/CouchDB-Object/trunk/Makefile.PL
r18195 r18660 6 6 requires 'MooseX::AttributeHelpers'; 7 7 requires 'MooseX::Types::URI'; 8 requires 'Class::Inspector'; 9 requires 'Exporter'; 8 requires 'Data::Dump::Streamer'; 10 9 requires 'Hash::AsObject'; 11 10 requires 'Hash::Merge'; 12 requires 'HTTP:: Request::Common' => 5.814; # for DELETE13 requires 'HTTP::Re sponse';11 requires 'HTTP::Headers'; 12 requires 'HTTP::Request'; 14 13 requires 'JSON::XS'; 15 14 requires 'LWP::UserAgent'; … … 20 19 21 20 test_requires 'Test::More'; 21 test_requires 'JSON::XS'; 22 22 test_requires 'String::Random'; 23 test_requires 'String::TT'; 24 test_requires 'URI'; 25 23 26 use_test_base; 24 27 auto_include; -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object.pm
r17845 r18660 1 1 package CouchDB::Object; 2 2 3 use strict; 4 use warnings; 3 use Moose; 4 use URI; 5 use CouchDB::Object::Database; 6 7 with 'CouchDB::Object::Role::Client'; 8 9 has 'scheme' => (is => 'rw', isa => 'Str', default => sub { 'http' }); 10 has 'host' => (is => 'rw', isa => 'Str', default => sub { 'localhost' }); 11 has 'port' => (is => 'rw', isa => 'Num', default => sub { 5984 }); 12 13 no Moose; 5 14 6 15 our $VERSION = '0.01'; 16 17 sub uri { 18 my $self = shift; 19 return URI->new(sprintf '%s://%s:%d/', $self->scheme, $self->host, $self->port); 20 } 21 22 sub db { 23 my ($self, $name) = @_; 24 return CouchDB::Object::Database->new( 25 name => $name, 26 server => $self->uri, 27 agent => $self->agent, 28 ); 29 } 30 31 sub all_dbs { 32 my ($self, $args) = @_; 33 34 my $res = $self->request(GET => $self->uri_for('_all_dbs')); 35 return $self->ping ? map { $self->db($_) } @{ $res->parsed_content } : (); 36 } 37 38 sub info { 39 my $self = shift; 40 return $self->request(GET => $self->uri); 41 } 42 43 sub ping { 44 my $self = shift; 45 return eval { $self->info->is_success }; 46 } 47 48 sub replicate { 49 # TODO: implements 50 } 51 52 __PACKAGE__->meta->make_immutable; 7 53 8 54 1; … … 11 57 12 58 CouchDB::Object - Yet another CouchDB client 59 60 =head1 SYNOPSIS 61 62 use CouchDB::Object; 63 64 my $couch = CouchDB::Object->new(host => 'localhost', port => 5984); 65 66 if ($couch->ping) { 67 print "connect CouchDB"; 68 69 my $db = $couch->db('dbname'); 70 my @dbs = $couch->all_dbs; 71 } 72 73 =head1 METHODS 74 75 =head2 new(host => $host, port => $port [, scheme => $scheme ]) 76 77 Returns the CouchDB server object. 78 79 =head2 ping 80 81 Returns true if a connection can be made to the server, false otherwise. 82 83 =head2 db($dbname) 84 85 Returns the L<CouchDB::Object::Database> object of that name. 86 87 =head2 all_dbs 88 89 Returns L<CouchDB::Object::Database> objects that the server knows of. 90 91 =head2 info 92 93 Returns the L<CouchDB::Object::Response> object for server. 94 95 =head2 replicate 96 97 Not implemented yet. 13 98 14 99 =head1 AUTHOR … … 23 108 =head1 SEE ALSO 24 109 25 L<CouchDB::Object:: Server>, L<CouchDB::Object::Database>110 L<CouchDB::Object::Database>, L<CouchDB::Object::Response> 26 111 27 112 =cut -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Database.pm
r18195 r18660 3 3 use Moose; 4 4 use MooseX::Types::URI qw(Uri); 5 use CouchDB::Object; 6 use CouchDB::Object::UserAgent; 7 use CouchDB::Object::Utils qw(uri_for); 5 use Data::Dump::Streamer; 6 use HTTP::Headers; 7 use JSON::XS (); 8 use URI::Escape qw(uri_escape_utf8); 9 10 with 'CouchDB::Object::Role::Client'; 8 11 9 12 has 'name' => ( 10 is => 'r o',13 is => 'rw', 11 14 isa => 'Str', 12 15 required => 1, 13 16 ); 14 17 15 has ' uri' => (16 is => 'r o',18 has 'server' => ( 19 is => 'rw', 17 20 isa => Uri, 18 21 coerce => 1, … … 20 23 ); 21 24 22 has 'agent' => (23 is => 'ro',24 isa => 'CouchDB::Object::UserAgent',25 required => 1,26 default => sub { CouchDB::Object::UserAgent->new },27 );28 29 25 no Moose; 30 26 31 our $VERSION = CouchDB::Object->VERSION;27 our $VERSION = '0.01'; 32 28 33 sub BUILD { 34 my ($self, $args) = @_; 35 $self->uri->$_(undef) for qw(query fragment); 29 sub uri { 30 my $self = shift; 31 32 my $uri = $self->server->clone; 33 $uri->path_segments($self->name, ''); 34 $uri->canonical; 36 35 } 37 36 38 37 sub create { 39 38 my $self = shift; 40 return $self-> agent->put($self->uri);39 return $self->request(PUT => $self->uri); 41 40 } 42 41 43 42 sub drop { 44 43 my $self = shift; 45 return $self-> agent->delete($self->uri);44 return $self->request(DELETE => $self->uri); 46 45 } 47 46 48 47 sub info { 49 48 my $self = shift; 50 return $self-> agent->get($self->uri);49 return $self->request(GET => $self->uri); 51 50 } 52 51 … … 57 56 sub all_docs { 58 57 my ($self, $args) = @_; 59 return $self-> agent->get($self->uri_for('_all_docs', $args));58 return $self->request(GET => $self->uri_for('_all_docs', $args)); 60 59 } 61 60 62 61 sub open_doc { 63 62 my ($self, $id, $args) = @_; 64 return $self-> agent->get($self->uri_for($id, $args));63 return $self->request(GET => $self->uri_for($id, $args)); 65 64 } 66 65 … … 68 67 my ($self, $doc, $args) = @_; 69 68 70 my $agent = $self->agent; 71 my $content = $doc->to_json; 72 my $res = $doc->has_id 73 ? $agent->put($self->uri_for($doc->id), Content => $content) 74 : $agent->post($self->uri, Content => $content); 69 my $header = HTTP::Headers->new('Content-Type' => 'application/json'); 70 my $res = $doc->has_id 71 ? $self->request(PUT => $self->uri_for($doc->id), $header, $doc->to_json) 72 : $self->request(POST => $self->uri, $header, $doc->to_json); 75 73 76 74 # merge … … 90 88 91 89 my $params = { rev => $doc->rev, %{ $args || {} } }; 92 return $self-> agent->delete($self->uri_for($doc->id, $params));90 return $self->request(DELETE => $self->uri_for($doc->id, $params)); 93 91 } 94 92 … … 98 96 99 97 sub query { 100 # TODO: implements 98 my ($self, $map, $reduce, $lang, $args) = @_; 99 100 my $body = { 101 language => $lang || (ref $map eq 'CODE') ? 'text/perl' : 'javascript', 102 map => _code2str($map), 103 }; 104 $body->{reduce} = _code2str($reduce) if defined $reduce; 105 $body = JSON::XS->new->encode($body); 106 107 my $header = HTTP::Headers->new('Content-Type' => 'application/json'); 108 return $self->request(POST => $self->uri_for('_temp_view', $args), $header, $body); 101 109 } 102 110 103 111 sub view { 104 112 # TODO: implements 113 } 114 115 # from CouchDB::View::Document 116 sub _code2str { 117 ref $_[0] 118 ? sprintf 'do { my $CODE1; %s; $CODE1 }', Data::Dump::Streamer->new->Data($_[0])->Out 119 : $_[0]; 105 120 } 106 121 … … 117 132 =head1 METHODS 118 133 119 =head2 new(name => $dbname, uri=> $uri)134 =head2 new(name => $dbname, server => $uri) 120 135 121 136 Returns the L<CouchDB::Object::Database> object -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Document.pm
r18195 r18660 5 5 use Hash::Merge (); 6 6 use JSON::XS (); 7 use CouchDB::Object;8 7 9 8 has 'id' => ( … … 28 27 no Moose; 29 28 30 our $VERSION = CouchDB::Object->VERSION;29 our $VERSION = '0.01'; 31 30 32 31 sub new_from_json { -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Documents.pm
r18195 r18660 3 3 use Moose; 4 4 use MooseX::AttributeHelpers; 5 use CouchDB::Object;6 5 use CouchDB::Object::Document; 7 6 … … 28 27 no Moose; 29 28 30 our $VERSION = CouchDB::Object->VERSION;29 our $VERSION = '0.01'; 31 30 32 31 sub new_from_json { … … 46 45 ); 47 46 } 47 48 sub all { shift->docs } # readonly 48 49 49 50 __PACKAGE__->meta->make_immutable; -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Response.pm
r18195 r18660 5 5 use Hash::AsObject; 6 6 use JSON::XS (); 7 use CouchDB::Object;8 7 use CouchDB::Object::Document; 9 8 use CouchDB::Object::Documents; … … 36 35 no Moose; 37 36 38 our $VERSION = CouchDB::Object->VERSION;37 our $VERSION = '0.01'; 39 38 40 39 sub new_from_response { -
lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/UserAgent.pm
r17939 r18660 2 2 3 3 use Moose; 4 use HTTP::Request::Common 5.814 qw(PUT DELETE);5 4 use CouchDB::Object; 6 use CouchDB::Object::Response;7 5 8 6 extends 'LWP::UserAgent'; … … 10 8 no Moose; 11 9 12 our $VERSION = CouchDB::Object->VERSION;10 our $VERSION = '0.01'; 13 11 14 12 sub BUILD { … … 26 24 $req->header(Content_Type => 'application/json') if $req->content; 27 25 28 my $res = $self->SUPER::request($req); 29 return CouchDB::Object::Response->new_from_response($res); 30 } 31 32 sub put { 33 my ($self, @params) = @_; 34 my @suff = $self->_process_colonic_headers(\@params, ref $params[1] ? 2 : 1); 35 return $self->request(PUT(@params), @suff); 36 } 37 38 sub delete { 39 my ($self, @params) = @_; 40 my @suff = $self->_process_colonic_headers(\@params, 1); 41 return $self->request(DELETE(@params), @suff); 26 # TODO: super() 27 return $self->SUPER::request($req); 42 28 } 43 29 -
lang/perl/CouchDB-Object/trunk/t/01_server.t
r17771 r18660 2 2 use t::CouchDB; 3 3 4 my $server = server(); 5 my $couch = CouchDB::Object::Server->new(uri => $server); 4 my $couch = test_couch(); 6 5 7 plan skip_all => "Can't connect CouchDB server: $server" unless $couch->ping; 8 plan tests => 3 if $couch->ping; 6 unless ($couch->ping) { 7 plan skip_all => "Can't connect CouchDB server: " . test_server(); 8 } 9 else { 10 plan tests => 2; 11 } 9 12 10 # server info 11 is $couch->uri => $server; 12 ok $couch->info->is_success; 13 14 # replicate 15 TODO: { 16 local $TODO = 'replicate(): not implemented yet'; 17 ok $couch->replicate; 18 }; 13 is $couch->uri => test_server(); 14 isa_ok $couch->db(test_dbname()) => 'CouchDB::Object::Database'; -
lang/perl/CouchDB-Object/trunk/t/02_database.t
r17771 r18660 2 2 use t::CouchDB; 3 3 4 my $server = server(); 5 my $couch = CouchDB::Object::Server->new(uri => $server); 4 my $couch = test_couch(); 6 5 7 plan skip_all => "Can't connect CouchDB server: $server" unless $couch->ping; 8 plan tests => 7 if $couch->ping; 6 unless ($couch->ping) { 7 plan skip_all => "Can't connect CouchDB server: " . test_server(); 8 } 9 else { 10 plan tests => 7; 11 } 9 12 10 my $name = random_name(); 11 my $uri = $server . $name; 12 my $db = $couch->db($name); 13 my $server = test_server(); 14 my $name = test_dbname(); 13 15 14 # info 15 is $db->name => $name; 16 is $db->uri => $uri; 16 my $uri = $server->clone; 17 $uri->path_segments($name, ''); 18 19 my $db = CouchDB::Object::Database->new(name => $name, server => $server); 20 21 is $db->uri => $uri; 17 22 18 23 # create … … 20 25 ok $db->create->is_success; # 201 21 26 ok $db->info->is_success; # 200 27 is $db->info->content->db_name => $name; 22 28 23 29 # drop -
lang/perl/CouchDB-Object/trunk/t/06_all_docs.t
r18195 r18660 2 2 use t::CouchDB; 3 3 4 my $server = server(); 5 my $couch = CouchDB::Object::Server->new(uri => $server); 4 my $couch = test_couch(); 6 5 7 plan skip_all => "Can't connect CouchDB server: $server" unless $couch->ping; 8 plan tests => 22 if $couch->ping; 9 10 my $dbname = random_name(); 11 my $dburi = $server . $dbname; 12 13 my $db = $couch->db($dbname); 14 $db->create; 15 END { 16 $db->drop if $couch->ping; 6 unless ($couch->ping) { 7 plan skip_all => "Can't connect CouchDB server: " . test_server(); 8 } 9 else { 10 plan tests => 24; 17 11 } 18 12 19 my @docs = (); 20 for (1..5) { 21 my $doc = CouchDB::Object::Document->new; 22 $doc->id(sprintf '%03d', $_); 23 $db->save_doc($doc); 24 push @docs, $doc; 13 my ($name, $db) = deploy_db(); 14 END { $db->drop if $couch->ping } 15 16 { 17 my $res = $db->all_docs; 18 ok $res->is_success; 19 20 my $docs = $res->to_document; 21 is $docs->total_docs => 5; 22 is $docs->offset => 0; 23 24 is $docs->count => 5; 25 for my $doc ($docs->all) { # 2 x 5 = 10 26 ok $doc->id; 27 ok $doc->rev; 28 } 25 29 } 26 30 27 my $all_docs = $db->all_docs->to_document; 28 is $all_docs->total_docs => 5; 29 is $all_docs->count => 5; 30 is $all_docs->offset => 0; 31 my @all_docs = $all_docs->docs; 32 for (0..4) { 33 is $all_docs[$_]->id, $docs[$_]->id; 34 is $all_docs[$_]->rev, $docs[$_]->rev; 31 { 32 my $res = $db->all_docs({ count => 3 }); 33 ok $res->is_success; 34 35 my $docs = $res->to_document; 36 is $docs->total_docs => 5; 37 is $docs->offset => 0; 38 39 is $docs->count => 3; 40 for my $doc ($docs->all) { # 2 x 3 = 6 41 ok $doc->id; 42 ok $doc->rev; 43 } 35 44 } 36 37 my $counted_docs = $db->all_docs({ count => 3 })->to_document;38 is $counted_docs->total_docs => 5;39 is $counted_docs->count => 3;40 is $counted_docs->offset => 0;41 my @counted_docs = $counted_docs->docs;42 for (0..2) {43 is $counted_docs[$_]->id, $docs[$_]->id;44 is $counted_docs[$_]->rev, $docs[$_]->rev;45 } -
lang/perl/CouchDB-Object/trunk/t/CouchDB.pm
r17771 r18660 1 1 package t::CouchDB; 2 2 3 use strict; 3 4 use Test::Base -Base; 4 use String::Random; 5 use CouchDB::Object::Server; 6 use CouchDB::Object::Database; 5 use JSON::XS (); 6 use String::Random (); 7 use URI; 8 use CouchDB::Object; 7 9 use CouchDB::Object::Document; 8 10 9 our @EXPORT = qw( server random_name);11 our @EXPORT = qw(test_server test_dbname test_couch deploy_db); 10 12 11 sub server {12 my $ server = $ENV{TEST_COUCHDB} || 'http://localhost:5984/';13 $ server =~ s{(?<!/)$}{/};14 $ server;13 sub test_server { 14 my $uri = URI->new($ENV{TEST_COUCHDB} || 'http://localhost:5984/'); 15 $uri->path('/'); 16 $uri; 15 17 } 16 18 17 sub random_name {19 sub test_dbname { 18 20 String::Random->new->randregex('[a-z]{20}'); 19 21 } 20 22 23 sub test_couch { 24 my $uri = test_server(); 25 CouchDB::Object->new(scheme => $uri->scheme, host => $uri->host, port => $uri->port); 26 } 27 28 sub deploy_db { 29 my $couch = test_couch(); 30 my $name = test_dbname(); 31 32 my $db = $couch->db($name); 33 $db->create; 34 35 my $data = do { 36 open my $fh, '<', 't/docs.json' or die $!; 37 local $/; <$fh>; 38 }; 39 my $json = JSON::XS->new->decode($data); 40 for (@$json) { 41 my $doc = CouchDB::Object::Document->new; 42 $doc->id(delete $_->{id}); 43 while (my ($key, $value) = each %$_) { 44 $doc->$key($value); 45 } 46 $db->save_doc($doc); 47 } 48 49 ($name, $db); 50 } 51 21 52 1;
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)