File Coverage

blib/lib/Mojolicious/Plugin/Mongodb.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 1     1   22235 use warnings;
  1         3  
  1         41  
2 1     1   6 use strict;
  1         2  
  1         69  
3             package Mojolicious::Plugin::Mongodb;
4             $Mojolicious::Plugin::Mongodb::VERSION = '1.16';
5 1     1   993 use Mojo::Base 'Mojolicious::Plugin';
  1         11968  
  1         10  
6 1     1   2139 use MongoDB;
  0            
  0            
7             use MongoDB::Collection;
8              
9             sub register {
10             my $self = shift;
11             my $app = shift;
12             my $conf = shift || {};
13              
14             $conf->{helper} ||= 'db';
15              
16             $app->attr('_mongodb' => sub {
17             my $m = Mojolicious::Plugin::Mongodb::Connection->new(mongo_conf => $conf);
18             $m->init();
19             return $m;
20             });
21              
22             $app->helper('mongodb_connection' => sub { return shift->app->_mongodb->_conn });
23              
24              
25             $app->helper($conf->{helper} => sub {
26             my $self = shift;
27             return $self->app->_mongodb->db(@_);
28             }) unless(defined($conf->{no_db}));
29              
30             $app->helper('model' => sub {
31             my $c = shift;
32             my $m = shift;
33              
34             if($m =~ /^(.*?)\.(.*)/) {
35             # first bit has to be the db
36             return $c->app->_mongodb->db($1)->get_collection($2);
37             } else {
38             # act like coll
39             return $c->app->_mongodb->coll($m);
40             }
41             }) unless(defined($conf->{no_model}));
42              
43             $app->helper('coll' => sub { return shift->app->_mongodb->coll(@_) }) unless(defined($conf->{no_coll}));
44              
45             for my $helpername (qw/find_and_modify map_reduce group/) {
46             next if(defined($conf->{'no_' . $helpername}));
47             $app->helper($helpername => sub { return shift->app->_mongodb->$helpername(@_) });
48             }
49             }
50              
51             package Mojolicious::Plugin::Mongodb::Connection;
52             $Mojolicious::Plugin::Mongodb::Connection::VERSION = '1.16';
53             use Mojo::Base -base;
54             use Tie::IxHash;
55              
56             has 'mongo_conf' => sub { {} };
57             has 'current_db';
58             has '_conn';
59              
60             sub init {
61             my $self = shift;
62            
63             $self->_conn(MongoDB::Connection->new($self->mongo_conf));
64             }
65              
66             sub db {
67             my $self = shift;
68             my $db = shift;
69              
70             $self->current_db($db) if($db);
71             return $self->_conn->get_database($self->current_db) if($self->current_db);
72             return undef;
73             }
74              
75             sub coll {
76             my $self = shift;
77             my $coll = shift;
78              
79             return $self->db->get_collection($coll);
80             }
81              
82             sub find_and_modify {
83             my $self = shift;
84             my $coll = shift;
85             my $opts = shift;
86              
87             my $cmd = Tie::IxHash->new(
88             "findAndModify" => $coll,
89             %$opts,
90             );
91              
92             return $self->db->run_command($cmd);
93             }
94              
95             sub map_reduce {
96             my $self = shift;
97             my $collection = shift;
98             my $opts = shift;
99             my $as_cursor = delete($opts->{'as_cursor'});
100              
101             my $cmd = Tie::IxHash->new(
102             "mapreduce" => $collection,
103             %$opts
104             );
105              
106             my $res = $self->db->run_command($cmd);
107             if($res->{ok} == 1) {
108             my $coll = $res->{result};
109             return ($as_cursor) ? $self->coll($coll)->find() : $res;
110             } else {
111             return undef;
112             }
113             }
114              
115             sub group {
116             my $self = shift;
117             my $collection = shift;
118             my $opts = shift;
119              
120             # fix the shit up
121             $opts->{'ns'} = $self->name,
122             $opts->{'$reduce'} = delete($opts->{'reduce'}) if($opts->{'reduce'});
123             $opts->{'$keyf'} = delete($opts->{'keyf'}) if($opts->{'keyf'});
124              
125             return $self->find_one({ group => $opts });
126             }
127              
128             1;
129             __END__
130             =head1 NAME
131              
132             Mojolicious::Plugin::Mongodb - Use MongoDB in Mojolicious
133              
134             =head1 VERSION
135              
136             version 1.16
137              
138             =head1 SYNOPSIS
139              
140             Provides a few helpers to ease the use of MongoDB in your Mojolicious application.
141              
142             use Mojolicious::Plugin::Mongodb
143              
144             sub startup {
145             my $self = shift;
146             $self->plugin('mongodb', {
147             host => 'localhost',
148             port => 27017,
149             helper => 'db',
150             });
151             }
152              
153             =head1 CONFIGURATION OPTIONS
154              
155             helper (optional) The name to give to the easy-access helper if you want
156             to change it's name from the default 'db'
157              
158             no_db (optional) Don't install the 'db' helper
159             no_model (optional) Don't install the 'model' helper
160             no_coll (optional) Don't install the 'coll' helper
161             no_find_and_modify (optional) Don't install the 'find_and_modify' helper
162             no_map_reduce (optional) Don't install the 'map_reduce' helper
163             no_group (optional) Don't install the 'group' helper
164              
165             All other options passed to the plugin are used to connect to MongoDB.
166              
167             =head1 HELPERS/ATTRIBUTES
168              
169             =head2 mongodb_connection
170              
171             This plugin helper will return the MongoDB::Connection object, use this if you need to access it for some reason.
172              
173             =head2 db([$dbname])
174              
175             This is the name of the default easy-access helper. The default name for it is 'db', unless you have changed it using the 'helper' configuration option. This helper will return either the database you specify, or the last database you specified. You must use this in order to set the database you wish to operate on for those helpers that specify you should.
176              
177             sub someaction {
178             my $self = shift;
179              
180             # select a database
181             $self->db('my_snazzy_database')->get_collection('foo')->insert({ bar => 'baz' });
182              
183             # do an insert on the same database
184             $self->db->get_collection('foo')->insert({ bar => 'baz' });
185             }
186              
187             =head2 coll($collname)
188              
189             This helper allows easy access to a collection. It requires that you have previously selected a database using the 'db' helper. It will return undef if you have not specified a database first.
190              
191             sub someaction {
192             my $self = shift;
193              
194             # get the 'foo' collection in the 'bar' database
195             $self->db('bar');
196             my $collection = $self->coll('foo');
197              
198             # get the 'bar' collection in the 'baz' database
199             $self->db('baz');
200             my $collection = $self->coll('bar');
201             }
202              
203             =head2 model($db_and_collection)
204              
205             This helper functions as a combination of the above, or if you just want to use a different notation. An example usage would be:
206              
207             # get the number of items in collection 'bar' in database 'foo'
208             my $count = $self->model('foo.bar')->count();
209              
210             # if you use dotted collection names, no problem!
211             my $system_js_count = $self->model('foo.system.js')->count();
212              
213             # if you pass it a regular string without dots, this helper will act like C<coll>.
214             my $bar_collection = $self->model('bar');
215              
216             This helper will set the last selected db to whatever was passed as the database part of the argument, so try not to mix and match C<model> with C<coll> and C<db>.
217              
218             =head2 find_and_modify($collname, \%options)
219              
220             This helper executes a 'findAndModify' operation on the given collection. You must have selected a database using the 'db' helper. See L<http://www.mongodb.org/display/DOCS/findAndModify+Command> for supported options. It will return the raw result from the MongoDB driver.
221              
222             =head2 map_reduce($collname, \%options)
223              
224             This helper executes a 'mapReduce' operation on the given collection. You must have selected a database using the 'db' helper. All options from L<http://www.mongodb.org/display/DOCS/MapReduce> are supported. It will return undef on failure. On success, it will return the raw result from the MongoDB driver, or if you have passed the 'as_cursor' option, it will return a MongoDB::Cursor object for your result collection.
225              
226             =head1 AUTHOR
227              
228             Ben van Staveren, C<< <madcat at cpan.org> >>
229              
230             =head1 BUGS/CONTRIBUTING
231              
232             Please report any bugs through the web interface at L<http://github.com/benvanstaveren/mojolicious-plugin-mongodb/issues>
233             If you want to contribute changes or otherwise involve yourself in development, feel free to fork the Git repository from
234             L<https://github.com/benvanstaveren/mojolicious-plugin-mongodb/>.
235              
236              
237             =head1 SUPPORT
238              
239             You can find documentation for this module with the perldoc command.
240              
241             perldoc Mojolicious::Plugin::Mongodb
242              
243              
244             You can also look for information at:
245              
246             =over 4
247              
248             =item * AnnoCPAN: Annotated CPAN documentation
249              
250             L<http://annocpan.org/dist/Mojolicious-Plugin-Mongodb>
251              
252             =item * CPAN Ratings
253              
254             L<http://cpanratings.perl.org/d/Mojolicious-Plugin-Mongodb>
255              
256             =item * Search CPAN
257              
258             L<http://search.cpan.org/dist/Mojolicious-Plugin-Mongodb/>
259              
260             =back
261              
262              
263             =head1 ACKNOWLEDGEMENTS
264              
265             Based on L<Mojolicious::Plugin::Database> because I don't want to leave the MongoDB crowd in the cold.
266              
267             Thanks to Henk van Oers for pointing out a few errors in the documentation, and letting me know I should really fix the MANIFEST
268              
269             =head1 LICENSE AND COPYRIGHT
270              
271             Copyright 2011, 2012, 2013 Ben van Staveren.
272              
273             This program is free software; you can redistribute it and/or modify it
274             under the terms of either: the GNU General Public License as published
275             by the Free Software Foundation; or the Artistic License.
276              
277             See http://dev.perl.org/licenses/ for more information.
278              
279              
280             =cut