File Coverage

blib/lib/MongoDB/Database.pm
Criterion Covered Total %
statement 54 103 52.4
branch 0 30 0.0
condition 0 26 0.0
subroutine 18 27 66.6
pod 9 9 100.0
total 81 195 41.5


line stmt bran cond sub pod time code
1             # Copyright 2009 - present MongoDB, Inc.
2             #
3             # Licensed under the Apache License, Version 2.0 (the "License");
4             # you may not use this file except in compliance with the License.
5             # You may obtain a copy of the License at
6             #
7             # http://www.apache.org/licenses/LICENSE-2.0
8             #
9             # Unless required by applicable law or agreed to in writing, software
10             # distributed under the License is distributed on an "AS IS" BASIS,
11             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12             # See the License for the specific language governing permissions and
13             # limitations under the License.
14              
15 59     59   377 use strict;
  59         125  
  59         1784  
16 59     59   273 use warnings;
  59         99  
  59         2057  
17             package MongoDB::Database;
18              
19              
20             # ABSTRACT: A MongoDB Database
21              
22 59     59   276 use version;
  59         97  
  59         421  
23             our $VERSION = 'v2.2.2';
24              
25 59     59   25974 use MongoDB::CommandResult;
  59         198  
  59         3936  
26 59     59   499 use MongoDB::Error;
  59         169  
  59         7065  
27 59     59   29316 use MongoDB::GridFSBucket;
  59         208  
  59         2124  
28 59     59   451 use MongoDB::Op::_Command;
  59         112  
  59         1335  
29 59     59   27389 use MongoDB::Op::_DropDatabase;
  59         187  
  59         2035  
30 59     59   22387 use MongoDB::Op::_ListCollections;
  59         219  
  59         2022  
31 59     59   431 use MongoDB::ReadPreference;
  59         116  
  59         1475  
32 59         324 use MongoDB::_Types qw(
33             BSONCodec
34             NonNegNum
35             ReadPreference
36             ReadConcern
37             WriteConcern
38             is_OrderedDoc
39 59     59   279 );
  59         120  
40 59         261 use Types::Standard qw(
41             InstanceOf
42             Str
43 59     59   88348 );
  59         135  
44 59     59   41516 use Carp 'carp';
  59         126  
  59         3080  
45 59     59   315 use boolean;
  59         108  
  59         326  
46 59     59   3140 use Moo;
  59         115  
  59         280  
47 59     59   20329 use namespace::clean -except => 'meta';
  59         124  
  59         339  
