File Coverage

blib/lib/MongoDB/BulkWrite.pm
Criterion Covered Total %
statement 33 76 43.4
branch 0 22 0.0
condition 0 15 0.0
subroutine 11 20 55.0
pod 3 3 100.0
total 47 136 34.5


line stmt bran cond sub pod time code
1             # Copyright 2014 - 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   448 use strict;
  59         157  
  59         1945  
16 59     59   334 use warnings;
  59         147  
  59         2512  
17             package MongoDB::BulkWrite;
18              
19             # ABSTRACT: MongoDB bulk write interface
20              
21 59     59   357 use version;
  59         132  
  59         438  
22             our $VERSION = 'v2.2.1';
23              
24 59     59   4826 use MongoDB::Error;
  59         149  
  59         6220  
25 59     59   432 use MongoDB::Op::_BulkWrite;
  59         147  
  59         1739  
26 59     59   371 use MongoDB::BulkWriteResult;
  59         166  
  59         1575  
27 59     59   25252 use MongoDB::BulkWriteView;
  59         198  
  59         2018  
28              
29 59     59   453 use Moo;
  59         145  
  59         277  
30 59         388 use MongoDB::_Types qw(
31             Boolish
32             to_WriteConcern
33 59     59   19504 );
  59         174  
34 59         277 use Types::Standard qw(
35             ArrayRef
36             InstanceOf
37 59     59   67554 );
  59         159  
38 59     59   48494 use namespace::clean -except => 'meta';
  59         154  
  59         338  
39              
40             #pod =attr collection (required)
41             #pod
42             #pod The L where the operations are to be performed.
43             #pod
44             #pod =cut
45              
46             has 'collection' => (
47             is => 'ro',
48             isa => InstanceOf['MongoDB::Collection'],
49             required => 1,
50             );
51              
52             #pod =attr ordered (required)
53             #pod
54             #pod A boolean for whether or not operations should be ordered (true) or
55             #pod unordered (false).
56             #pod
57             #pod =cut
58              
59             has 'ordered' => (
60             is => 'ro',
61             isa => Boolish,
62             required => 1,
63             );
64              
65             #pod =attr bypassDocumentValidation
66             #pod
67             #pod A boolean for whether or not operations should bypass document validation.
68             #pod Default is false.
69             #pod
70             #pod =cut
71              
72             has 'bypassDocumentValidation' => (
73             is => 'ro',
74             isa => Boolish,
75             );
76              
77             has '_executed' => (
78             is => 'rw',
79             isa => Boolish,
80             init_arg => undef,
81             default => 0,
82             );
83              
84             has '_queue' => (
85             is => 'rw',
86             isa => ArrayRef[ArrayRef],
87             init_arg => undef,
88             default => sub { [] },
89             );
90              
91             sub _enqueue_write {
92 0     0     my $self = shift;
93 0           push @{$self->{_queue}}, @_;
  0            
94             }
95              
96 0     0     sub _all_writes { return @{$_[0]->{_queue}} }
  0            
97              
98 0     0     sub _count_writes { return scalar @{$_[0]->{_queue}} }
  0            
99              
100 0     0     sub _clear_writes { @{$_[0]->{_queue}} = (); return; }
  0            
  0            
