File Coverage

blib/lib/MongoDB/ReadPreference.pm
Criterion Covered Total %
statement 48 49 97.9
branch 11 14 78.5
condition 7 9 77.7
subroutine 13 13 100.0
pod 0 3 0.0
total 79 88 89.7


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 61     61   1122 use strict;
  61         128  
  61         1851  
16 61     61   320 use warnings;
  61         123  
  61         1968  
17             package MongoDB::ReadPreference;
18              
19             # ABSTRACT: Encapsulate and validate read preferences
20              
21 61     61   737 use version;
  61         1914  
  61         344  
22             our $VERSION = 'v2.2.1';
23              
24 61     61   5198 use Moo;
  61         10807  
  61         314  
25 61     61   21257 use MongoDB::Error;
  61         184  
  61         7208  
26 61         454 use MongoDB::_Types qw(
27             ArrayOfHashRef
28             MaxStalenessNum
29             NonNegNum
30             ReadPrefMode
31 61     61   470 );
  61         139  
32 61     61   89690 use namespace::clean -except => 'meta';
  61         130  
  61         406  
33              
34             use overload (
35 222     222   872 q[""] => sub { $_[0]->mode },
36 61         624 fallback => 1,
37 61     61   41749 );
  61         136  
38              
39             #pod =attr mode
40             #pod
41             #pod The read preference mode determines which server types are candidates
42             #pod for a read operation. Valid values are:
43             #pod
44             #pod =for :list
45             #pod * primary
46             #pod * primaryPreferred
47             #pod * secondary
48             #pod * secondaryPreferred
49             #pod * nearest
50             #pod
51             #pod =cut
52              
53             has mode => (
54             is => 'ro',
55             isa => ReadPrefMode,
56             default => 'primary',
57             coerce => ReadPrefMode->coercion,
58             );
59              
60             #pod =attr tag_sets
61             #pod
62             #pod The C parameter is an ordered list of tag sets used to restrict the
63             #pod eligibility of servers, such as for data center awareness.
64             #pod
65             #pod The application of C varies depending on the C parameter. If
66             #pod the C is 'primary', then C must not be supplied.
67             #pod
68             #pod =cut
69              
70             has tag_sets => (
71             is => 'ro',
72             isa => ArrayOfHashRef,
73             default => sub { [ {} ] },
74             coerce => ArrayOfHashRef->coercion,
75             );
76              
77             #pod =attr max_staleness_seconds
78             #pod
79             #pod The C parameter represents the maximum replication lag in
80             #pod seconds (wall clock time) that a secondary can suffer and still be
81             #pod eligible for reads. The default is -1, which disables staleness checks.
82             #pod
83             #pod If the C is 'primary', then C must not be supplied.
84             #pod
85             #pod =cut
86              
87             has max_staleness_seconds => (
88             is => 'ro',
89             isa => MaxStalenessNum,
90             default => -1,
91             );
92              
93             sub BUILD {
94 509     509 0 89064 my ($self) = @_;
95              
96 509 100 100     3066 if ( $self->mode eq 'primary' && !$self->has_empty_tag_sets ) {
97 1         13 MongoDB::UsageError->throw("A tag set list is not allowed with read preference mode 'primary'");
98             }
99              
100 508 100 100     2847 if ( $self->mode eq 'primary' && $self->max_staleness_seconds > 0 ) {
101 4         29 MongoDB::UsageError->throw("A positive max_staleness_seconds is not allowed with read preference mode 'primary'");
102             }
103              
104 504         5223 return;
105             }
106              
107             # Returns true if the C array is empty or if it consists only of a
108             # single, empty hash reference.
109              
110             sub has_empty_tag_sets {
111 459     459 0 1108 my ($self) = @_;
112 459         1299 my $tag_sets = $self->tag_sets;
113 459   33     2359 return @$tag_sets == 0 || ( @$tag_sets == 1 && !keys %{ $tag_sets->[0] } );
114             }
115              
116             # Reformat to the document needed by mongos in $readPreference
117              
118             sub _as_hashref {
119 120     120   325 my ($self) = @_;
120             return {
121 120 50       387 mode => $self->mode,
    50          
122             ( $self->has_empty_tag_sets ? () : ( tags => $self->tag_sets ) ),
123             ( $self->max_staleness_seconds > 0 ? ( maxStalenessSeconds => int($self->max_staleness_seconds )) : () ),
124             };
125             }
126              
127             # Format as a string for error messages
128              
129             sub as_string {
130 3     3 0 18 my ($self) = @_;
131 3         7 my $string = $self->mode;
132 3 100       7 unless ( $self->has_empty_tag_sets ) {
133 1         2 my @ts;
134 1         49 for my $set ( @{ $self->tag_sets } ) {
  1         9  
135 3 100       16 push @ts, keys(%$set) ? join( ",", map { "$_\:$set->{$_}" } sort keys %$set ) : "";
  3         15  
136             }
137 1         3 $string .= " (" . join( ",", map { "{$_}" } @ts ) . ")";
  3         10  
138             }
139 3 50       82 if ( $self->max_staleness_seconds > 0) {
140 0         0 $string .= " ( maxStalenessSeconds: " . $self->max_staleness_seconds . " )";
141             }
142 3         13 return $string;
143             }
144              
145              
146             1;
147              
148             __END__