Changeset 18660 for lang/perl

Show
Ignore:
Timestamp:
09/02/08 21:43:53 (5 years ago)
Author:
masaki
Message:

Database#query 追加,テストも追加,Utils やめて Role にした

Location:
lang/perl/CouchDB-Object/trunk
Files:
7 added
3 removed
10 modified
1 moved

Legend:

Unmodified
Added
Removed
  • lang/perl/CouchDB-Object/trunk/Makefile.PL

    r18195 r18660  
    66requires 'MooseX::AttributeHelpers'; 
    77requires 'MooseX::Types::URI'; 
    8 requires 'Class::Inspector'; 
    9 requires 'Exporter'; 
     8requires 'Data::Dump::Streamer'; 
    109requires 'Hash::AsObject'; 
    1110requires 'Hash::Merge'; 
    12 requires 'HTTP::Request::Common' => 5.814; # for DELETE 
    13 requires 'HTTP::Response'; 
     11requires 'HTTP::Headers'; 
     12requires 'HTTP::Request'; 
    1413requires 'JSON::XS'; 
    1514requires 'LWP::UserAgent'; 
     
    2019 
    2120test_requires 'Test::More'; 
     21test_requires 'JSON::XS'; 
    2222test_requires 'String::Random'; 
     23test_requires 'String::TT'; 
     24test_requires 'URI'; 
     25 
    2326use_test_base; 
    2427auto_include; 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object.pm

    r17845 r18660  
    11package CouchDB::Object; 
    22 
    3 use strict; 
    4 use warnings; 
     3use Moose; 
     4use URI; 
     5use CouchDB::Object::Database; 
     6 
     7with 'CouchDB::Object::Role::Client'; 
     8 
     9has 'scheme' => (is => 'rw', isa => 'Str', default => sub { 'http' }); 
     10has 'host'   => (is => 'rw', isa => 'Str', default => sub { 'localhost' }); 
     11has 'port'   => (is => 'rw', isa => 'Num', default => sub { 5984 }); 
     12 
     13no Moose; 
    514 
    615our $VERSION = '0.01'; 
     16 
     17sub uri { 
     18    my $self = shift; 
     19    return URI->new(sprintf '%s://%s:%d/', $self->scheme, $self->host, $self->port); 
     20} 
     21 
     22sub 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 
     31sub 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 
     38sub info { 
     39    my $self = shift; 
     40    return $self->request(GET => $self->uri); 
     41} 
     42 
     43sub ping { 
     44    my $self = shift; 
     45    return eval { $self->info->is_success }; 
     46} 
     47 
     48sub replicate { 
     49    # TODO: implements 
     50} 
     51 
     52__PACKAGE__->meta->make_immutable; 
    753 
    8541; 
     
    1157 
    1258CouchDB::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 
     77Returns the CouchDB server object. 
     78 
     79=head2 ping 
     80 
     81Returns true if a connection can be made to the server, false otherwise. 
     82 
     83=head2 db($dbname) 
     84 
     85Returns the L<CouchDB::Object::Database> object of that name. 
     86 
     87=head2 all_dbs 
     88 
     89Returns L<CouchDB::Object::Database> objects that the server knows of. 
     90 
     91=head2 info 
     92 
     93Returns the L<CouchDB::Object::Response> object for server. 
     94 
     95=head2 replicate 
     96 
     97Not implemented yet. 
    1398 
    1499=head1 AUTHOR 
     
    23108=head1 SEE ALSO 
    24109 
    25 L<CouchDB::Object::Server>, L<CouchDB::Object::Database> 
     110L<CouchDB::Object::Database>, L<CouchDB::Object::Response> 
    26111 
    27112=cut 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Database.pm

    r18195 r18660  
    33use Moose; 
    44use MooseX::Types::URI qw(Uri); 
    5 use CouchDB::Object; 
    6 use CouchDB::Object::UserAgent; 
    7 use CouchDB::Object::Utils qw(uri_for); 
     5use Data::Dump::Streamer; 
     6use HTTP::Headers; 
     7use JSON::XS (); 
     8use URI::Escape qw(uri_escape_utf8); 
     9 
     10with 'CouchDB::Object::Role::Client'; 
    811 
    912has 'name' => ( 
    10     is       => 'ro', 
     13    is       => 'rw', 
    1114    isa      => 'Str', 
    1215    required => 1, 
    1316); 
    1417 
    15 has 'uri' => ( 
    16     is       => 'ro', 
     18has 'server' => ( 
     19    is       => 'rw', 
    1720    isa      => Uri, 
    1821    coerce   => 1, 
     
    2023); 
    2124 
    22 has 'agent' => ( 
    23     is       => 'ro', 
    24     isa      => 'CouchDB::Object::UserAgent', 
    25     required => 1, 
    26     default  => sub { CouchDB::Object::UserAgent->new }, 
    27 ); 
    28  
    2925no Moose; 
    3026 
    31 our $VERSION = CouchDB::Object->VERSION; 
     27our $VERSION = '0.01'; 
    3228 
    33 sub BUILD { 
    34     my ($self, $args) = @_; 
    35     $self->uri->$_(undef) for qw(query fragment); 
     29sub uri { 
     30    my $self = shift; 
     31 
     32    my $uri = $self->server->clone; 
     33    $uri->path_segments($self->name, ''); 
     34    $uri->canonical; 
    3635} 
    3736 
    3837sub create { 
    3938    my $self = shift; 
    40     return $self->agent->put($self->uri); 
     39    return $self->request(PUT => $self->uri); 
    4140} 
    4241 
    4342sub drop { 
    4443    my $self = shift; 
    45     return $self->agent->delete($self->uri); 
     44    return $self->request(DELETE => $self->uri); 
    4645} 
    4746 
    4847sub info { 
    4948    my $self = shift; 
    50     return $self->agent->get($self->uri); 
     49    return $self->request(GET => $self->uri); 
    5150} 
    5251 
     
    5756sub all_docs { 
    5857    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)); 
    6059} 
    6160 
    6261sub open_doc { 
    6362    my ($self, $id, $args) = @_; 
    64     return $self->agent->get($self->uri_for($id, $args)); 
     63    return $self->request(GET => $self->uri_for($id, $args)); 
    6564} 
    6665 
     
    6867    my ($self, $doc, $args) = @_; 
    6968 
    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); 
    7573 
    7674    # merge 
     
    9088 
    9189    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)); 
    9391} 
    9492 
     
    9896 
    9997sub 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); 
    101109} 
    102110 
    103111sub view { 
    104112    # TODO: implements 
     113} 
     114 
     115# from CouchDB::View::Document 
     116sub _code2str { 
     117    ref $_[0] 
     118        ? sprintf 'do { my $CODE1; %s; $CODE1 }', Data::Dump::Streamer->new->Data($_[0])->Out 
     119        : $_[0]; 
    105120} 
    106121 
     
    117132=head1 METHODS 
    118133 
    119 =head2 new(name => $dbname, uri => $uri) 
     134=head2 new(name => $dbname, server => $uri) 
    120135 
    121136Returns the L<CouchDB::Object::Database> object 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Document.pm

    r18195 r18660  
    55use Hash::Merge (); 
    66use JSON::XS (); 
    7 use CouchDB::Object; 
    87 
    98has 'id' => ( 
     
    2827no Moose; 
    2928 
    30 our $VERSION = CouchDB::Object->VERSION; 
     29our $VERSION = '0.01'; 
    3130 
    3231sub new_from_json { 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Documents.pm

    r18195 r18660  
    33use Moose; 
    44use MooseX::AttributeHelpers; 
    5 use CouchDB::Object; 
    65use CouchDB::Object::Document; 
    76 
     
    2827no Moose; 
    2928 
    30 our $VERSION = CouchDB::Object->VERSION; 
     29our $VERSION = '0.01'; 
    3130 
    3231sub new_from_json { 
     
    4645    ); 
    4746} 
     47 
     48sub all { shift->docs } # readonly 
    4849 
    4950__PACKAGE__->meta->make_immutable; 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/Response.pm

    r18195 r18660  
    55use Hash::AsObject; 
    66use JSON::XS (); 
    7 use CouchDB::Object; 
    87use CouchDB::Object::Document; 
    98use CouchDB::Object::Documents; 
     
    3635no Moose; 
    3736 
    38 our $VERSION = CouchDB::Object->VERSION; 
     37our $VERSION = '0.01'; 
    3938 
    4039sub new_from_response { 
  • lang/perl/CouchDB-Object/trunk/lib/CouchDB/Object/UserAgent.pm

    r17939 r18660  
    22 
    33use Moose; 
    4 use HTTP::Request::Common 5.814 qw(PUT DELETE); 
    54use CouchDB::Object; 
    6 use CouchDB::Object::Response; 
    75 
    86extends 'LWP::UserAgent'; 
     
    108no Moose; 
    119 
    12 our $VERSION = CouchDB::Object->VERSION; 
     10our $VERSION = '0.01'; 
    1311 
    1412sub BUILD { 
     
    2624    $req->header(Content_Type => 'application/json') if $req->content; 
    2725 
    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); 
    4228} 
    4329 
  • lang/perl/CouchDB-Object/trunk/t/01_server.t

    r17771 r18660  
    22use t::CouchDB; 
    33 
    4 my $server = server(); 
    5 my $couch  = CouchDB::Object::Server->new(uri => $server); 
     4my $couch = test_couch(); 
    65 
    7 plan skip_all => "Can't connect CouchDB server: $server" unless $couch->ping; 
    8 plan tests => 3 if $couch->ping; 
     6unless ($couch->ping) { 
     7    plan skip_all => "Can't connect CouchDB server: " . test_server(); 
     8} 
     9else { 
     10    plan tests => 2; 
     11} 
    912 
    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 }; 
     13is $couch->uri => test_server(); 
     14isa_ok $couch->db(test_dbname()) => 'CouchDB::Object::Database'; 
  • lang/perl/CouchDB-Object/trunk/t/02_database.t

    r17771 r18660  
    22use t::CouchDB; 
    33 
    4 my $server = server(); 
    5 my $couch  = CouchDB::Object::Server->new(uri => $server); 
     4my $couch = test_couch(); 
    65 
    7 plan skip_all => "Can't connect CouchDB server: $server" unless $couch->ping; 
    8 plan tests => 7 if $couch->ping; 
     6unless ($couch->ping) { 
     7    plan skip_all => "Can't connect CouchDB server: " . test_server(); 
     8} 
     9else { 
     10    plan tests => 7; 
     11} 
    912 
    10 my $name = random_name(); 
    11 my $uri  = $server . $name; 
    12 my $db   = $couch->db($name); 
     13my $server = test_server(); 
     14my $name   = test_dbname(); 
    1315 
    14 # info 
    15 is $db->name => $name; 
    16 is $db->uri  => $uri; 
     16my $uri = $server->clone; 
     17$uri->path_segments($name, ''); 
     18 
     19my $db = CouchDB::Object::Database->new(name => $name, server => $server); 
     20 
     21is $db->uri => $uri; 
    1722 
    1823# create 
     
    2025ok $db->create->is_success; # 201 
    2126ok $db->info->is_success;   # 200 
     27is $db->info->content->db_name => $name; 
    2228 
    2329# drop 
  • lang/perl/CouchDB-Object/trunk/t/06_all_docs.t

    r18195 r18660  
    22use t::CouchDB; 
    33 
    4 my $server = server(); 
    5 my $couch  = CouchDB::Object::Server->new(uri => $server); 
     4my $couch = test_couch(); 
    65 
    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; 
     6unless ($couch->ping) { 
     7    plan skip_all => "Can't connect CouchDB server: " . test_server(); 
     8} 
     9else { 
     10    plan tests => 24; 
    1711} 
    1812 
    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; 
     13my ($name, $db) = deploy_db(); 
     14END { $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    } 
    2529} 
    2630 
    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    } 
    3544} 
    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  
    11package t::CouchDB; 
    22 
     3use strict; 
    34use Test::Base -Base; 
    4 use String::Random; 
    5 use CouchDB::Object::Server; 
    6 use CouchDB::Object::Database; 
     5use JSON::XS (); 
     6use String::Random (); 
     7use URI; 
     8use CouchDB::Object; 
    79use CouchDB::Object::Document; 
    810 
    9 our @EXPORT = qw(server random_name); 
     11our @EXPORT = qw(test_server test_dbname test_couch deploy_db); 
    1012 
    11 sub server { 
    12     my $server = $ENV{TEST_COUCHDB} || 'http://localhost:5984/'; 
    13     $server =~ s{(?<!/)$}{/}; 
    14     $server; 
     13sub test_server { 
     14    my $uri = URI->new($ENV{TEST_COUCHDB} || 'http://localhost:5984/'); 
     15    $uri->path('/'); 
     16    $uri; 
    1517} 
    1618 
    17 sub random_name { 
     19sub test_dbname { 
    1820    String::Random->new->randregex('[a-z]{20}'); 
    1921} 
    2022 
     23sub test_couch { 
     24    my $uri = test_server(); 
     25    CouchDB::Object->new(scheme => $uri->scheme, host => $uri->host, port => $uri->port); 
     26} 
     27 
     28sub 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 
    21521;