File Coverage

blib/lib/KiokuDB/Backend/MongoDB.pm
Criterion Covered Total %
statement 2 4 50.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 4 6 66.6


line stmt bran cond sub pod time code
1             package KiokuDB::Backend::MongoDB;
2             BEGIN {
3 1     1   37682 $KiokuDB::Backend::MongoDB::VERSION = '0.03';
4             }
5 1     1   461 use Moose;
  0            
  0            
6              
7             use namespace::clean -except => 'meta';
8              
9             with qw(
10             KiokuDB::Backend
11             KiokuDB::Backend::Serialize::JSPON
12             KiokuDB::Backend::Role::Clear
13             KiokuDB::Backend::Role::Scan
14             KiokuDB::Backend::Role::Query::Simple
15             KiokuDB::Backend::Role::Query
16             );
17              
18             use MongoDB::Connection; # In case we are expected to create the connection
19             use Data::Stream::Bulk::Callback ();
20              
21             has [qw/database_name database_host database_port collection_name/] => (
22             is => 'ro',
23             isa => 'Str',
24             );
25              
26             has collection => (
27             isa => 'MongoDB::Collection',
28             is => 'ro',
29             lazy => 1,
30             builder => '_build_collection',
31             );
32              
33             has '+id_field' => ( default => "_id" );
34             has '+class_field' => ( default => "class" );
35             has '+class_meta_field' => ( default => "class_meta" );
36              
37             sub _build_collection {
38             my ($self) = @_;
39             my $host = $self->database_host || 'localhost';
40             my $port = $self->database_port || 27017;
41             die "collection_name required" unless $self->collection_name;
42             my $conn = MongoDB::Connection->new(host => $host, port => $port);
43             return $conn->get_database($self->database_name)->get_collection($self->collection_name);
44             }
45              
46             sub BUILD {
47             my ($self) = @_;
48             $self->collection;
49             }
50              
51             sub clear {
52             my $self = shift;
53             $self->collection->drop;
54             }
55              
56             sub all_entries {
57             my $self = shift;
58             return $self->_proto_search({});
59             }
60              
61             sub insert {
62             my ($self, @entries) = @_;
63              
64             my $coll = $self->collection;
65              
66             for my $entry (@entries) {
67             my $collapsed = $self->serialize($entry);
68             if ($entry->prev) {
69             $coll->update({ _id => $collapsed->{_id} }, $collapsed);
70             my $err = $coll->_database->run_command({getlasterror => 1});
71             die $err->{err} if $err->{err};
72             }
73             else {
74             $coll->insert($collapsed);
75             my $err = $coll->_database->run_command({getlasterror => 1});
76             die $err->{err} if $err->{err};
77             }
78             }
79             return;
80             }
81              
82             sub get {
83             my ($self, @ids) = @_;
84             return map {
85             $self->get_entry($_)
86             } @ids;
87             }
88              
89             sub get_entry {
90             my ($self, $id) = @_;
91             my $obj = eval { $self->collection->find_one({ _id => $id }); };
92             return undef unless $obj;
93             return $self->deserialize($obj);
94             }
95              
96             sub delete {
97             my ($self, @ids_or_entries) = @_;
98             for my $id (map { $_->isa('KiokuDB::Entry') ? $_->id : $_ } @ids_or_entries)
99             {
100             $self->collection->remove({_id => $id});
101             }
102             return;
103             }
104              
105             sub exists {
106             my ($self, @ids) = @_;
107             my $coll = $self->collection;
108             return map { $coll->find_one({ _id => $_ }) } @ids;
109             # $self->get(@ids);
110             }
111              
112             sub simple_search {
113             my ($self, $proto) = @_;
114             return $self->search($proto);
115             }
116              
117             sub search {
118             my ($self, $proto, $args) = @_;
119              
120             for my $key (keys %$proto) {
121             next if $key =~ m/^data\./;
122             next if $key eq 'class';
123             my $value = delete $proto->{$key};
124             $proto->{"data.$key"} = $value;
125             }
126              
127             return $self->_proto_search($proto, $args);
128             }
129              
130             sub _proto_search {
131             my ($self, $proto, $args) = @_;
132             my $cursor = $self->collection->query($proto, $args);
133             return Data::Stream::Bulk::Callback->new(
134             callback => sub {
135             if (my $obj = $cursor->next) {
136             $obj->{_id} = $obj->{_id}->to_string if (ref $obj->{_id} eq 'MongoDB::OID');
137             return [$self->deserialize($obj)];
138             }
139             return;
140             }
141             );
142             }
143              
144              
145             sub serialize {
146             my $self = shift;
147             return $self->collapse_jspon(@_);
148             }
149              
150             sub deserialize {
151             my ( $self, $doc, @args ) = @_;
152             $self->expand_jspon( $doc, @args );
153             }
154              
155              
156              
157             __PACKAGE__->meta->make_immutable;
158              
159             1;
160              
161             __END__
162              
163             =head1 NAME
164              
165             KiokuDB::Backend::MongoDB - MongoDB backend for KiokuDB
166              
167             =head1 SYNOPSIS
168              
169             use KiokuDB::Backend::MongoDB;
170              
171             my $conn = MongoDB::Connection->new(host => 'localhost');
172             my $mongodb = $conn->get_database('somedb');
173             my $collection = $mongodb->get_collection('kiokutest');
174             my $mongo = KiokuDB::Backend::MongoDB->new('collection' => $collection);
175              
176             my $d = KiokuDB->new(
177             backend => $mongo
178             );
179              
180             my $s = $d->new_scope;
181             my $uuid = $d->store($some_object);
182             ...
183              
184              
185             =head1 DESCRIPTION
186              
187             This KiokuDB backend implements the C<Clear>, C<Scan> and the C<Query::Simple>
188             roles.
189              
190             =head1 AUTHOR
191              
192             Ask Bjørn Hansen, C<< <ask at develooper.com> >>
193              
194             =head1 BUGS
195              
196             Please report any bugs or feature requests to
197             C<bug-kiokudb-backend-mongodb at rt.cpan.org>, or through the web
198             interface at
199             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=KiokuDB-Backend-MongoDB>.
200             I will be notified, and then you'll automatically be notified of
201             progress on your bug as I make changes.
202              
203              
204             =head1 SUPPORT
205              
206             You can find documentation for this module with the perldoc command.
207              
208             perldoc KiokuDB::Backend::MongoDB
209              
210             You can also look for information at:
211              
212             =over 4
213              
214             =item * RT: CPAN's request tracker
215              
216             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=KiokuDB-Backend-MongoDB>
217              
218             =item * CPAN Ratings
219              
220             L<http://cpanratings.perl.org/d/KiokuDB-Backend-MongoDB>
221              
222             =item * Search CPAN
223              
224             L<http://search.cpan.org/dist/KiokuDB-Backend-MongoDB/>
225              
226             =back
227              
228              
229             =head1 ACKNOWLEDGEMENTS
230              
231             Yuval Kogman (KiokuDB::Backend::CouchDB) and Florian Ragwitz (MongoDB).
232              
233             =head1 COPYRIGHT & LICENSE
234              
235             Copyright 2009-2010 Ask Bjørn Hansen, all rights reserved.
236              
237             This program is free software; you can redistribute it and/or modify it
238             under the same terms as Perl itself.
239              
240              
241             =cut