101              
102             has '_database' => (
103             is => 'lazy',
104             isa => InstanceOf['MongoDB::Database'],
105             );
106              
107             sub _build__database {
108 0     0     my ($self) = @_;
109 0           return $self->collection->database;
110             }
111              
112             has '_client' => (
113             is => 'lazy',
114             isa => InstanceOf['MongoDB::MongoClient'],
115             );
116              
117             sub _build__client {
118 0     0     my ($self) = @_;
119 0           return $self->_database->_client;
120             }
121              
122             has _retryable => (
123             is => 'rw',
124             isa => Boolish,
125             default => 1,
126             );
127              
128             #pod =method find
129             #pod
130             #pod $view = $bulk->find( $query_document );
131             #pod
132             #pod The C method returns a L object that allows
133             #pod write operations like C or C, constrained by a query document.
134             #pod
135             #pod A query document is required. Use an empty hashref for no criteria:
136             #pod
137             #pod $bulk->find( {} )->remove; # remove all documents!
138             #pod
139             #pod An exception will be thrown on error.
140             #pod
141             #pod =cut
142              
143             sub find {
144 0     0 1   my ( $self, $doc ) = @_;
145              
146 0 0         MongoDB::UsageError->throw("find requires a criteria document. Use an empty hashref for no criteria.")
147             unless defined $doc;
148              
149 0           my $type = ref $doc;
150 0 0 0       unless ( @_ == 2 && grep { $type eq $_ } qw/HASH ARRAY Tie::IxHash/ ) {
  0            
151 0           MongoDB::UsageError->throw("argument to find must be a single hashref, arrayref or Tie::IxHash");
152             }
153              
154 0 0         if ( ref $doc eq 'ARRAY' ) {
155 0 0         MongoDB::UsageError->throw("array reference to find must have key/value pairs")
156             if @$doc % 2;
157 0           $doc = {@$doc};
158             }
159              
160 0           return MongoDB::BulkWriteView->new(
161             _query => $doc,
162             _bulk => $self,
163             );
164             }
165              
166             #pod =method insert_one
167             #pod
168             #pod $bulk->insert_one( $doc );
169             #pod
170             #pod Queues a document for insertion when L is called. The document may
171             #pod be a hash reference, an array reference (with balanced key/value pairs) or a
172             #pod L object. If the document does not have an C<_id> field, one will
173             #pod be added to the original.
174             #pod
175             #pod The method has an empty return on success; an exception will be thrown on error.
176             #pod
177             #pod =cut
178              
179             sub insert_one {
180 0 0 0 0 1   MongoDB::UsageError->throw("insert_one requires a single document reference as an argument")
181             unless @_ == 2 && ref( $_[1] );
182              
183 0           my ( $self, $doc ) = @_;
184              
185 0 0         if ( ref $doc eq 'ARRAY' ) {
186 0 0         MongoDB::UsageError->throw("array reference to find must have key/value pairs")
187             if @$doc % 2;
188 0           $doc = {@$doc};
189             }
190              
191 0           $self->_enqueue_write( [ insert => $doc ] );
192              
193 0           return;
194             }
195              
196             #pod =method execute
197             #pod
198             #pod my $result = $bulk->execute;
199             #pod # Optional write concern:
200             #pod my $result = $bulk->execute( $concern );
201             #pod # With options
202             #pod my $result = $bulk->execute( $concern, $options );
203             #pod
204             #pod Executes the queued operations. The order and semantics depend on
205             #pod whether the bulk object is ordered or unordered:
206             #pod
207             #pod =for :list
208             #pod * ordered — operations are executed in order, but operations of the same type
209             #pod (e.g. multiple inserts) may be grouped together and sent to the server. If
210             #pod the server returns an error, the bulk operation will stop and an error will
211             #pod be thrown.
212             #pod * unordered — operations are grouped by type and sent to the server in an
213             #pod unpredictable order. After all operations are sent, if any errors occurred,
214             #pod an error will be thrown.
215             #pod
216             #pod When grouping operations of a type, operations will be sent to the server in
217             #pod batches not exceeding 16MiB or 1000 items (for a version 2.6 or later server)
218             #pod or individually (for legacy servers without write command support).
219             #pod
220             #pod A write concern is optional, and can either take a pre-constructed WriteConcern
221             #pod object, or the arguments to construct one. For information on write concerns,
222             #pod see L.
223             #pod
224             #pod The options argument is an optional hashref which can contain the following
225             #pod values:
226             #pod
227             #pod =for :list
228             #pod * C - the session to use for these operations. If not supplied, will
229             #pod use an implicit session. For more information see L
230             #pod
231             #pod This method returns a L object if the bulk operation
232             #pod executes successfully.
233             #pod
234             #pod Typical errors might include:
235             #pod
236             #pod =for :list
237             #pod * C — one or more write operations failed
238             #pod * C - all writes were accepted by a primary, but
239             #pod the write concern failed
240             #pod * C — a command to the database failed entirely
241             #pod
242             #pod See L for more on error handling.
243             #pod
244             #pod B: it is an error to call C without any operations or
245             #pod to call C more than once on the same bulk object.
246             #pod
247             #pod
248             #pod =cut
249              
250             sub execute {
251 0     0 1   my ( $self, $write_concern, $options ) = @_;
252 0 0 0       $write_concern = to_WriteConcern($write_concern)
253             if defined($write_concern) && ref($write_concern) ne 'MongoDB::WriteConcern';
254              
255 0 0         if ( $self->_executed ) {
256 0           MongoDB::UsageError->throw("bulk op execute called more than once");
257             }
258             else {
259 0           $self->_executed(1);
260             }
261              
262 0 0         unless ( $self->_count_writes ) {
263 0           MongoDB::UsageError->throw("no bulk ops to execute");
264             }
265              
266 0   0       $write_concern ||= $self->collection->write_concern;
267              
268 0           my $session = $self->_client->_get_session_from_hashref( $options );
269              
270             # Transaction write concern overrides all
271 0 0 0       $write_concern = $session->_get_transaction_write_concern
272             if defined $session && $session->_active_transaction;
273              
274 0           my $op = MongoDB::Op::_BulkWrite->_new(
275             client => $self->_client,
276             db_name => $self->_database->name,
277             coll_name => $self->collection->name,
278             full_name => $self->collection->full_name,
279             queue => $self->_queue,
280             ordered => $self->ordered,
281             bypassDocumentValidation => $self->bypassDocumentValidation,
282             bson_codec => $self->collection->bson_codec,
283             write_concern => $write_concern,
284             session => $session,
285             monitoring_callback => $self->_client->monitoring_callback,
286             _retryable => $self->_retryable,
287             );
288              
289             # Op::_BulkWrite internally does retryable writes
290 0           return $self->_client->send_write_op( $op );
291             }
292              
293             1;
294              
295             __END__