File Coverage

blib/lib/MongoDB/MongoClient.pm
Criterion Covered Total %
statement 207 301 68.7
branch 48 104 46.1
condition 9 37 24.3
subroutine 71 93 76.3
pod 12 15 80.0
total 347 550 63.0


line stmt bran cond sub pod time code
1             # Copyright 2012 - 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 58     58   380 use strict;
  58         120  
  58         1651  
16 58     58   299 use warnings;
  58         116  
  58         1886  
17             package MongoDB::MongoClient;
18              
19             # ABSTRACT: A connection to a MongoDB server or multi-server deployment
20              
21 58     58   286 use version;
  58         113  
  58         288  
22             our $VERSION = 'v2.2.0';
23              
24 58     58   30691 use Moo;
  58         544364  
  58         319  
25 58     58   103400 use MongoDB::ClientSession;
  58         212  
  58         2283  
26 58     58   35982 use MongoDB::Cursor;
  58         241  
  58         2203  
27 58     58   450 use MongoDB::Error;
  58         136  
  58         6339  
28 58     58   389 use MongoDB::Op::_Command;
  58         144  
  58         1290  
29 58     58   25467 use MongoDB::Op::_FSyncUnlock;
  58         220  
  58         2277  
30 58     58   440 use MongoDB::ReadConcern;
  58         137  
  58         1150  
31 58     58   351 use MongoDB::ReadPreference;
  58         128  
  58         1079  
32 58     58   294 use MongoDB::WriteConcern;
  58         141  
  58         1150  
33 58     58   276 use MongoDB::_Constants;
  58         125  
  58         6660  
34 58     58   26508 use MongoDB::_Credential;
  58         188  
  58         2192  
35 58     58   30268 use MongoDB::_Dispatcher;
  58         183  
  58         2207  
36 58     58   25526 use MongoDB::_SessionPool;
  58         254  
  58         2145  
37 58     58   36382 use MongoDB::_Topology;
  58         271  
  58         2815  
38 58     58   27539 use MongoDB::_URI;
  58         253  
  58         2624  
39 58     58   527 use BSON 1.012000;
  58         1774  
  58         2841  
40 58     58   390 use Digest::MD5;
  58         135  
  58         1791  
41 58     58   354 use UUID::URandom;
  58         133  
  58         1709  
42 58     58   330 use Tie::IxHash;
  58         143  
  58         1561  
43 58     58   348 use Time::HiRes qw/usleep/;
  58         138  
  58         418  
44 58     58   7439 use Carp 'carp', 'croak', 'confess';
  58         150  
  58         4070  
45 58     58   436 use Safe::Isa 1.000007;
  58         1233  
  58         6405  
46 58     58   527 use Scalar::Util qw/reftype weaken/;
  58         128  
  58         3230  
47 58     58   431 use boolean;
  58         144  
  58         608  
48 58     58   4351 use Encode;
  58         147  
  58         5843  
49 58         637 use MongoDB::_Types qw(
50             ArrayOfHashRef
51             AuthMechanism
52             Boolish
53             BSONCodec
54             CompressionType
55             Document
56             HeartbeatFreq
57             MaxStalenessNum
58             NonNegNum
59             ReadPrefMode
60             ReadPreference
61             ZlibCompressionLevel
62 58     58   494 );
  58         146  
63 58         315 use Types::Standard qw(
64             CodeRef
65             HashRef
66             ArrayRef
67             InstanceOf
68             Undef
69             Int
70             Num
71             Str
72             Maybe
73 58     58   144591 );
  58         169  
74              
75 58     58   93902 use namespace::clean -except => 'meta';
  58         179  
  58         421  
