From 143476dc5a9fe961247b791d0fcefc40e5e34a4c Mon Sep 17 00:00:00 2001 From: Bob Kleemann Date: Wed, 20 Mar 2019 09:57:24 -0700 Subject: [PATCH 1/2] Create tests for the refactor of parse_dsn() --- t/parse_dsn.t | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 t/parse_dsn.t diff --git a/t/parse_dsn.t b/t/parse_dsn.t new file mode 100644 index 00000000..e091c6bc --- /dev/null +++ b/t/parse_dsn.t @@ -0,0 +1,39 @@ +use strict; +use warnings; + +use Test::Deep; +use Test::More; +use DBD::MariaDB; + +plan tests => 8; + +my @dsn_localhost_test = qw( + db=test;hostname=localhost;port=3306 + dbname=test;host=localhost;port=3306 + database=test;host=localhost:3306 + test:localhost:3306 + test:localhost:3306;notarealdb:notarealhost:1234 + notarealdb:notarealhost:1234;database=test;host=localhost;port=3306 + database=test;host=localhost;port=3306;notarealdb:notarealhost:1234 +); +my %attrs_localhost_test = ( + database => 'test', + host => 'localhost', + port => 3306, +); +foreach my $dsn (@dsn_localhost_test) { + my $attrs = DBD::MariaDB->parse_dsn($dsn); + cmp_deeply($attrs, \%attrs_localhost_test, "$dsn parsed correctly"); +} + +{ + my %attrs_ipv6_test = ( + database => 'test', + host => '::1', + port => 3306, + ); + my $dsn = 'database=test;host=[::1]:3306'; + my $attrs = DBD::MariaDB->parse_dsn($dsn); + cmp_deeply($attrs, \%attrs_ipv6_test, "$dsn parsed correctly"); +} + From 74307af43f8c6d8019ebb46e542d6f67cf51c64e Mon Sep 17 00:00:00 2001 From: Bob Kleemann Date: Wed, 20 Mar 2019 09:57:47 -0700 Subject: [PATCH 2/2] Refactor parse_dsn() for clarity and efficiency --- lib/DBD/MariaDB.pm | 54 +++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/lib/DBD/MariaDB.pm b/lib/DBD/MariaDB.pm index d5bf0812..219cce8c 100644 --- a/lib/DBD/MariaDB.pm +++ b/lib/DBD/MariaDB.pm @@ -64,38 +64,32 @@ sub CLONE { sub parse_dsn { my ($class, $dsn) = @_; + my $hash = {}; - my($var, $val); - if (!defined($dsn)) { - return $hash; - } while (length($dsn)) { - if ($dsn =~ /([^:;]*\[.*]|[^:;]*)[:;](.*)/) { - $val = $1; - $dsn = $2; - $val =~ s/\[|]//g; # Remove [] if present, the rest of the code prefers plain IPv6 addresses - } else { - $val = $dsn; - $dsn = ''; - } - if ($val =~ /([^=]*)=(.*)/) { - $var = $1; - $val = $2; - if ($var eq 'hostname' || $var eq 'host') { - $hash->{'host'} = $val; - } elsif ($var eq 'db' || $var eq 'dbname') { - $hash->{'database'} = $val; - } else { - $hash->{$var} = $val; - } - } else { - foreach $var (qw(database host port)) { - if (!defined($hash->{$var})) { - $hash->{$var} = $val; - last; - } - } - } + my $part; + if ($dsn =~ /([^:;]*\[[^\]]*\]|[^:;]*)[:;](.*)/) { + ($part, $dsn) = ($1, $2); + $part =~ tr/\[\]//d; # Remove [] if present, the rest of the code prefers plain IPv6 addresses + } else { + ($part, $dsn) = ($dsn, ''); + } + if ($part =~ /([^=]*)=(.*)/) { + my ($var, $val) = ($1, $2); + # These are legacy, do not change, and do not add + if ( $var eq 'db' || $var eq 'dbname' ) { + $var = 'database'; + } elsif ( $var eq 'hostname' ) { + $var = 'host'; + } + $hash->{$var} = $val; + } else { + foreach my $var (qw(database host port)) { + next if defined($hash->{$var}); + $hash->{$var} = $part; + last; + } + } } return $hash; }