our
$VERSION
=
'v0.999.998.6'
;
my
$uri_re
= MongoDB::_Types::connection_uri_re();
has
uri
=> (
is
=>
'ro'
,
isa
=> ConnectionStr,
required
=> 1,
);
has
username
=> (
is
=>
'ro'
,
isa
=> Str,
writer
=>
'_set_username'
,
default
=>
''
,
);
has
password
=> (
is
=>
'ro'
,
isa
=> Str,
writer
=>
'_set_password'
,
default
=>
''
,
);
has
db_name
=> (
is
=>
'ro'
,
isa
=> Str,
writer
=>
'_set_db_name'
,
default
=>
''
,
);
has
options
=> (
is
=>
'ro'
,
isa
=> HashRef,
writer
=>
'_set_options'
,
default
=>
sub
{ {} },
);
has
hostpairs
=> (
is
=>
'ro'
,
isa
=> ArrayRef,
writer
=>
'_set_hostpairs'
,
default
=>
sub
{ [] },
);
sub
_unescape_all {
my
$str
=
shift
;
return
''
unless
defined
$str
;
$str
=~ s/%([0-9a-f]{2})/
chr
(
hex
($1))/ieg;
return
$str
;
}
sub
_parse_tag_set {
my
(
$string
) =
@_
;
my
$set
= {};
for
my
$tag
(
split
/,/,
$string
) {
if
(
$tag
=~ /\S/ ) {
my
@kv
=
map
{ s{^\s*}{}; s{\s*$}{};
$_
}
split
/:/,
$tag
, 2;
MongoDB::UsageError->throw(
"readPreferenceTagSet '$tag' is not a key:value pair"
)
unless
@kv
== 2;
$set
->{
$kv
[0]} =
$kv
[1];
}
}
return
$set
;
}
sub
BUILD {
my
(
$self
) =
@_
;
my
$uri
=
$self
->uri;
my
%result
;
if
(
$uri
=~ m{^
$uri_re
$}) {
(
$result
{username},
$result
{password},
$result
{hostpairs},
$result
{db_name},
$result
{options}) = ($1, $2, $3, $4, $5);
for
my
$subcomponent
(
qw/username password db_name/
) {
$result
{
$subcomponent
} = _unescape_all(
$result
{
$subcomponent
})
unless
!(
defined
$result
{
$subcomponent
});
}
$result
{hostpairs} =
'localhost'
unless
$result
{hostpairs};
$result
{hostpairs} = [
map
{
lc
$_
}
map
{
@_
=
split
':'
,
$_
; _unescape_all(
$_
[0]).
":"
._unescape_all(
$_
[1]) }
map
{
$_
.=
':27017'
unless
$_
=~ /:/ ;
$_
}
split
','
,
$result
{hostpairs}
];
if
(
defined
$result
{options} ) {
my
%parsed
;
for
my
$opt
(
split
'&'
,
$result
{options} ) {
my
@kv
=
split
'='
,
$opt
;
push
@kv
,
''
if
@kv
== 1;
MongoDB::UsageError->throw(
"expected key value pair"
)
unless
@kv
== 2;
my
(
$k
,
$v
) =
map
{ _unescape_all(
$_
) }
@kv
;
if
(
$k
eq
'readPreferenceTags'
) {
$parsed
{
$k
} ||= [];
push
@{
$parsed
{
$k
}}, _parse_tag_set(
$v
);
}
else
{
$parsed
{
$k
} =
$v
;
}
}
$result
{options} = \
%parsed
;
}
delete
$result
{username}
unless
defined
$result
{username} &&
length
$result
{username};
delete
$result
{password}
unless
defined
$result
{password};
delete
$result
{db_name}
unless
defined
$result
{db_name} &&
length
$result
{db_name};
}
else
{
MongoDB::UsageError->throw(
"URI '$uri' could not be parsed"
);
}
for
my
$attr
(
qw/username password db_name options hostpairs/
) {
my
$setter
=
"_set_$attr"
;
$self
->
$setter
(
$result
{
$attr
} )
if
defined
$result
{
$attr
};
}
return
;
}
'""'
=>
sub
{
$_
[0]->uri },
'fallback'
=> 1;
__PACKAGE__->meta->make_immutable;
1;