48              
49             has _client => (
50             is => 'ro',
51             isa => InstanceOf['MongoDB::MongoClient'],
52             required => 1,
53             );
54              
55             #pod =attr name
56             #pod
57             #pod The name of the database.
58             #pod
59             #pod =cut
60              
61             has name => (
62             is => 'ro',
63             isa => Str,
64             required => 1,
65             );
66              
67             #pod =attr read_preference
68             #pod
69             #pod A L object. It may be initialized with a string
70             #pod corresponding to one of the valid read preference modes or a hash reference
71             #pod that will be coerced into a new MongoDB::ReadPreference object.
72             #pod By default it will be inherited from a L object.
73             #pod
74             #pod =cut
75              
76             has read_preference => (
77             is => 'ro',
78             isa => ReadPreference,
79             required => 1,
80             coerce => ReadPreference->coercion,
81             );
82              
83             #pod =attr write_concern
84             #pod
85             #pod A L object. It may be initialized with a hash
86             #pod reference that will be coerced into a new MongoDB::WriteConcern object.
87             #pod By default it will be inherited from a L object.
88             #pod
89             #pod =cut
90              
91             has write_concern => (
92             is => 'ro',
93             isa => WriteConcern,
94             required => 1,
95             coerce => WriteConcern->coercion,
96             );
97              
98             #pod =attr read_concern
99             #pod
100             #pod A L object. May be initialized with a hash
101             #pod reference or a string that will be coerced into the level of read
102             #pod concern.
103             #pod
104             #pod By default it will be inherited from a L object.
105             #pod
106             #pod =cut
107              
108             has read_concern => (
109             is => 'ro',
110             isa => ReadConcern,
111             required => 1,
112             coerce => ReadConcern->coercion,
113             );
114              
115             #pod =attr max_time_ms
116             #pod
117             #pod Specifies the maximum amount of time in milliseconds that the server should use
118             #pod for working on a query.
119             #pod
120             #pod B: this will only be used for server versions 2.6 or greater, as that
121             #pod was when the C<$maxTimeMS> meta-operator was introduced.
122             #pod
123             #pod =cut
124              
125             has max_time_ms => (
126             is => 'ro',
127             isa => NonNegNum,
128             required => 1,
129             );
130              
131             #pod =attr bson_codec
132             #pod
133             #pod An object that provides the C and C methods, such as
134             #pod from L. It may be initialized with a hash reference that will
135             #pod be coerced into a new L object. By default it will be inherited
136             #pod from a L object.
137             #pod
138             #pod =cut
139              
140             has bson_codec => (
141             is => 'ro',
142             isa => BSONCodec,
143             coerce => BSONCodec->coercion,
144             required => 1,
145             );
146              
147             #--------------------------------------------------------------------------#
148             # methods
149             #--------------------------------------------------------------------------#
150              
151             #pod =method client
152             #pod
153             #pod $client = $db->client;
154             #pod
155             #pod Returns the L object associated with this
156             #pod object.
157             #pod
158             #pod =cut
159              
160             sub client {
161 0     0 1   my ($self) = @_;
162 0           return $self->_client;
163             }
164              
165             #pod =method list_collections
166             #pod
167             #pod $result = $coll->list_collections( $filter );
168             #pod $result = $coll->list_collections( $filter, $options );
169             #pod
170             #pod Returns a L object to iterate over collection description
171             #pod documents. These will contain C and C keys like so:
172             #pod
173             #pod use boolean;
174             #pod
175             #pod {
176             #pod name => "my_capped_collection",
177             #pod options => {
178             #pod capped => true,
179             #pod size => 10485760,
180             #pod }
181             #pod },
182             #pod
183             #pod An optional filter document may be provided, which cause only collection
184             #pod description documents matching a filter expression to be returned. See the
185             #pod L
186             #pod documentation|http://docs.mongodb.org/manual/reference/command/listCollections/>
187             #pod for more details on filtering for specific collections.
188             #pod
189             #pod A hash reference of options may be provided. Valid keys include:
190             #pod
191             #pod =for :list
192             #pod * C – the number of documents to return per batch.
193             #pod * C – the maximum amount of time in milliseconds to allow the
194             #pod command to run. (Note, this will be ignored for servers before version 2.6.)
195             #pod * C - query and return names of the collections only. Defaults to
196             #pod false. (Note, this will be ignored for servers before version 4.0)
197             #pod * C - the session to use for these operations. If not supplied, will
198             #pod use an implicit session. For more information see L
199             #pod
200             #pod B: When using C, the filter query must be empty or must only
201             #pod query the C field or else no documents will be found.
202             #pod
203             #pod =cut
204              
205             sub list_collections {
206 0     0 1   my ( $self, $filter, $options ) = @_;
207 0   0       $filter ||= {};
208 0   0       $options ||= {};
209              
210             # possibly fallback to default maxTimeMS
211 0 0 0       if ( ! exists $options->{maxTimeMS} && $self->max_time_ms ) {
212 0           $options->{maxTimeMS} = $self->max_time_ms;
213             }
214              
215 0           my $session = $self->_client->_get_session_from_hashref( $options );
216              
217 0           my $op = MongoDB::Op::_ListCollections->_new(
218             db_name => $self->name,
219             client => $self->_client,
220             bson_codec => $self->bson_codec,
221             filter => $filter,
222             options => $options,
223             session => $session,
224             monitoring_callback => $self->_client->monitoring_callback,
225             read_preference => MongoDB::ReadPreference->new( mode => 'primary' ),
226             );
227              
228 0           return $self->_client->send_retryable_read_op($op);
229             }
230              
231             #pod =method collection_names
232             #pod
233             #pod my @collections = $database->collection_names;
234             #pod my @collections = $database->collection_names( $filter );
235             #pod my @collections = $database->collection_names( $filter, $options );
236             #pod
237             #pod Returns the list of collections in this database.
238             #pod
239             #pod An optional filter document may be provided, which cause only collection
240             #pod description documents matching a filter expression to be returned. See the
241             #pod L
242             #pod documentation|http://docs.mongodb.org/manual/reference/command/listCollections/>
243             #pod for more details on filtering for specific collections.
244             #pod
245             #pod A hashref of options may also be provided.
246             #pod
247             #pod Valid options include:
248             #pod
249             #pod =for :list
250             #pod * C - the session to use for these operations. If not supplied, will
251             #pod use an implicit session. For more information see L
252             #pod
253             #pod B if the number of collections is very large, this may return
254             #pod a very large result. Either pass an appropriate filter, or use
255             #pod L to iterate over collections instead.
256             #pod
257             #pod =cut
258              
259             sub collection_names {
260 0     0 1   my ( $self, $filter, $options ) = @_;
261              
262 0   0       $filter ||= {};
263 0   0       $options ||= {};
264              
265 0           my @filter_keys = keys %$filter;
266             $options->{nameOnly} =
267 0   0       @filter_keys == 0 || ( @filter_keys == 1 && exists $filter->{name} );
268              
269 0           my $res = $self->list_collections( $filter, $options );
270              
271 0           return map { $_->{name} } $res->all;
  0            
272             }
273              
274             #pod =method get_collection, coll
275             #pod
276             #pod my $collection = $database->get_collection('foo');
277             #pod my $collection = $database->get_collection('foo', $options);
278             #pod my $collection = $database->coll('foo', $options);
279             #pod
280             #pod Returns a L for the given collection name within this
281             #pod database.
282             #pod
283             #pod It takes an optional hash reference of options that are passed to the
284             #pod L constructor.
285             #pod
286             #pod The C method is an alias for C.
287             #pod
288             #pod =cut
289              
290             sub get_collection {
291 0     0 1   my ( $self, $collection_name, $options ) = @_;
292 0 0         return MongoDB::Collection->new(
293             read_preference => $self->read_preference,
294             write_concern => $self->write_concern,
295             read_concern => $self->read_concern,
296             bson_codec => $self->bson_codec,
297             max_time_ms => $self->max_time_ms,
298             ( $options ? %$options : () ),
299             # not allowed to be overridden by options
300             database => $self,
301             name => $collection_name,
302             );
303             }
304              
305 59     59   61892 { no warnings 'once'; *coll = \&get_collection }
  59         139  
  59         7161  