76              
77             #--------------------------------------------------------------------------#
78             # public attributes
79             #
80             # Of these, only host, port and bson_codec are set without regard for
81             # connection string options. The rest are built lazily in BUILD so that
82             # option precedence can be resolved.
83             #--------------------------------------------------------------------------#
84              
85             #pod =attr host
86             #pod
87             #pod The C attribute specifies either a single server to connect to (as
88             #pod C or C), or else a L
89             #pod STRING URI> with a seed list of one or more servers plus connection options.
90             #pod
91             #pod B: Options specified in the connection string take precedence over options
92             #pod provided as constructor arguments.
93             #pod
94             #pod Defaults to the connection string URI C.
95             #pod
96             #pod For IPv6 support, you must have a recent version of L
97             #pod installed. This module ships with the Perl core since v5.20.0 and is
98             #pod available on CPAN for older Perls.
99             #pod
100             #pod =cut
101              
102             has host => (
103             is => 'ro',
104             isa => Str,
105             default => 'mongodb://localhost:27017',
106             );
107              
108             #pod =attr app_name
109             #pod
110             #pod This attribute specifies an application name that should be associated with
111             #pod this client. The application name will be communicated to the server as
112             #pod part of the initial connection handshake, and will appear in
113             #pod connection-level and operation-level diagnostics on the server generated on
114             #pod behalf of this client. This may be set in a connection string with the
115             #pod C option.
116             #pod
117             #pod The default is the empty string, which indicates a lack of an application
118             #pod name.
119             #pod
120             #pod The application name must not exceed 128 bytes.
121             #pod
122             #pod =cut
123              
124             has app_name => (
125             is => 'lazy',
126             isa => Str,
127             builder => '_build_app_name',
128             );
129              
130             sub _build_app_name {
131 188     188   2464 my ($self) = @_;
132 188         824 my $app_name = $self->__uri_or_else(
133             u => 'appname',
134             e => 'app_name',
135             d => '',
136             );
137 188 100       777 unless ( length($app_name) <= 128 ) {
138 1         20 MongoDB::UsageError->throw("app name must be at most 128 bytes");
139             }
140 187         3125 return $app_name;
141             }
142              
143             #pod =attr auth_mechanism
144             #pod
145             #pod This attribute determines how the client authenticates with the server.
146             #pod Valid values are:
147             #pod
148             #pod =for :list
149             #pod * NONE
150             #pod * DEFAULT
151             #pod * MONGODB-CR
152             #pod * MONGODB-X509
153             #pod * GSSAPI
154             #pod * PLAIN
155             #pod * SCRAM-SHA-1
156             #pod
157             #pod If not specified, then if no username or C URI option is provided,
158             #pod it defaults to NONE. Otherwise, it is set to DEFAULT, which chooses
159             #pod SCRAM-SHA-1 if available or MONGODB-CR otherwise.
160             #pod
161             #pod This may be set in a connection string with the C option.
162             #pod
163             #pod =cut
164              
165             has auth_mechanism => (
166             is => 'lazy',
167             isa => AuthMechanism,
168             builder => '_build_auth_mechanism',
169             );
170              
171             sub _build_auth_mechanism {
172 187     187   10226 my ($self) = @_;
173              
174 187   100     3062 my $source = $self->_uri->options->{authsource} // "";
175 187 100 100     5103 my $default = length( $self->username ) || length($source) ? 'DEFAULT' : 'NONE';
176              
177 187         10966 return $self->__uri_or_else(
178             u => 'authmechanism',
179             e => 'auth_mechanism',
180             d => $default,
181             );
182             }
183              
184             #pod =attr auth_mechanism_properties
185             #pod
186             #pod This is an optional hash reference of authentication mechanism specific properties.
187             #pod See L for details.
188             #pod
189             #pod This may be set in a connection string with the C
190             #pod option. If given, the value must be key/value pairs joined with a ":".
191             #pod Multiple pairs must be separated by a comma. If ": or "," appear in a key or
192             #pod value, they must be URL encoded.
193             #pod
194             #pod =cut
195              
196             has auth_mechanism_properties => (
197             is => 'lazy',
198             isa => HashRef,
199             builder => '_build_auth_mechanism_properties',
200             );
201              
202             sub _build_auth_mechanism_properties {
203 187     187   11096 my ($self) = @_;
204 187         737 return $self->__uri_or_else(
205             u => 'authmechanismproperties',
206             e => 'auth_mechanism_properties',
207             d => {},
208             );
209             }
210              
211             #pod =attr bson_codec
212             #pod
213             #pod An object that provides the C and C methods, such as
214             #pod from L. It may be initialized with a hash reference that will
215             #pod be coerced into a new L object.
216             #pod
217             #pod If not provided, a L object with default values will be generated.
218             #pod
219             #pod =cut
220              
221             has bson_codec => (
222             is => 'lazy',
223             isa => BSONCodec,
224             coerce => BSONCodec->coercion,
225             writer => '_set_bson_codec',
226             builder => '_build_bson_codec',
227             );
228              
229             sub _build_bson_codec {
230 180     180   3969 my ($self) = @_;
231 180         2817 return BSON->new();
232             }
233              
234             #pod =attr compressors
235             #pod
236             #pod An array reference of compression type names. Currently, C, C and
237             #pod C are supported.
238             #pod
239             #pod =cut
240              
241             has compressors => (
242             is => 'lazy',
243             isa => ArrayRef[CompressionType],
244             builder => '_build_compressors',
245             );
246              
247             sub _build_compressors {
248 115     115   18687 my ($self) = @_;
249 115         464 return $self->__uri_or_else(
250             u => 'compressors',
251             e => 'compressors',
252             d => [],
253             );
254             }
255              
256             #pod =attr zlib_compression_level
257             #pod
258             #pod An integer from C<-1> to C<9> specifying the compression level to use
259             #pod when L is set to C.
260             #pod
261             #pod B: When the special value C<-1> is given, the default compression
262             #pod level will be used.
263             #pod
264             #pod =cut
265              
266             has zlib_compression_level => (
267             is => 'lazy',
268             isa => ZlibCompressionLevel,
269             builder => '_build_zlib_compression_level',
270             );
271              
272             sub _build_zlib_compression_level {
273 173     173   18203 my ($self) = @_;
274 173         751 return $self->__uri_or_else(
275             u => 'zlibcompressionlevel',
276             e => 'zlib_compression_level',
277             d => -1,
278             );
279             }
280              
281             #pod =attr connect_timeout_ms
282             #pod
283             #pod This attribute specifies the amount of time in milliseconds to wait for a
284             #pod new connection to a server.
285             #pod
286             #pod The default is 10,000 ms.
287             #pod
288             #pod If set to a negative value, connection operations will block indefinitely
289             #pod until the server replies or until the operating system TCP/IP stack gives
290             #pod up (e.g. if the name can't resolve or there is no process listening on the
291             #pod target host/port).
292             #pod
293             #pod A zero value polls the socket during connection and is thus likely to fail
294             #pod except when talking to a local process (and perhaps even then).
295             #pod
296             #pod This may be set in a connection string with the C option.
297             #pod
298             #pod =cut
299              
300             has connect_timeout_ms => (
301             is => 'lazy',
302             isa => Num,
303             builder => '_build_connect_timeout_ms',
304             );
305              
306             sub _build_connect_timeout_ms {
307 187     187   9826 my ($self) = @_;
308 187         694 return $self->__uri_or_else(
309             u => 'connecttimeoutms',
310             e => 'connect_timeout_ms',
311             d => 10000,
312             );
313             }
314              
315             #pod =attr db_name
316             #pod
317             #pod Optional. If an L requires a database for authentication,
318             #pod this attribute will be used. Otherwise, it will be ignored. Defaults to
319             #pod "admin".
320             #pod
321             #pod This may be provided in the L as
322             #pod a path between the authority and option parameter sections. For example, to
323             #pod authenticate against the "admin" database (showing a configuration option only
324             #pod for illustration):
325             #pod
326             #pod mongodb://localhost/admin?readPreference=primary
327             #pod
328             #pod =cut
329              
330             has db_name => (
331             is => 'lazy',
332             isa => Str,
333             builder => '_build_db_name',
334             );
335              
336             sub _build_db_name {
337 187     187   10103 my ($self) = @_;
338 187         3064 return __string( $self->_uri->db_name, $self->_deferred->{db_name} );
339             }
340              
341             #pod =attr heartbeat_frequency_ms
342             #pod
343             #pod The time in milliseconds (non-negative) between scans of all servers to
344             #pod check if they are up and update their latency. Defaults to 60,000 ms.
345             #pod
346             #pod This may be set in a connection string with the C option.
347             #pod
348             #pod =cut
349              
350             has heartbeat_frequency_ms => (
351             is => 'lazy',
352             isa => HeartbeatFreq,
353             builder => '_build_heartbeat_frequency_ms',
354             );
355              
356             sub _build_heartbeat_frequency_ms {
357 187     187   9772 my ($self) = @_;
358 187         706 return $self->__uri_or_else(
359             u => 'heartbeatfrequencyms',
360             e => 'heartbeat_frequency_ms',
361             d => 60000,
362             );
363             }
364              
365             #pod =attr j
366             #pod
367             #pod If true, the client will block until write operations have been committed to the
368             #pod server's journal. Prior to MongoDB 2.6, this option was ignored if the server was
369             #pod running without journaling. Starting with MongoDB 2.6, write operations will fail
370             #pod if this option is used when the server is running without journaling.
371             #pod
372             #pod This may be set in a connection string with the C option as the
373             #pod strings 'true' or 'false'.
374             #pod
375             #pod =cut
376              
377             has j => (
378             is => 'lazy',
379             isa => Boolish,
380             builder => '_build_j',
381             );
382              
383             sub _build_j {
384 186     186   10006 my ($self) = @_;
385 186         623 return $self->__uri_or_else(
386             u => 'journal',
387             e => 'j',
388             d => undef,
389             );
390             }
391              
392             #pod =attr local_threshold_ms
393             #pod
394             #pod The width of the 'latency window': when choosing between multiple suitable
395             #pod servers for an operation, the acceptable delta in milliseconds
396             #pod (non-negative) between shortest and longest average round-trip times.
397             #pod Servers within the latency window are selected randomly.
398             #pod
399             #pod Set this to "0" to always select the server with the shortest average round
400             #pod trip time. Set this to a very high value to always randomly choose any known
401             #pod server.
402             #pod
403             #pod Defaults to 15 ms.
404             #pod
405             #pod See L for more details.
406             #pod
407             #pod This may be set in a connection string with the C option.
408             #pod
409             #pod =cut
410              
411             has local_threshold_ms => (
412             is => 'lazy',
413             isa => NonNegNum,
414             builder => '_build_local_threshold_ms',
415             );
416              
417             sub _build_local_threshold_ms {
418 186     186   9112 my ($self) = @_;
419 186         655 return $self->__uri_or_else(
420             u => 'localthresholdms',
421             e => 'local_threshold_ms',
422             d => 15,
423             );
424             }
425              
426             #pod =attr max_staleness_seconds
427             #pod
428             #pod The C parameter represents the maximum replication lag in
429             #pod seconds (wall clock time) that a secondary can suffer and still be
430             #pod eligible for reads. The default is -1, which disables staleness checks.
431             #pod Otherwise, it must be a positive integer.
432             #pod
433             #pod B: this will only be used for server versions 3.4 or greater, as that
434             #pod was when support for staleness tracking was added.
435             #pod
436             #pod If the read preference mode is 'primary', then C must not
437             #pod be supplied.
438             #pod
439             #pod The C must be at least the C
440             #pod plus 10 seconds (which is how often the server makes idle writes to the
441             #pod oplog).
442             #pod
443             #pod This may be set in a connection string with the C option.
444             #pod
445             #pod =cut
446              
447             has max_staleness_seconds => (
448             is => 'lazy',
449             isa => MaxStalenessNum,
450             builder => '_build_max_staleness_seconds',
451             );
452              
453             sub _build_max_staleness_seconds {
454 186     186   9938 my ($self) = @_;
455 186         761 return $self->__uri_or_else(
456             u => 'maxstalenessseconds',
457             e => 'max_staleness_seconds',
458             d => -1,
459             );
460             }
461              
462             #pod =attr max_time_ms
463             #pod
464             #pod Specifies the maximum amount of time in (non-negative) milliseconds that the
465             #pod server should use for working on a database command. Defaults to 0, which disables
466             #pod this feature. Make sure this value is shorter than C.
467             #pod
468             #pod B: this will only be used for server versions 2.6 or greater, as that
469             #pod was when the C<$maxTimeMS> meta-operator was introduced.
470             #pod
471             #pod You are B encouraged to set this variable if you know your
472             #pod environment has MongoDB 2.6 or later, as getting a definitive error response
473             #pod from the server is vastly preferred over a getting a network socket timeout.
474             #pod
475             #pod This may be set in a connection string with the C option.
476             #pod
477             #pod =cut
478              
479             has max_time_ms => (
480             is => 'lazy',
481             isa => NonNegNum,
482             builder => '_build_max_time_ms',
483             );
484              
485             sub _build_max_time_ms {
486 186     186   10117 my ($self) = @_;
487 186         634 return $self->__uri_or_else(
488             u => 'maxtimems',
489             e => 'max_time_ms',
490             d => 0,
491             );
492             }
493              
494             #pod =attr monitoring_callback
495             #pod
496             #pod Specifies a code reference used to receive monitoring events. See
497             #pod L for more details.
498             #pod
499             #pod =cut
500              
501             has monitoring_callback => (
502             is => 'ro',
503             isa => Maybe [CodeRef],
504             );
505              
506             #pod =attr password
507             #pod
508             #pod If an L requires a password, this attribute will be
509             #pod used. Otherwise, it will be ignored.
510             #pod
511             #pod This may be provided in the L as
512             #pod a C pair in the leading portion of the authority section
513             #pod before a C<@> character. For example, to authenticate as user "mulder" with
514             #pod password "trustno1":
515             #pod
516             #pod mongodb://mulder:trustno1@localhost
517             #pod
518             #pod If the username or password have a ":" or "@" in it, they must be URL encoded.
519             #pod An empty password still requires a ":" character.
520             #pod
521             #pod =cut
522              
523             has password => (
524             is => 'lazy',
525             isa => Str,
526             builder => '_build_password',
527             );
528              
529             sub _build_password {
530 186     186   13920 my ($self) = @_;
531             return
532             defined( $self->_uri->password ) ? $self->_uri->password
533             : defined( $self->_deferred->{password} ) ? $self->_deferred->{password}
534 186 100       3056 : '';
    100          
535             }
536              
537             #pod =attr port
538             #pod
539             #pod If a network port is not specified as part of the C attribute, this
540             #pod attribute provides the port to use. It defaults to 27107.
541             #pod
542             #pod =cut
543              
544             has port => (
545             is => 'ro',
546             isa => Int,
547             default => 27017,
548             );
549              
550             #pod =attr read_concern_level
551             #pod
552             #pod The read concern level determines the consistency level required
553             #pod of data being read.
554             #pod
555             #pod The default level is C, which means the server will use its configured
556             #pod default.
557             #pod
558             #pod If the level is set to "local", reads will return the latest data a server has
559             #pod locally.
560             #pod
561             #pod Additional levels are storage engine specific. See L
562             #pod Concern|http://docs.mongodb.org/manual/search/?query=readConcern> in the MongoDB
563             #pod documentation for more details.
564             #pod
565             #pod This may be set in a connection string with the the C option.
566             #pod
567             #pod =cut
568              
569             has read_concern_level => (
570             is => 'lazy',
571             isa => Maybe [Str],
572             builder => '_build_read_concern_level',
573             );
574              
575             sub _build_read_concern_level {
576 185     185   9832 my ($self) = @_;
577 185         593 return $self->__uri_or_else(
578             u => 'readconcernlevel',
579             e => 'read_concern_level',
580             d => undef,
581             );
582             }
583              
584             #pod =attr read_pref_mode
585             #pod
586             #pod The read preference mode determines which server types are candidates
587             #pod for a read operation. Valid values are:
588             #pod
589             #pod =for :list
590             #pod * primary
591             #pod * primaryPreferred
592             #pod * secondary
593             #pod * secondaryPreferred
594             #pod * nearest
595             #pod
596             #pod For core documentation on read preference see
597             #pod L.
598             #pod
599             #pod This may be set in a connection string with the C option.
600             #pod
601             #pod =cut
602              
603             has read_pref_mode => (
604             is => 'lazy',
605             isa => ReadPrefMode,
606             coerce => ReadPrefMode->coercion,
607             builder => '_build_read_pref_mode',
608             );
609              
610             sub _build_read_pref_mode {
611 186     186   11666 my ($self) = @_;
612 186         667 return $self->__uri_or_else(
613             u => 'readpreference',
614             e => 'read_pref_mode',
615             d => 'primary',
616             );
617             }
618              
619             #pod =attr read_pref_tag_sets
620             #pod
621             #pod The C parameter is an ordered list of tag sets used to
622             #pod restrict the eligibility of servers, such as for data center awareness. It
623             #pod must be an array reference of hash references.
624             #pod
625             #pod The application of C varies depending on the
626             #pod C parameter. If the C is 'primary', then
627             #pod C must not be supplied.
628             #pod
629             #pod For core documentation on read preference see
630             #pod L.
631             #pod
632             #pod This may be set in a connection string with the C option.
633             #pod If given, the value must be key/value pairs joined with a ":". Multiple pairs
634             #pod must be separated by a comma. If ": or "," appear in a key or value, they must
635             #pod be URL encoded. The C option may appear more than once, in
636             #pod which case each document will be added to the tag set list.
637             #pod
638             #pod =cut
639              
640             has read_pref_tag_sets => (
641             is => 'lazy',
642             isa => ArrayOfHashRef,
643             coerce => ArrayOfHashRef->coercion,
644             builder => '_build_read_pref_tag_sets',
645             );
646              
647             sub _build_read_pref_tag_sets {
648 186     186   19057 my ($self) = @_;
649 186         860 return $self->__uri_or_else(
650             u => 'readpreferencetags',
651             e => 'read_pref_tag_sets',
652             d => [ {} ],
653             );
654             }
655              
656             #pod =attr replica_set_name
657             #pod
658             #pod Specifies the replica set name to connect to. If this string is non-empty,
659             #pod then the topology is treated as a replica set and all server replica set
660             #pod names must match this or they will be removed from the topology.
661             #pod
662             #pod This may be set in a connection string with the C option.
663             #pod
664             #pod =cut
665              
666             has replica_set_name => (
667             is => 'lazy',
668             isa => Str,
669             builder => '_build_replica_set_name',
670             );
671              
672             sub _build_replica_set_name {
673 186     186   16145 my ($self) = @_;
674 186         734 return $self->__uri_or_else(
675             u => 'replicaset',
676             e => 'replica_set_name',
677             d => '',
678             );
679             }
680              
681             #pod =attr retry_reads
682             #pod
683             #pod =cut
684              
685             has retry_reads => (
686             is => 'lazy',
687             isa => Boolish,
688             builder => '_build_retry_reads',
689             );
690              
691             sub _build_retry_reads {
692 186     186   9111 my ( $self ) = @_;
693 186         583 return $self->__uri_or_else(
694             u => 'retryreads',
695             e => 'retry_reads',
696             d => 1,
697             );
698             }
699              
700             #pod =attr retry_writes
701             #pod
702             #pod Whether the client should use retryable writes for supported commands. The
703             #pod default value is true, which means that commands which support retryable writes
704             #pod will be retried on certain errors, such as C and C
705             #pod recovering> errors.
706             #pod
707             #pod This may be set in a connection string with the C option.
708             #pod
709             #pod Note that this is only supported on MongoDB > 3.6 in Replica Set or Shard
710             #pod Clusters, and will be ignored on other deployments.
711             #pod
712             #pod Unacknowledged write operations also do not support retryable writes, even when
713             #pod retry_writes has been enabled.
714             #pod
715             #pod The supported single statement write operations are currently as follows:
716             #pod
717             #pod =for :list
718             #pod * C
719             #pod * C
720             #pod * C
721             #pod * C
722             #pod * C
723             #pod * C
724             #pod * C
725             #pod
726             #pod The supported multi statement write operations are as follows:
727             #pod
728             #pod =for :list
729             #pod * C
730             #pod * C
731             #pod
732             #pod The multi statement operations may be ether ordered or unordered. Note that for
733             #pod C operations, the request may not include update_many or
734             #pod delete_many operations.
735             #pod
736             #pod =cut
737              
738             has retry_writes => (
739             is => 'lazy',
740             isa => Boolish,
741             builder => '_build_retry_writes',
742             );
743              
744             sub _build_retry_writes {
745 186     186   10158 my ( $self ) = @_;
746 186         710 return $self->__uri_or_else(
747             u => 'retrywrites',
748             e => 'retry_writes',
749             d => 1,
750             );
751             }
752              
753             #pod =attr server_selection_timeout_ms
754             #pod
755             #pod This attribute specifies the amount of time in milliseconds to wait for a
756             #pod suitable server to be available for a read or write operation. If no
757             #pod server is available within this time period, an exception will be thrown.
758             #pod
759             #pod The default is 30,000 ms.
760             #pod
761             #pod See L for more details.
762             #pod
763             #pod This may be set in a connection string with the C
764             #pod option.
765             #pod
766             #pod =cut
767              
768             has server_selection_timeout_ms => (
769             is => 'lazy',
770             isa => Num,
771             builder => '_build_server_selection_timeout_ms',
772             );
773              
774             sub _build_server_selection_timeout_ms {
775 186     186   9176 my ($self) = @_;
776 186         674 return $self->__uri_or_else(
777             u => 'serverselectiontimeoutms',
778             e => 'server_selection_timeout_ms',
779             d => 30000,
780             );
781             }
782              
783             #pod =attr server_selection_try_once
784             #pod
785             #pod This attribute controls whether the client will make only a single attempt
786             #pod to find a suitable server for a read or write operation. The default is true.
787             #pod
788             #pod When true, the client will B use the C.
789             #pod Instead, if the topology information is stale and needs to be checked or
790             #pod if no suitable server is available, the client will make a single
791             #pod scan of all known servers to try to find a suitable one.
792             #pod
793             #pod When false, the client will continually scan known servers until a suitable
794             #pod server is found or the C is reached.
795             #pod
796             #pod See L for more details.
797             #pod
798             #pod This may be set in a connection string with the C
799             #pod option.
800             #pod
801             #pod =cut
802              
803             has server_selection_try_once => (
804             is => 'lazy',
805             isa => Boolish,
806             builder => '_build_server_selection_try_once',
807             );
808              
809             sub _build_server_selection_try_once {
810 186     186   9820 my ($self) = @_;
811 186         722 return $self->__uri_or_else(
812             u => 'serverselectiontryonce',
813             e => 'server_selection_try_once',
814             d => 1,
815             );
816             }
817              
818             #pod =attr server_selector
819             #pod
820             #pod Optional. This takes a function that augments the server selection rules.
821             #pod The function takes as a parameter a list of server descriptions representing
822             #pod the suitable servers for the read or write operation, and returns a list of
823             #pod server descriptions that should still be considered suitable. Most users
824             #pod should rely on the default server selection algorithm and should not need
825             #pod to set this attribute.
826             #pod
827             #pod =cut
828              
829             has server_selector => (
830             is => 'ro',
831             isa => Maybe[CodeRef],
832             );
833              
834             #pod =attr socket_check_interval_ms
835             #pod
836             #pod If a socket to a server has not been used in this many milliseconds, an
837             #pod C command will be issued to check the status of the server before
838             #pod issuing any reads or writes. Must be non-negative.
839             #pod
840             #pod The default is 5,000 ms.
841             #pod
842             #pod This may be set in a connection string with the C
843             #pod option.
844             #pod
845             #pod =cut
846              
847             has socket_check_interval_ms => (
848             is => 'lazy',
849             isa => NonNegNum,
850             builder => '_build_socket_check_interval_ms',
851             );
852              
853             sub _build_socket_check_interval_ms {
854 186     186   9217 my ($self) = @_;
855 186         632 return $self->__uri_or_else(
856             u => 'socketcheckintervalms',
857             e => 'socket_check_interval_ms',
858             d => 5000,
859             );
860             }
861              
862             #pod =attr socket_timeout_ms
863             #pod
864             #pod This attribute specifies the amount of time in milliseconds to wait for a
865             #pod reply from the server before issuing a network exception.
866             #pod
867             #pod The default is 30,000 ms.
868             #pod
869             #pod If set to a negative value, socket operations will block indefinitely
870             #pod until the server replies or until the operating system TCP/IP stack
871             #pod gives up.
872             #pod
873             #pod The driver automatically sets the TCP keepalive option when initializing the
874             #pod socket. For keepalive related issues, check the MongoDB documentation for
875             #pod L.
876             #pod
877             #pod A zero value polls the socket for available data and is thus likely to fail
878             #pod except when talking to a local process (and perhaps even then).
879             #pod
880             #pod This may be set in a connection string with the C option.
881             #pod
882             #pod =cut
883              
884             has socket_timeout_ms => (
885             is => 'lazy',
886             isa => Num,
887             builder => '_build_socket_timeout_ms',
888             );
889              
890             sub _build_socket_timeout_ms {
891 186     186   9689 my ($self) = @_;
892 186         689 return $self->__uri_or_else(
893             u => 'sockettimeoutms',
894             e => 'socket_timeout_ms',
895             d => 30000,
896             );
897             }
898              
899             #pod =attr ssl
900             #pod
901             #pod ssl => 1
902             #pod ssl => \%ssl_options
903             #pod
904             #pod This tells the driver that you are connecting to an SSL mongodb instance.
905             #pod
906             #pod You must have L 1.42+ and L 1.49+ installed for
907             #pod SSL support.
908             #pod
909             #pod The C attribute takes either a boolean value or a hash reference of
910             #pod options to pass to IO::Socket::SSL. For example, to set a CA file to validate
911             #pod the server certificate and set a client certificate for the server to validate,
912             #pod you could set the attribute like this:
913             #pod
914             #pod ssl => {
915             #pod SSL_ca_file => "/path/to/ca.pem",
916             #pod SSL_cert_file => "/path/to/client.pem",
917             #pod }
918             #pod
919             #pod If C is not provided, server certificates are verified against a
920             #pod default list of CAs, either L or an operating-system-specific
921             #pod default CA file. To disable verification, you can use
922             #pod C<< SSL_verify_mode => 0x00 >>.
923             #pod
924             #pod B.
925             #pod
926             #pod Server hostnames are also validated against the CN name in the server
927             #pod certificate using C<< SSL_verifycn_scheme => 'http' >>. You can use the
928             #pod scheme 'none' to disable this check.
929             #pod
930             #pod B
931             #pod recommended>.
932             #pod
933             #pod This may be set to the string 'true' or 'false' in a connection string with the
934             #pod C option, which will enable ssl with default configuration. (A future
935             #pod version of the driver may support customizing ssl via the connection string.)
936             #pod
937             #pod =cut
938              
939             has ssl => (
940             is => 'lazy',
941             isa => Boolish|HashRef,
942             builder => '_build_ssl',
943             );
944              
945             sub _build_ssl {
946 186     186   9947 my ($self) = @_;
947 186         630 my $ssl = $self->__uri_or_else(
948             u => 'ssl',
949             e => 'ssl',
950             d => 0,
951             );
952             # allow optional arguments to override as long as SSL is already enabled
953 186 50 66     817 if ( $ssl && exists $self->_deferred->{ssl} ) {
954 2         38 return $self->_deferred->{ssl};
955             }
956 184         3118 return $ssl;
957             }
958              
959             #pod =attr username
960             #pod
961             #pod Optional username for this client connection. If this field is set, the client
962             #pod will attempt to authenticate when connecting to servers. Depending on the
963             #pod L, the L field or other attributes will need to be
964             #pod set for authentication to succeed.
965             #pod
966             #pod This may be provided in the L as
967             #pod a C pair in the leading portion of the authority section
968             #pod before a C<@> character. For example, to authenticate as user "mulder" with
969             #pod password "trustno1":
970             #pod
971             #pod mongodb://mulder:trustno1@localhost
972             #pod
973             #pod If the username or password have a ":" or "@" in it, they must be URL encoded.
974             #pod An empty password still requires a ":" character.
975             #pod
976             #pod =cut
977              
978             has username => (
979             is => 'lazy',
980             isa => Str,
981             builder => '_build_username',
982             );
983              
984             sub _build_username {
985 187     187   2274 my ($self) = @_;
986              
987             return
988             defined( $self->_uri->username ) ? $self->_uri->username
989             : defined( $self->_deferred->{username} ) ? $self->_deferred->{username}
990 187 100       3020 : '';
    100          
991             }
992              
993             #pod =attr w
994             #pod
995             #pod The client I.
996             #pod
997             #pod =over 4
998             #pod
999             #pod =item * C<0> Unacknowledged. MongoClient will B wait for an acknowledgment that
1000             #pod the server has received and processed the request. Older documentation may refer
1001             #pod to this as "fire-and-forget" mode. This option is not recommended.
1002             #pod
1003             #pod =item * C<1> Acknowledged. MongoClient will wait until the
1004             #pod primary MongoDB acknowledges the write.
1005             #pod
1006             #pod =item * C<2> Replica acknowledged. MongoClient will wait until at least two
1007             #pod replicas (primary and one secondary) acknowledge the write. You can set a higher
1008             #pod number for more replicas.
1009             #pod
1010             #pod =item * C All replicas acknowledged.
1011             #pod
1012             #pod =item * C A majority of replicas acknowledged.
1013             #pod
1014             #pod =back
1015             #pod
1016             #pod If not set, the server default is used, which is typically "1".
1017             #pod
1018             #pod In MongoDB v2.0+, you can "tag" replica members. With "tagging" you can
1019             #pod specify a custom write concern For more information see L
1020             #pod Awareness|http://docs.mongodb.org/manual/data-center-awareness/>
1021             #pod
1022             #pod This may be set in a connection string with the C option.
1023             #pod
1024             #pod =cut
1025              
1026             has w => (
1027             is => 'lazy',
1028             isa => Int|Str|Undef,
1029             builder => '_build_w',
1030             );
1031              
1032             sub _build_w {
1033 186     186   14415 my ($self) = @_;
1034 186         647 return $self->__uri_or_else(
1035             u => 'w',
1036             e => 'w',
1037             d => undef,
1038             );
1039             }
1040              
1041             #pod =attr wtimeout
1042             #pod
1043             #pod The number of milliseconds an operation should wait for C secondaries to
1044             #pod replicate it.
1045             #pod
1046             #pod Defaults to 1000 (1 second). If you set this to undef, it could block indefinitely
1047             #pod (or until socket timeout is reached).
1048             #pod
1049             #pod See C above for more information.
1050             #pod
1051             #pod This may be set in a connection string with the C option.
1052             #pod
1053             #pod =cut
1054              
1055             has wtimeout => (
1056             is => 'lazy',
1057             isa => Maybe[Int],
1058             builder => '_build_wtimeout',
1059             );
1060              
1061             sub _build_wtimeout {
1062 185     185   9748 my ($self) = @_;
1063 185         666 return $self->__uri_or_else(
1064             u => 'wtimeoutms',
1065             e => 'wtimeout',
1066             d => 1000,
1067             );
1068             }
1069              
1070             #--------------------------------------------------------------------------#
1071             # computed attributes - these are private and can't be set in the
1072             # constructor, but have a public accessor
1073             #--------------------------------------------------------------------------#
1074              
1075             #pod =method read_preference
1076             #pod
1077             #pod Returns a L object constructed from
1078             #pod L and L
1079             #pod
1080             #pod B as a mutator has been removed.> Read
1081             #pod preference is read-only. If you need a different read preference for
1082             #pod a database or collection, you can specify that in C or
1083             #pod C.
1084             #pod
1085             #pod =cut
1086              
1087             has _read_preference => (
1088             is => 'lazy',
1089             isa => ReadPreference,
1090             reader => 'read_preference',
1091             init_arg => undef,
1092             builder => '_build__read_preference',
1093             );
1094              
1095             sub _build__read_preference {
1096 185     185   2249 my ($self) = @_;
1097 185 50       3165 return MongoDB::ReadPreference->new(
    50          
    50          
1098             ( defined $self->read_pref_mode ? ( mode => $self->read_pref_mode ) : () ),
1099             ( defined $self->read_pref_tag_sets ? ( tag_sets => $self->read_pref_tag_sets ) : () ),
1100             ( defined $self->max_staleness_seconds ? ( max_staleness_seconds => $self->max_staleness_seconds ) : () ),
1101             );
1102             }
1103              
1104             #pod =method write_concern
1105             #pod
1106             #pod Returns a L object constructed from L, L
1107             #pod and L.
1108             #pod
1109             #pod =cut
1110              
1111             has _write_concern => (
1112             is => 'lazy',
1113             isa => InstanceOf['MongoDB::WriteConcern'],
1114             reader => 'write_concern',
1115             init_arg => undef,
1116             builder => '_build__write_concern',
1117             );
1118              
1119             sub _build__write_concern {
1120 183     183   2177 my ($self) = @_;
1121              
1122 183         722 return MongoDB::WriteConcern->new( $self->_write_concern_options );
1123             }
1124              
1125             # Seperated out for use in transaction option defaults
1126             sub _write_concern_options {
1127 183     183   470 my ($self) = @_;
1128              
1129             return (
1130 183 100       3093 wtimeout => $self->wtimeout,
    100          
1131             # Must check for defined as w can be 0, and defaults to undef
1132             ( defined $self->w ? ( w => $self->w ) : () ),
1133             ( defined $self->j ? ( j => $self->j ) : () ),
1134             );
1135             }
1136              
1137              
1138             #pod =method read_concern
1139             #pod
1140             #pod Returns a L object constructed from
1141             #pod L.
1142             #pod
1143             #pod =cut
1144              
1145             has _read_concern => (
1146             is => 'lazy',
1147             isa => InstanceOf['MongoDB::ReadConcern'],
1148             reader => 'read_concern',
1149             init_arg => undef,
1150             builder => '_build__read_concern',
1151             );
1152              
1153             sub _build__read_concern {
1154 5     5   152 my ($self) = @_;
1155              
1156 5 100       89 return MongoDB::ReadConcern->new(
1157             ( $self->read_concern_level ?
1158             ( level => $self->read_concern_level ) : () ),
1159             );
1160             }
1161              
1162             #--------------------------------------------------------------------------#
1163             # private attributes
1164             #--------------------------------------------------------------------------#
1165              
1166             # used for a more accurate 'is this client the same one' for sessions, instead
1167             # of memory location which just feels... yucky
1168             has _id => (
1169             is => 'ro',
1170             init_arg => undef,
1171             default => sub { UUID::URandom::create_uuid_string() },
1172             );
1173              
1174             # collects constructor options and defer them so precedence can be resolved
1175             # against the _uri options; unlike other private args, this needs a valid
1176             # init argument
1177             has _deferred => (
1178             is => 'ro',
1179             isa => HashRef,
1180             init_arg => '_deferred',
1181             default => sub { {} },
1182             );
1183              
1184             #pod =method topology_type
1185             #pod
1186             #pod Returns an enumerated topology type. If the L is set,
1187             #pod the value will be either 'ReplicaSetWithPrimary' or 'ReplicaSetNoPrimary'
1188             #pod (if the primary is down or not yet discovered). Without
1189             #pod L, if there is more than one server in the list of
1190             #pod hosts, the type will be 'Sharded'.
1191             #pod
1192             #pod With only a single host and no replica set name, the topology type will
1193             #pod start as 'Direct' until the server is contacted the first time, after which
1194             #pod the type will be 'Sharded' for a mongos or 'Single' for standalone server
1195             #pod or direct connection to a replica set member.
1196             #pod
1197             #pod =cut
1198              
1199             has _topology => (
1200             is => 'lazy',
1201             isa => InstanceOf ['MongoDB::_Topology'],
1202             init_arg => undef,
1203             builder => '_build__topology',
1204             handles => {
1205             topology_type => 'type',
1206             _cluster_time => 'cluster_time',
1207             _update_cluster_time => 'update_cluster_time',
1208             },
1209             clearer => '_clear__topology',
1210             );
1211              
1212             sub _build__topology {
1213 182     182   2382 my ($self) = @_;
1214              
1215             my $type =
1216             length( $self->replica_set_name ) ? 'ReplicaSetNoPrimary'
1217 182 50       3078 : @{ $self->_uri->hostids } > 1 ? 'Sharded'
  180 100       4508  
1218             : 'Direct';
1219              
1220 182 50       5248 MongoDB::_Topology->new(
    50          
    100          
1221             uri => $self->_uri,
1222             type => $type,
1223             app_name => $self->app_name,
1224             replica_set_name => $self->replica_set_name,
1225             server_selection_timeout_sec => $self->server_selection_timeout_ms / 1000,
1226             server_selection_try_once => $self->server_selection_try_once,
1227             local_threshold_sec => $self->local_threshold_ms / 1000,
1228             heartbeat_frequency_sec => $self->heartbeat_frequency_ms / 1000,
1229             min_server_version => MIN_SERVER_VERSION,
1230             max_wire_version => MAX_WIRE_VERSION,
1231             min_wire_version => MIN_WIRE_VERSION,
1232             credential => $self->_credential,
1233             link_options => {
1234             connect_timeout => $self->connect_timeout_ms >= 0 ? $self->connect_timeout_ms / 1000
1235             : undef,
1236             socket_timeout => $self->socket_timeout_ms >= 0 ? $self->socket_timeout_ms / 1000
1237             : undef,
1238             with_ssl => !!$self->ssl,
1239             ( ref( $self->ssl ) eq 'HASH' ? ( SSL_options => $self->ssl ) : () ),
1240             },
1241             monitoring_callback => $self->monitoring_callback,
1242             compressors => $self->compressors,
1243             zlib_compression_level => $self->zlib_compression_level,
1244             socket_check_interval_sec => $self->socket_check_interval_ms / 1000,
1245             server_selector => $self->server_selector,
1246             );
1247             }
1248              
1249             has _credential => (
1250             is => 'lazy',
1251             isa => InstanceOf ['MongoDB::_Credential'],
1252             init_arg => undef,
1253             builder => '_build__credential',
1254             );
1255              
1256             sub _build__credential {
1257 182     182   27034 my ($self) = @_;
1258 182         3004 my $mechanism = $self->auth_mechanism;
1259 182         4101 my $uri_options = $self->_uri->options;
1260 182         1637 my $source = $uri_options->{authsource};
1261 182 100       3345 my $cred = MongoDB::_Credential->new(
    100          
    100          
    100          
1262             monitoring_callback => $self->monitoring_callback,
1263             mechanism => $mechanism,
1264             mechanism_properties => $self->auth_mechanism_properties,
1265             ( $self->username ? ( username => $self->username ) : () ),
1266             ( $self->password ? ( password => $self->password ) : () ),
1267             ( $source ? ( source => $source ) : () ),
1268             ( $self->db_name ? ( db_name => $self->db_name ) : () ),
1269             );
1270 173         3833 return $cred;
1271             }
1272              
1273             has _uri => (
1274             is => 'lazy',
1275             isa => InstanceOf ['MongoDB::_URI'],
1276             init_arg => undef,
1277             builder => '_build__uri',
1278             );
1279              
1280             sub _build__uri {
1281 188     188   2368 my ($self) = @_;
1282 188 100       1594 if ( $self->host =~ m{^[\w\+]+://} ) {
1283 132         2653 return MongoDB::_URI->new( uri => $self->host );
1284             }
1285             else {
1286             my $uri = $self->host =~ /:\d+$/
1287             ? $self->host
1288 56 100       518 : sprintf("%s:%s", map { $self->$_ } qw/host port/ );
  110         829  
1289 56         757 return MongoDB::_URI->new( uri => ("mongodb://$uri") );
1290             }
1291             }
1292              
1293             has _dispatcher => (
1294             is => 'lazy',
1295             isa => InstanceOf ['MongoDB::_Dispatcher'],
1296             init_arg => undef,
1297             builder => '_build__dispatcher',
1298             handles => [
1299             qw(
1300             send_direct_op
1301             send_primary_op
1302             send_retryable_read_op
1303             send_read_op
1304             send_retryable_write_op
1305             send_write_op
1306             )
1307             ],
1308             );
1309              
1310             sub _build__dispatcher {
1311 0     0   0 my $self = shift;
1312 0         0 return MongoDB::_Dispatcher->new(
1313             topology => $self->_topology,
1314             retry_writes => $self->retry_writes,
1315             retry_reads => $self->retry_reads,
1316             );
1317             }
1318              
1319             has _server_session_pool => (
1320             is => 'lazy',
1321             isa => InstanceOf['MongoDB::_SessionPool'],
1322             init_arg => undef,
1323             builder => '_build__server_session_pool',
1324             );
1325              
1326             sub _build__server_session_pool {
1327 0     0   0 my $self = shift;
1328 0         0 return MongoDB::_SessionPool->new(
1329             dispatcher => $self->_dispatcher,
1330             topology => $self->_topology,
1331             );
1332             }
1333              
1334             #--------------------------------------------------------------------------#
1335             # Constructor customization
1336             #--------------------------------------------------------------------------#
1337              
1338             # these attributes are lazy, built from either _uri->options or from
1339             # _config_options captured in BUILDARGS
1340             my @deferred_options = qw(
1341             app_name
1342             auth_mechanism
1343             auth_mechanism_properties
1344             connect_timeout_ms
1345             db_name
1346             heartbeat_frequency_ms
1347             j
1348             local_threshold_ms
1349             max_staleness_seconds
1350             max_time_ms
1351             read_pref_mode
1352             read_pref_tag_sets
1353             replica_set_name
1354             retry_writes
1355             retry_reads
1356             server_selection_timeout_ms
1357             server_selection_try_once
1358             socket_check_interval_ms
1359             socket_timeout_ms
1360             ssl
1361             username
1362             password
1363             w
1364             wtimeout
1365             read_concern_level
1366             );
1367              
1368             around BUILDARGS => sub {
1369             my $orig = shift;
1370             my $class = shift;
1371             my $hr = $class->$orig(@_);
1372             my $deferred = {};
1373             for my $k ( @deferred_options ) {
1374             $deferred->{$k} = delete $hr->{$k}
1375             if exists $hr->{$k};
1376             }
1377             $hr->{_deferred} = $deferred;
1378             return $hr;
1379             };
1380              
1381             sub BUILD {
1382 188     188 0 32595 my ($self, $opts) = @_;
1383              
1384 188         4000 my $uri = $self->_uri;
1385              
1386 188         5532 my @addresses = @{ $uri->hostids };
  188         876  
1387              
1388             # resolve and validate all deferred attributes
1389 188         4135 $self->$_ for @deferred_options;
1390              
1391             # resolve and validate read pref and write concern
1392 185         8010 $self->read_preference;
1393 183         9013 $self->write_concern;
1394              
1395             # Add error handler to codec if user didn't provide their own
1396 182 50       9289 unless ( $self->bson_codec->error_callback ) {
1397             $self->_set_bson_codec(
1398             $self->bson_codec->clone(
1399             error_callback => sub {
1400 0     0   0 my ($msg, $ref, $op) = @_;
1401 0 0       0 if ( $op =~ /^encode/ ) {
1402 0         0 MongoDB::DocumentError->throw(
1403             message => $msg,
1404             document => $ref
1405             );
1406             }
1407             else {
1408 0         0 MongoDB::DecodingError->throw($msg);
1409             }
1410             },
1411             )
1412 182         228877 );
1413             }
1414              
1415             # Instantiate topology
1416 182         42942 $self->_topology;
1417              
1418 173         8038 return;
1419             }
1420              
1421             #--------------------------------------------------------------------------#
1422             # helper functions
1423             #--------------------------------------------------------------------------#
1424              
1425             sub __uri_or_else {
1426 4384     4384   13817 my ( $self, %spec ) = @_;
1427 4384         68831 my $uri_options = $self->_uri->options;
1428 4384         33533 my $deferred = $self->_deferred;
1429 4384         10213 my ( $u, $e, $default ) = @spec{qw/u e d/};
1430             return
1431             exists $uri_options->{$u} ? $uri_options->{$u}
1432 4384 100       67760 : exists $deferred->{$e} ? $deferred->{$e}
    100          
1433             : $default;
1434             }
1435              
1436             sub __string {
1437 187     187   2164 local $_;
1438 187 100       595 my ($first) = grep { defined && length } @_;
  374         1884  
1439 187   100     3728 return $first || '';
1440             }
1441              
1442             #--------------------------------------------------------------------------#
1443             # public methods - network communication
1444             #--------------------------------------------------------------------------#
1445              
1446             #pod =method connect
1447             #pod
1448             #pod $client->connect;
1449             #pod
1450             #pod Calling this method is unnecessary, as connections are established
1451             #pod automatically as needed. It is kept for backwards compatibility. Calling it
1452             #pod will check all servers in the deployment which ensures a connection to any
1453             #pod that are available.
1454             #pod
1455             #pod See L for a method that is useful when using forks or threads.
1456             #pod
1457             #pod =cut
1458              
1459             sub connect {
1460 0     0 1   my ($self) = @_;
1461 0           $self->_topology->scan_all_servers;
1462 0           return 1;
1463             }
1464              
1465             #pod =method disconnect
1466             #pod
1467             #pod $client->disconnect;
1468             #pod
1469             #pod Drops all connections to servers.
1470             #pod
1471             #pod =cut
1472              
1473             sub disconnect {
1474 0     0 1   my ($self) = @_;
1475 0           $self->_topology->close_all_links;
1476 0           return 1;
1477             }
1478              
1479             #pod =method reconnect
1480             #pod
1481             #pod $client->reconnect;
1482             #pod
1483             #pod This method closes all connections to the server, as if L were
1484             #pod called, and then immediately reconnects. It also clears the session
1485             #pod cache. Use this after forking or spawning off a new thread.
1486             #pod
1487             #pod =cut
1488              
1489             sub reconnect {
1490 0     0 1   my ($self) = @_;
1491 0           $self->_topology->close_all_links;
1492 0           $self->_server_session_pool->reset_pool;
1493 0           $self->_topology->scan_all_servers(1);
1494 0           return 1;
1495             }
1496              
1497             #pod =method topology_status
1498             #pod
1499             #pod $client->topology_status;
1500             #pod $client->topology_status( refresh => 1 );
1501             #pod
1502             #pod Returns a hash reference with server topology information like this:
1503             #pod
1504             #pod {
1505             #pod 'topology_type' => 'ReplicaSetWithPrimary'
1506             #pod 'replica_set_name' => 'foo',
1507             #pod 'last_scan_time' => '1433766895.183241',
1508             #pod 'servers' => [
1509             #pod {
1510             #pod 'address' => 'localhost:50003',
1511             #pod 'ewma_rtt_ms' => '0.223462326',
1512             #pod 'type' => 'RSSecondary'
1513             #pod },
1514             #pod {
1515             #pod 'address' => 'localhost:50437',
1516             #pod 'ewma_rtt_ms' => '0.268435456',
1517             #pod 'type' => 'RSArbiter'
1518             #pod },
1519             #pod {
1520             #pod 'address' => 'localhost:50829',
1521             #pod 'ewma_rtt_ms' => '0.737782272',
1522             #pod 'type' => 'RSPrimary'
1523             #pod }
1524             #pod },
1525             #pod }
1526             #pod
1527             #pod If the 'refresh' argument is true, then the topology will be scanned
1528             #pod to update server data before returning the hash reference.
1529             #pod
1530             #pod =cut
1531              
1532             sub topology_status {
1533 0     0 1   my ($self, %opts) = @_;
1534 0 0         $self->_topology->scan_all_servers(1) if $opts{refresh};
1535 0           return $self->_topology->status_struct;
1536             }
1537              
1538             #pod =method start_session
1539             #pod
1540             #pod $client->start_session;
1541             #pod $client->start_session( $options );
1542             #pod
1543             #pod Returns a new L with the supplied options.
1544             #pod
1545             #pod will throw a C if sessions are not supported by
1546             #pod the connected MongoDB deployment.
1547             #pod
1548             #pod the options hash is an optional hash which can have the following keys:
1549             #pod
1550             #pod =for :list
1551             #pod * C - Enable Causally Consistent reads for this session.
1552             #pod Defaults to true.
1553             #pod
1554             #pod for more information see L.
1555             #pod
1556             #pod =cut
1557              
1558             sub start_session {
1559 0     0 1   my ( $self, $opts ) = @_;
1560              
1561 0 0         unless ( $self->_topology->_supports_sessions ) {
1562 0           MongoDB::ConfigurationError->throw( "Sessions are not supported by this MongoDB deployment" );
1563             }
1564              
1565 0           return $self->_start_client_session( 1, $opts );
1566             }
1567              
1568             sub _maybe_get_implicit_session {
1569 0     0     my ($self) = @_;
1570              
1571             # Dont return an error as implicit sessions need to be backwards compatible
1572 0 0         return undef unless $self->_topology->_supports_sessions; ## no critic
1573              
1574 0           return $self->_start_client_session(0);
1575             }
1576              
1577             sub _start_client_session {
1578 0     0     my ( $self, $is_explicit, $opts ) = @_;
1579              
1580 0   0       $opts ||= {};
1581              
1582 0           my $session = $self->_server_session_pool->get_server_session;
1583 0           return MongoDB::ClientSession->new(
1584             client => $self,
1585             options => $opts,
1586             _is_explicit => $is_explicit,
1587             server_session => $session,
1588             );
1589             }
1590              
1591             #--------------------------------------------------------------------------#
1592             # semi-private methods; these are public but undocumented and their
1593             # semantics might change in future releases
1594             #--------------------------------------------------------------------------#
1595              
1596             # Undocumented in old MongoDB::MongoClient; semantics don't translate, but
1597             # best approximation is checking if we can send a command to a server
1598             sub connected {
1599 0     0 0   my ($self) = @_;
1600 0           return eval { $self->send_admin_command([ismaster => 1]); 1 };
  0            
  0            
1601             }
1602              
1603             sub send_admin_command {
1604 0     0 0   my ( $self, $command, $read_pref ) = @_;
1605              
1606 0 0 0       $read_pref = MongoDB::ReadPreference->new(
    0          
1607             ref($read_pref) ? $read_pref : ( mode => $read_pref ) )
1608             if $read_pref && ref($read_pref) ne 'MongoDB::ReadPreference';
1609              
1610 0           my $op = MongoDB::Op::_Command->_new(
1611             db_name => 'admin',
1612             query => $command,
1613             query_flags => {},
1614             bson_codec => $self->bson_codec,
1615             read_preference => $read_pref,
1616             session => $self->_maybe_get_implicit_session,
1617             monitoring_callback => $self->monitoring_callback,
1618             );
1619              
1620 0           return $self->send_retryable_read_op( $op );
1621             }
1622              
1623             # Ostensibly the same as above, but allows for specific addressing - uses 'send_direct_op'.
1624             sub _send_direct_admin_command {
1625 0     0     my ( $self, $address, $command, $read_pref ) = @_;
1626              
1627 0 0 0       $read_pref = MongoDB::ReadPreference->new(
    0          
1628             ref($read_pref) ? $read_pref : ( mode => $read_pref ) )
1629             if $read_pref && ref($read_pref) ne 'MongoDB::ReadPreference';
1630              
1631 0           my $op = MongoDB::Op::_Command->_new(
1632             db_name => 'admin',
1633             query => $command,
1634             query_flags => {},
1635             bson_codec => $self->bson_codec,
1636             read_preference => $read_pref,
1637             session => $self->_maybe_get_implicit_session,
1638             monitoring_callback => $self->monitoring_callback,
1639             );
1640              
1641 0           return $self->send_direct_op( $op, $address );
1642             }
1643              
1644             #--------------------------------------------------------------------------#
1645             # database helper methods
1646             #--------------------------------------------------------------------------#
1647              
1648             #pod =method list_databases
1649             #pod
1650             #pod # get all information on all databases
1651             #pod my @dbs = $client->list_databases;
1652             #pod
1653             #pod # get only the foo databases
1654             #pod my @foo_dbs = $client->list_databases({ filter => { name => qr/^foo/ } });
1655             #pod
1656             #pod Lists all databases with information on each database. Supports filtering by
1657             #pod any of the output fields under the C argument, such as:
1658             #pod
1659             #pod =for :list
1660             #pod * C
1661             #pod * C
1662             #pod * C
1663             #pod * C
1664             #pod
1665             #pod =cut
1666              
1667             sub list_databases {
1668 0     0 1   my ( $self, $args ) = @_;
1669 0           my @databases;
1670             eval {
1671 0 0         my $output = $self->send_admin_command([ listDatabases => 1, ( $args ? %$args : () ) ])->output;
1672 0 0 0       if (ref($output) eq 'HASH' && exists $output->{databases}) {
1673 0           @databases = @{ $output->{databases} };
  0            
1674             }
1675 0           return 1;
1676 0 0         } or do {
1677 0   0       my $error = $@ || "Unknown error";
1678 0 0         if ( $error->$_isa("MongoDB::DatabaseError" ) ) {
1679 0 0         return if $error->result->output->{code} == CANT_OPEN_DB_IN_READ_LOCK();
1680             }
1681 0           die $error;
1682             };
1683 0           return @databases;
1684             }
1685              
1686             #pod =method database_names
1687             #pod
1688             #pod my @dbs = $client->database_names;
1689             #pod
1690             #pod # get only the foo database names
1691             #pod my @foo_dbs = $client->database_names({ filter => { name => qr/^foo/ } });
1692             #pod
1693             #pod List of all database names on the MongoDB server. Supports filters in the same
1694             #pod way as L.
1695             #pod
1696             #pod =cut
1697              
1698             sub database_names {
1699 0     0 1   my ( $self, $args ) = @_;
1700              
1701 0   0       $args ||= {};
1702 0           $args->{nameOnly} = 1;
1703 0           my @output = $self->list_databases($args);
1704              
1705 0           my @databases = map { $_->{name} } @output;
  0            
1706              
1707 0           return @databases;
1708             }
1709              
1710             #pod =method get_database, db
1711             #pod
1712             #pod my $database = $client->get_database('foo');
1713             #pod my $database = $client->get_database('foo', $options);
1714             #pod my $database = $client->db('foo', $options);
1715             #pod
1716             #pod Returns a L instance for the database with the given
1717             #pod C<$name>.
1718             #pod
1719             #pod It takes an optional hash reference of options that are passed to the
1720             #pod L constructor.
1721             #pod
1722             #pod The C method is an alias for C.
1723             #pod
1724             #pod =cut
1725              
1726             sub get_database {
1727 0     0 1   my ( $self, $database_name, $options ) = @_;
1728 0 0         return MongoDB::Database->new(
1729             read_preference => $self->read_preference,
1730             write_concern => $self->write_concern,
1731             read_concern => $self->read_concern,
1732             bson_codec => $self->bson_codec,
1733             max_time_ms => $self->max_time_ms,
1734             ( $options ? %$options : () ),
1735             # not allowed to be overridden by options
1736             _client => $self,
1737             name => $database_name,
1738             );
1739             }
1740              
1741 58     58   339252 { no warnings 'once'; *db = \&get_database }
  58         190  
  58         11790  
1742              
1743             #pod =method get_namespace, ns
1744             #pod
1745             #pod my $collection = $client->get_namespace('test.foo');
1746             #pod my $collection = $client->get_namespace('test.foo', $options);
1747             #pod my $collection = $client->ns('test.foo', $options);
1748             #pod
1749             #pod Returns a L instance for the given namespace.
1750             #pod The namespace has both the database name and the collection name
1751             #pod separated with a dot character.
1752             #pod
1753             #pod This is a quick way to get a collection object if you don't need
1754             #pod the database object separately.
1755             #pod
1756             #pod It takes an optional hash reference of options that are passed to the
1757             #pod L constructor. The intermediate L
1758             #pod object will be created with default options.
1759             #pod
1760             #pod The C method is an alias for C.
1761             #pod
1762             #pod =cut
1763              
1764             sub get_namespace {
1765 0     0 1   my ( $self, $ns, $options ) = @_;
1766 0 0 0       MongoDB::UsageError->throw("namespace requires a string argument")
1767             unless defined($ns) && length($ns);
1768 0           my ( $db, $coll ) = split /\./, $ns, 2;
1769 0 0 0       MongoDB::UsageError->throw("$ns is not a valid namespace")
1770             unless defined($db) && defined($coll);
1771 0           return $self->db($db)->coll( $coll, $options );
1772             }
1773              
1774 58     58   530 { no warnings 'once'; *ns = \&get_namespace }
  58         195  
  58         32814  
1775              
1776             #pod =method fsync(\%args)
1777             #pod
1778             #pod $client->fsync();
1779             #pod
1780             #pod A function that will forces the server to flush all pending writes to the storage layer.
1781             #pod
1782             #pod The fsync operation is synchronous by default, to run fsync asynchronously, use the following form:
1783             #pod
1784             #pod $client->fsync({async => 1});
1785             #pod
1786             #pod The primary use of fsync is to lock the database during backup operations. This will flush all data to the data storage layer and block all write operations until you unlock the database. Note: you can still read while the database is locked.
1787             #pod
1788             #pod $conn->fsync({lock => 1});
1789             #pod
1790             #pod =cut
1791              
1792             sub fsync {
1793 0     0 1   my ($self, $args) = @_;
1794              
1795 0   0       $args ||= {};
1796              
1797             # Pass this in as array-ref to ensure that 'fsync => 1' is the first argument.
1798 0           return $self->get_database('admin')->run_command([fsync => 1, %$args]);
1799             }
1800              
1801             #pod =method fsync_unlock
1802             #pod
1803             #pod $conn->fsync_unlock();
1804             #pod
1805             #pod Unlocks a database server to allow writes and reverses the operation of a $conn->fsync({lock => 1}); operation.
1806             #pod
1807             #pod =cut
1808              
1809             sub fsync_unlock {
1810 0     0 1   my ($self) = @_;
1811              
1812 0           my $op = MongoDB::Op::_FSyncUnlock->_new(
1813             db_name => 'admin',
1814             client => $self,
1815             bson_codec => $self->bson_codec,
1816             monitoring_callback => $self->monitoring_callback,
1817             );
1818              
1819 0           return $self->send_primary_op($op);
1820             }
1821              
1822             sub _get_session_from_hashref {
1823 0     0     my ( $self, $hashref ) = @_;
1824              
1825 0           my $session = delete $hashref->{session};
1826              
1827 0 0         if ( defined $session ) {
1828 0 0         MongoDB::UsageError->throw( "Cannot use session from another client" )
1829             if ( $session->client->_id ne $self->_id );
1830 0 0         MongoDB::UsageError->throw( "Cannot use session which has ended" )
1831             if ! defined $session->session_id;
1832             } else {
1833 0           $session = $self->_maybe_get_implicit_session;
1834             }
1835              
1836 0           return $session;
1837             }
1838              
1839             #pod =method watch
1840             #pod
1841             #pod Watches for changes on the cluster.
1842             #pod
1843             #pod Perform an aggregation with an implicit initial C<$changeStream> stage
1844             #pod and returns a L result which can be used to
1845             #pod iterate over the changes in the cluster. This functionality is
1846             #pod available since MongoDB 4.0.
1847             #pod
1848             #pod my $stream = $client->watch();
1849             #pod my $stream = $client->watch( \@pipeline );
1850             #pod my $stream = $client->watch( \@pipeline, \%options );
1851             #pod
1852             #pod while (1) {
1853             #pod
1854             #pod # This inner loop will only run until no more changes are
1855             #pod # available.
1856             #pod while (my $change = $stream->next) {
1857             #pod # process $change
1858             #pod }
1859             #pod }
1860             #pod
1861             #pod The returned stream will not block forever waiting for changes. If you
1862             #pod want to respond to changes over a longer time use C and
1863             #pod regularly call C in a loop.
1864             #pod
1865             #pod See L for details on usage and available
1866             #pod options.
1867             #pod
1868             #pod =cut
1869              
1870             sub watch {
1871 0     0 1   my ( $self, $pipeline, $options ) = @_;
1872              
1873 0   0       $pipeline ||= [];
1874 0   0       $options ||= {};
1875              
1876 0           my $session = $self->_get_session_from_hashref( $options );
1877              
1878             return MongoDB::ChangeStream->new(
1879             exists($options->{startAtOperationTime})
1880             ? (start_at_operation_time => delete $options->{startAtOperationTime})
1881             : (),
1882             exists($options->{fullDocument})
1883             ? (full_document => delete $options->{fullDocument})
1884             : (full_document => 'default'),
1885             exists($options->{resumeAfter})
1886             ? (resume_after => delete $options->{resumeAfter})
1887             : (),
1888             exists($options->{startAfter})
1889             ? (start_after => delete $options->{startAfter})
1890             : (),
1891             exists($options->{maxAwaitTimeMS})
1892             ? (max_await_time_ms => delete $options->{maxAwaitTimeMS})
1893 0 0         : (),
    0          
    0          
    0          
    0          
1894             client => $self,
1895             all_changes_for_cluster => 1,
1896             pipeline => $pipeline,
1897             session => $session,
1898             options => $options,
1899             op_args => {
1900             read_concern => $self->read_concern,
1901             db_name => 'admin',,
1902             coll_name => 1,
1903             full_name => 'admin.1',
1904             bson_codec => $self->bson_codec,
1905             write_concern => $self->write_concern,
1906             read_concern => $self->read_concern,
1907             read_preference => $self->read_preference,
1908             monitoring_callback => $self->monitoring_callback,
1909             },
1910             );
1911             }
1912              
1913             sub _primary_server_version {
1914 0     0     my $self = shift;
1915 0           my $build = $self->send_admin_command( [ buildInfo => 1 ] )->output;
1916 0           my ($version_str) = $build->{version} =~ m{^([0-9.]+)};
1917 0           return version->parse("v$version_str");
1918             }
1919              
1920             1;
1921              
1922             __END__