File Coverage

blib/lib/MongoDB/Op/_FindAndUpdate.pm
Criterion Covered Total %
statement 27 45 60.0
branch 0 12 0.0
condition 0 5 0.0
subroutine 9 10 90.0
pod 0 1 0.0
total 36 73 49.3


line stmt bran cond sub pod time code
1             # Copyright 2015 - 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   433 use strict;
  59         154  
  59         1839  
16 59     59   351 use warnings;
  59         139  
  59         2275  
17             package MongoDB::Op::_FindAndUpdate;
18              
19             # Encapsulate find_and_update operation; atomically update and return doc
20              
21 59     59   336 use version;
  59         140  
  59         374  
22             our $VERSION = 'v2.2.1';
23              
24 59     59   4473 use Moo;
  59         219  
  59         351  
25              
26 59     59   18873 use MongoDB::Error;
  59         173  
  59         6404  
27 59     59   519 use MongoDB::Op::_Command;
  59         188  
  59         1962  
28 59         519 use Types::Standard qw(
29             HashRef
30 59     59   447 );
  59         142  
31 59         436 use MongoDB::_Types qw(
32             Boolish
33 59     59   30843 );
  59         149  
34 59     59   59110 use namespace::clean;
  59         151  
  59         398  
35              
36             has filter => (
37             is => 'ro',
38             required => 1,
39             isa => HashRef,
40             );
41              
42             has modifier => (
43             is => 'ro',
44             required => 1,
45             );
46              
47             has options => (
48             is => 'ro',
49             required => 1,
50             isa => HashRef,
51             );
52              
53             has is_replace => (
54             is => 'ro',
55             required => 1,
56             isa => Boolish,
57             );
58              
59             with $_ for qw(
60             MongoDB::Role::_PrivateConstructor
61             MongoDB::Role::_CollectionOp
62             MongoDB::Role::_WriteOp
63             MongoDB::Role::_BypassValidation
64             MongoDB::Role::_UpdatePreEncoder
65             );
66              
67             sub execute {
68 0     0 0   my ( $self, $link, $topology ) = @_;
69              
70 0 0 0       if ( defined $self->options->{collation} and !$link->supports_collation ) {
71 0           MongoDB::UsageError->throw(
72             "MongoDB host '" . $link->address . "' doesn't support collation" );
73             }
74              
75             my $command = $self->_maybe_bypass(
76             $link->supports_document_validation,
77             [
78             findAndModify => $self->coll_name,
79             query => $self->filter,
80             update => $self->_pre_encode_update(
81             $link->max_bson_object_size,
82             $self->modifier,
83             $self->is_replace,
84             ),
85             (
86             $link->supports_find_modify_write_concern
87 0           ? ( @{ $self->write_concern->as_args } )
88             : ()
89             ),
90 0 0         %{ $self->options },
  0            
91             ]
92             );
93              
94 0           my $op = MongoDB::Op::_Command->_new(
95             db_name => $self->db_name,
96             query => $command,
97             query_flags => {},
98             bson_codec => $self->bson_codec,
99             session => $self->session,
100             retryable_write => $self->retryable_write,
101             monitoring_callback => $self->monitoring_callback,
102             );
103              
104             # XXX more special error handling that will be a problem for
105             # command monitoring
106 0           my $result;
107             eval {
108 0           $result = $op->execute( $link, $topology );
109 0           $result = $result->{output};
110 0           1;
111 0 0         } or do {
112 0   0       my $error = $@ || "Unknown error";
113 0 0         die $error unless $error eq 'No matching object found';
114             };
115              
116             # findAndModify returns ok:1 even for write concern errors, so
117             # we must check and throw explicitly
118 0 0         if ( $result->{writeConcernError} ) {
119             MongoDB::WriteConcernError->throw(
120             message => $result->{writeConcernError}{errmsg},
121 0           result => $result,
122             code => WRITE_CONCERN_ERROR,
123             );
124             }
125              
126 0 0         return $result->{value} if $result;
127 0           return;
128             }
129              
130             1;