From 5f87a9ec07915fd9540e876567011336c1b0d8a9 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Wed, 24 Mar 2021 10:31:13 -0500 Subject: [PATCH 1/2] Fix course archival procedures (or anything that calls _get_db_info in Std.pm. The code in sql_single.pm is modified in the same way for consistency (althought that wasn't broken). The modification is to always use the new parsing of the DSN string regardless of the DBD driver used. --- lib/WeBWorK/DB/Schema/NewSQL/Std.pm | 9 +++------ lib/WeBWorK/Utils/CourseManagement/sql_single.pm | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/WeBWorK/DB/Schema/NewSQL/Std.pm b/lib/WeBWorK/DB/Schema/NewSQL/Std.pm index 5db40d7ae0..6824a2f718 100644 --- a/lib/WeBWorK/DB/Schema/NewSQL/Std.pm +++ b/lib/WeBWorK/DB/Schema/NewSQL/Std.pm @@ -271,18 +271,15 @@ sub _get_db_info { my $password = $self->{params}{password}; my %dsn; - if ( $dsn =~ m/^dbi:mariadb:/i ) { + if ($dsn =~ m/^dbi:mariadb:/i || $dsn =~ m/^dbi:mysql:/i) { # Expect DBI:MariaDB:database=webwork;host=db;port=3306 + # or DBI:mysql:database=webwork;host=db;port=3306 + # The host and port are optional. my ($dbi,$dbtype,$temp1) = split(':',$dsn); ( $dsn{database}, $dsn{host}, $dsn{port} ) = split(';',$temp1); $dsn{database} =~ s/database=//; $dsn{host} =~ s/host=// if ( defined $dsn{host} ); $dsn{port} =~ s/port=// if ( defined $dsn{port} ); - } elsif ( $dsn =~ m/^dbi:mysql:/i ) { - # This code works for DBD::mysql - # this is an internal function which we probably shouldn't be using here - # but it's quick and gets us what we want (FIXME what about sockets, etc?) - DBD::mysql->_OdbcParse($dsn, \%dsn, ['database', 'host', 'port']); } else { die "Can't call dump_table or restore_table on a table with a non-MySQL/MariaDB source"; } diff --git a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm b/lib/WeBWorK/Utils/CourseManagement/sql_single.pm index 82480dcaac..b55f2bf354 100644 --- a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm +++ b/lib/WeBWorK/Utils/CourseManagement/sql_single.pm @@ -199,7 +199,7 @@ sub _get_db_info { my %dsn; if ( $dsn =~ s/^dbi:mariadb://i ) { my ($dbi,$dbtype,$temp1) = split(':',$dsn); - ( $dsn{database}, $dsn{host}, $dsn{port} ) = split(';',$db); + ( $dsn{database}, $dsn{host}, $dsn{port} ) = split(';',$temp1); $dsn{database} =~ s/database=//; $dsn{host} =~ s/host=// if ( defined $dsn{host} ); $dsn{port} =~ s/port=// if ( defined $dsn{port} ); From 3ba4640cf3b41c82c03ab951fabe43ccb701eb34 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Wed, 24 Mar 2021 23:07:13 -0500 Subject: [PATCH 2/2] Switch to a new more versatile method of dns parsing (that is actually much more like the method used in the _OdbcParse method used before). This allows for things like `dbi:MariaDB:database=webwork;mariadb_socket=/var/run/mysqld/mysqld.conf` which Ubuntu 18.04 will need to use the cpan DBD::MariaDB package due to a bug in the mariadb_config output. --- lib/WeBWorK/DB/Schema/NewSQL/Std.pm | 18 ++++++++----- .../Utils/CourseManagement/sql_single.pm | 27 ++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lib/WeBWorK/DB/Schema/NewSQL/Std.pm b/lib/WeBWorK/DB/Schema/NewSQL/Std.pm index 6824a2f718..718eb3e294 100644 --- a/lib/WeBWorK/DB/Schema/NewSQL/Std.pm +++ b/lib/WeBWorK/DB/Schema/NewSQL/Std.pm @@ -275,15 +275,21 @@ sub _get_db_info { # Expect DBI:MariaDB:database=webwork;host=db;port=3306 # or DBI:mysql:database=webwork;host=db;port=3306 # The host and port are optional. - my ($dbi,$dbtype,$temp1) = split(':',$dsn); - ( $dsn{database}, $dsn{host}, $dsn{port} ) = split(';',$temp1); - $dsn{database} =~ s/database=//; - $dsn{host} =~ s/host=// if ( defined $dsn{host} ); - $dsn{port} =~ s/port=// if ( defined $dsn{port} ); + my ($dbi, $dbtype, $dsn_opts) = split(':', $dsn); + while (length($dsn_opts)) { + if ($dsn_opts =~ /^([^=]*)=([^;]*);(.*)$/) { + $dsn{$1} = $2; + $dsn_opts = $3; + } else { + my ($var, $val) = $dsn_opts =~ /^([^=]*)=([^;]*)$/; + $dsn{$var} = $val; + $dsn_opts = ''; + } + } } else { die "Can't call dump_table or restore_table on a table with a non-MySQL/MariaDB source"; } - + die "no database specified in DSN!" unless defined $dsn{database}; my $mysqldump = $self->{params}{mysqldump_path}; diff --git a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm b/lib/WeBWorK/Utils/CourseManagement/sql_single.pm index b55f2bf354..b4a00f4cfc 100644 --- a/lib/WeBWorK/Utils/CourseManagement/sql_single.pm +++ b/lib/WeBWorK/Utils/CourseManagement/sql_single.pm @@ -197,18 +197,21 @@ sub _get_db_info { my $password = $ce->{database_password}; my %dsn; - if ( $dsn =~ s/^dbi:mariadb://i ) { - my ($dbi,$dbtype,$temp1) = split(':',$dsn); - ( $dsn{database}, $dsn{host}, $dsn{port} ) = split(';',$temp1); - $dsn{database} =~ s/database=//; - $dsn{host} =~ s/host=// if ( defined $dsn{host} ); - $dsn{port} =~ s/port=// if ( defined $dsn{port} ); - } elsif ( $dsn =~ s/^dbi:mysql://i ) { - # This code works for DBD::mysql - # this is an internal function which we probably shouldn't be using here - # but it's quick and gets us what we want (FIXME what about sockets, etc?) - runtime_use "DBD::mysql"; - DBD::mysql->_OdbcParse($dsn, \%dsn, ['database', 'host', 'port']); + if ($dsn =~ m/^dbi:mariadb:/i || $dsn =~ m/^dbi:mysql:/i) { + # Expect DBI:MariaDB:database=webwork;host=db;port=3306 + # or DBI:mysql:database=webwork;host=db;port=3306 + # The host and port are optional. + my ($dbi, $dbtype, $dsn_opts) = split(':', $dsn); + while (length($dsn_opts)) { + if ($dsn_opts =~ /^([^=]*)=([^;]*);(.*)$/) { + $dsn{$1} = $2; + $dsn_opts = $3; + } else { + my ($var, $val) = $dsn_opts =~ /^([^=]*)=([^;]*)$/; + $dsn{$var} = $val; + $dsn_opts = ''; + } + } } else { die "Can't call dump_table or restore_table on a table with a non-MySQL/MariaDB source"; }