Skip to content

Commit

Permalink
make read_preference a public attribute, not a role
Browse files Browse the repository at this point in the history
This eliminates the _HasReadPreference role.

For MongoClient, read_preference is now a public attribute, with a
somewhat backwards compatible accessor.  For Cursor, read_preference is
a private attribute, but with a public method that overrides it, which
is mostly backwards compatible.
  • Loading branch information
xdg committed Nov 10, 2014
1 parent 2c5c8d5 commit 40f0075
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 76 deletions.
61 changes: 50 additions & 11 deletions lib/MongoDB/Cursor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ after the database is queried.
=cut

with 'MongoDB::Role::_HasReadPreference', 'MongoDB::Role::_Cursor';
with 'MongoDB::Role::_Cursor';

# general attributes

Expand Down Expand Up @@ -160,6 +160,19 @@ has _query_options => (
default => sub { { slave_ok => !! $MongoDB::Cursor::slave_okay } },
);

has _read_preference => (
is => 'ro',
isa => 'ReadPreference',
lazy => 1,
builder => '_build__read_preference',
writer => '_set_read_preference',
);

sub _build__read_preference {
my ($self) = @_;
return $self->_client->read_preference;
}

# lazy result attribute
has result => (
is => 'ro',
Expand All @@ -181,7 +194,7 @@ sub _build_result {
$self->_limit,
$self->_batch_size,
$self->_query_options,
( $self->_has_read_preference ? $self->_read_preference : () )
$self->_read_preference,
);
}

Expand Down Expand Up @@ -434,23 +447,49 @@ sub partial {
return $self;
}

=head2 read_preference ($mode, $tag_sets)
=head2 read_preference
my $cursor = $coll->find()->read_preference($read_preference_object);
my $cursor = $coll->find()->read_preference(MongoDB::MongoClient->PRIMARY_PREFERRED, [{foo => 'bar'}]);
Sets read preference for the cursor's connection. The $mode argument
should be a constant in MongoClient (PRIMARY, PRIMARY_PREFERRED, SECONDARY,
SECONDARY_PREFERRED, NEAREST). The $tag_sets specify selection criteria for secondaries
in a replica set and should be an ArrayRef whose array elements are HashRefs.
This is a convenience method which is identical in function to
L<MongoDB::MongoClient/read_preference>.
In order to use read preference, L<MongoDB::MongoClient/find_master> must be set.
For core documentation on read preference see L<http://docs.mongodb.org/manual/core/read-preference/>.
Sets read preference for the cursor's connection.
If given a single argument that is a L<MongoDB::ReadPreference> object, the
read preference is set to that object. Otherwise, it takes positional
arguments: the read preference mode and a tag set list.
The mode argument should be a constant in MongoClient (PRIMARY,
PRIMARY_PREFERRED, SECONDARY, SECONDARY_PREFERRED, NEAREST). The tag set list
specifies selection criteria for secondaries in a replica set and should be an
array reference whose array elements are hash references.
For core documentation on read preference see
L<http://docs.mongodb.org/manual/core/read-preference/>.
Returns $self so that this method can be chained.
=cut

sub read_preference {
my $self = shift;

my $type = ref $_[0];
if ( $type eq 'MongoDB::ReadPreference' ) {
$self->_set_read_preference( $_[0] );
}
else {
my $mode = shift || 'primary';
my $tag_sets = shift;
my $rp = MongoDB::ReadPreference->new(
mode => $mode,
( $tag_sets ? ( tag_sets => $tag_sets ) : () )
);
$self->_set_read_preference($rp);
}

return $self;
}

=head2 slave_okay
$cursor->slave_okay(1);
Expand Down
39 changes: 38 additions & 1 deletion lib/MongoDB/MongoClient.pm
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use constant {
NEAREST => 'nearest',
};

with 'MongoDB::Role::_Client', 'MongoDB::Role::_HasReadPreference';
with 'MongoDB::Role::_Client';

#--------------------------------------------------------------------------#
# public attributes
Expand Down Expand Up @@ -130,6 +130,43 @@ has server_selection_timeout_ms => (
default => 30_000,
);

has read_preference => (
is => 'bare', # public reader implemented manually for back-compatibility
isa => 'ReadPreference',
reader => '_get_read_preference',
writer => '_set_read_preference',
coerce => 1,
lazy => 1,
builder => '_build__read_preference',
);

sub _build__read_preference {
my ($self) = @_;
return MongoDB::ReadPreference->new;
}

sub read_preference {
my $self = shift;

if ( @_ ) {
my $type = ref $_[0];
if ( $type eq 'MongoDB::ReadPreference' ) {
$self->_set_read_preference( $_[0] );
}
else {
my $mode = shift || 'primary';
my $tag_sets = shift;
my $rp = MongoDB::ReadPreference->new(
mode => $mode,
( $tag_sets ? ( tag_sets => $tag_sets ) : () )
);
$self->_set_read_preference($rp);
}
}

return $self->_get_read_preference;
}

# authentication attributes

has username => (
Expand Down
59 changes: 0 additions & 59 deletions lib/MongoDB/Role/_HasReadPreference.pm

This file was deleted.

7 changes: 2 additions & 5 deletions t/readpref.t
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ subtest "read preference connection string" => sub {
"mongodb://localhost/?readPreference=primaryPreferred&readPreferenceTags=dc:ny,rack:1&readPreferenceTags=dc:ny&readPreferenceTags=",
auto_connect => 0
);
my $rp = $conn2->_read_preference;
my $rp = $conn2->read_preference;
is( $rp->mode, 'primaryPreferred', "mode from" );
is_deeply(
$rp->tag_sets,
Expand Down Expand Up @@ -76,11 +76,8 @@ subtest "read preference on cursor" => sub {
};

subtest "argument variants" => sub {
$conn->read_preference();
is( $conn->_read_preference->mode, 'primary', "read pref mode defaults to primary" );

$conn->read_preference( MongoDB::ReadPreference->new( mode => 'secondary_preferred' ) );
is( $conn->_read_preference->mode, 'secondaryPreferred', "read pref from object" );
is( $conn->read_preference->mode, 'secondaryPreferred', "read pref from object" );
};


Expand Down

0 comments on commit 40f0075

Please sign in to comment.