306              
307             #pod =method get_gridfsbucket, gfs
308             #pod
309             #pod my $grid = $database->get_gridfsbucket;
310             #pod my $grid = $database->get_gridfsbucket($options);
311             #pod my $grid = $database->gfs($options);
312             #pod
313             #pod This method returns a L object for storing and
314             #pod retrieving files from the database.
315             #pod
316             #pod It takes an optional hash reference of options that are passed to the
317             #pod L constructor.
318             #pod
319             #pod See L for more information.
320             #pod
321             #pod The C method is an alias for C.
322             #pod
323             #pod =cut
324              
325             sub get_gridfsbucket {
326 0     0 1   my ($self, $options) = @_;
327              
328 0 0         return MongoDB::GridFSBucket->new(
329             read_preference => $self->read_preference,
330             write_concern => $self->write_concern,
331             read_concern => $self->read_concern,
332             bson_codec => $self->bson_codec,
333             max_time_ms => $self->max_time_ms,
334             ( $options ? %$options : () ),
335             # not allowed to be overridden by options
336             database => $self,
337             )
338             }
339              
340 59     59   412 { no warnings 'once'; *gfs = \&get_gridfsbucket }
  59         113  
  59         42503  
341              
342             #pod =method drop
343             #pod
344             #pod $database->drop;
345             #pod
346             #pod Deletes the database.
347             #pod
348             #pod A hashref of options may also be provided.
349             #pod
350             #pod Valid options include:
351             #pod
352             #pod =for :list
353             #pod * C - the session to use for these operations. If not supplied, will
354             #pod use an implicit session. For more information see L
355             #pod
356             #pod =cut
357              
358             sub drop {
359 0     0 1   my ( $self, $options ) = @_;
360              
361 0           my $session = $self->_client->_get_session_from_hashref( $options );
362              
363 0           return $self->_client->send_write_op(
364             MongoDB::Op::_DropDatabase->_new(
365             client => $self->_client,
366             db_name => $self->name,
367             bson_codec => $self->bson_codec,
368             write_concern => $self->write_concern,
369             session => $session,
370             monitoring_callback => $self->_client->monitoring_callback,
371             )
372             )->output;
373             }
374              
375             #pod =method run_command
376             #pod
377             #pod my $output = $database->run_command([ some_command => 1 ]);
378             #pod
379             #pod my $output = $database->run_command(
380             #pod [ some_command => 1 ],
381             #pod { mode => 'secondaryPreferred' }
382             #pod );
383             #pod
384             #pod my $output = $database->run_command(
385             #pod [ some_command => 1 ],
386             #pod $read_preference,
387             #pod $options
388             #pod );
389             #pod
390             #pod This method runs a database command. The first argument must be a document
391             #pod with the command and its arguments. It should be given as an array reference
392             #pod of key-value pairs or a L object with the command name as the
393             #pod first key. An error will be thrown if the command is not an
394             #pod L.
395             #pod
396             #pod By default, commands are run with a read preference of 'primary'. An optional
397             #pod second argument may specify an alternative read preference. If given, it must
398             #pod be a L object or a hash reference that can be used to
399             #pod construct one.
400             #pod
401             #pod A hashref of options may also be provided.
402             #pod
403             #pod Valid options include:
404             #pod
405             #pod =for :list
406             #pod * C - the session to use for these operations. If not supplied, will
407             #pod use an implicit session. For more information see L
408             #pod
409             #pod It returns the output of the command (a hash reference) on success or throws a
410             #pod L exception if
411             #pod the command fails.
412             #pod
413             #pod For a list of possible database commands, run:
414             #pod
415             #pod my $commands = $db->run_command([listCommands => 1]);
416             #pod
417             #pod There are a few examples of database commands in the
418             #pod L section. See also core documentation
419             #pod on database commands: L.
420             #pod
421             #pod =cut
422              
423             sub run_command {
424 0     0 1   my ( $self, $command, $read_pref, $options ) = @_;
425 0 0         MongoDB::UsageError->throw("command was not an ordered document")
426             if ! is_OrderedDoc($command);
427              
428 0 0 0       $read_pref = MongoDB::ReadPreference->new(
    0          
429             ref($read_pref) ? $read_pref : ( mode => $read_pref ) )
430             if $read_pref && ref($read_pref) ne 'MongoDB::ReadPreference';
431              
432 0           my $session = $self->_client->_get_session_from_hashref( $options );
433              
434 0           my $op = MongoDB::Op::_Command->_new(
435             client => $self->_client,
436             db_name => $self->name,
437             query => $command,
438             query_flags => {},
439             bson_codec => $self->bson_codec,
440             read_preference => $read_pref,
441             session => $session,
442             monitoring_callback => $self->_client->monitoring_callback,
443             );
444              
445 0           my $obj = $self->_client->send_retryable_read_op($op);
446              
447 0           return $obj->output;
448             }
449              
450             #pod =method aggregate
451             #pod
452             #pod Runs a query using the MongoDB 3.6+ aggregation framework and returns a
453             #pod L object.
454             #pod
455             #pod The first argument must be an array-ref of L
456             #pod pipeline|http://docs.mongodb.org/manual/core/aggregation-pipeline/> documents.
457             #pod Each pipeline document must be a hash reference.
458             #pod
459             #pod The server supports several collection-less aggregation source stages like
460             #pod C<$currentOp> and C<$listLocalSessions>.
461             #pod
462             #pod $result = $database->aggregate( [
463             #pod {
464             #pod "\$currentOp" => {
465             #pod allUsers => true,
466             #pod },
467             #pod },
468             #pod ] );
469             #pod
470             #pod See L in the MongoDB manual
471             #pod for more information on how to construct aggregation queries.
472             #pod
473             #pod =cut
474              
475             sub aggregate {
476 0 0   0 1   MongoDB::UsageError->throw("pipeline argument must be an array reference")
477             unless ref( $_[1] ) eq 'ARRAY';
478              
479 0           my ( $self, $pipeline, $options ) = @_;
480 0   0       $options ||= {};
481              
482 0           my $session = $self->_client->_get_session_from_hashref( $options );
483              
484             # boolify some options
485 0           for my $k (qw/allowDiskUse explain/) {
486 0 0         $options->{$k} = ( $options->{$k} ? true : false ) if exists $options->{$k};
    0          
487             }
488              
489             # possibly fallback to default maxTimeMS
490 0 0 0       if ( ! exists $options->{maxTimeMS} && $self->max_time_ms ) {
491 0           $options->{maxTimeMS} = $self->max_time_ms;
492             }
493              
494             # read preferences are ignored if the last stage is $out or $merge
495 0           my ($last_op) = keys %{ $pipeline->[-1] };
  0            
496              
497 0           my $op = MongoDB::Op::_Aggregate->_new(
498             pipeline => $pipeline,
499             options => $options,
500             read_concern => $self->read_concern,
501             has_out => !!($last_op =~ m/\$out|\$merge/),
502             client => $self->_client,
503             bson_codec => $self->bson_codec,
504             db_name => $self->name,
505             coll_name => 1, # Magic not-an-actual-collection number
506             full_name => $self->name . ".1",
507             read_preference => $self->read_preference,
508             write_concern => $self->write_concern,
509             session => $session,
510             monitoring_callback => $self->_client->monitoring_callback,
511             );
512              
513 0           return $self->_client->send_retryable_read_op($op);
514             }
515              
516             #pod =method watch
517             #pod
518             #pod Watches for changes on this database.
519             #pod
520             #pod Perform an aggregation with an implicit initial C<$changeStream> stage
521             #pod and returns a L result which can be used to
522             #pod iterate over the changes in the database. This functionality is
523             #pod available since MongoDB 4.0.
524             #pod
525             #pod my $stream = $db->watch();
526             #pod my $stream = $db->watch( \@pipeline );
527             #pod my $stream = $db->watch( \@pipeline, \%options );
528             #pod
529             #pod while (1) {
530             #pod
531             #pod # This inner loop will only run until no more changes are
532             #pod # available.
533             #pod while (my $change = $stream->next) {
534             #pod # process $change
535             #pod }
536             #pod }
537             #pod
538             #pod The returned stream will not block forever waiting for changes. If you
539             #pod want to respond to changes over a longer time use C and
540             #pod regularly call C in a loop.
541             #pod
542             #pod See L for details on usage and available
543             #pod options.
544             #pod
545             #pod =cut
546              
547             sub watch {
548 0     0 1   my ( $self, $pipeline, $options ) = @_;
549              
550 0   0       $pipeline ||= [];
551 0   0       $options ||= {};
552              
553 0           my $session = $self->_client->_get_session_from_hashref( $options );
554              
555             return MongoDB::ChangeStream->new(
556             exists($options->{startAtOperationTime})
557             ? (start_at_operation_time => delete $options->{startAtOperationTime})
558             : (),
559             exists($options->{fullDocument})
560             ? (full_document => delete $options->{fullDocument})
561             : (full_document => 'default'),
562             exists($options->{resumeAfter})
563             ? (resume_after => delete $options->{resumeAfter})
564             : (),
565             exists($options->{startAfter})
566             ? (start_after => delete $options->{startAfter})
567             : (),
568             exists($options->{maxAwaitTimeMS})
569             ? (max_await_time_ms => delete $options->{maxAwaitTimeMS})
570 0 0         : (),
    0          
    0          
    0          
    0          
571             client => $self->_client,
572             pipeline => $pipeline,
573             session => $session,
574             options => $options,
575             op_args => {
576             read_concern => $self->read_concern,
577             bson_codec => $self->bson_codec,
578             db_name => $self->name,
579             coll_name => 1, # Magic not-an-actual-collection number
580             full_name => $self->name . ".1",
581             read_preference => $self->read_preference,
582             write_concern => $self->write_concern,
583             monitoring_callback => $self->_client->monitoring_callback,
584             },
585             );
586             }
587              
588             1;
589              
590             __END__