From 03379b005285f4481ac17a2740c84e6bb921799a Mon Sep 17 00:00:00 2001 From: Ilia Ross Date: Tue, 16 Dec 2025 13:56:27 +0200 Subject: [PATCH] Add ability to use correct driver depending on the database --- mysql/cpan_modules.pl | 3 +-- mysql/index.cgi | 25 +++++++++++++-------- mysql/lang/en | 2 ++ mysql/mysql-lib.pl | 52 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/mysql/cpan_modules.pl b/mysql/cpan_modules.pl index 7f5cd9e11..de962b378 100755 --- a/mysql/cpan_modules.pl +++ b/mysql/cpan_modules.pl @@ -3,6 +3,5 @@ require 'mysql-lib.pl'; sub cpan_recommended { -return ( "DBI", $mysql_version =~ /mariadb/ ? "DBD::MariaDB" : "DBD::mysql" ); +return ( "DBI", $mysql_version =~ /mariadb/i ? "DBD::MariaDB" : "DBD::mysql" ); } - diff --git a/mysql/index.cgi b/mysql/index.cgi index d8f1f4ebd..55d923386 100755 --- a/mysql/index.cgi +++ b/mysql/index.cgi @@ -320,19 +320,26 @@ else { if (foreign_available("cpan")) { eval "use DBI"; push(@needs, "DBI") if ($@); - eval "use DBD::mysql"; - if ($@) { - eval "use DBD::MariaDB"; - if ($@) { - push(@needs, $mysql_version =~ /mariadb/ ? "DBD::MariaDB" - : "DBD::mysql"); - } - } + push(@needs, $driver_info->{prefer}) if (!$driver_info->{avail}); if (@needs) { $needs = &urlize(join(" ", @needs)); print &ui_alert_box(&text(@needs == 2 ? 'index_nomods' : 'index_nomod', @needs, "../cpan/download.cgi?source=3&cpan=$needs&mode=2&return=/$module_name/&returndesc=". - &urlize($text{'index_return'})), 'warn'); + &urlize($text{'index_return'})), 'warn', + undef, undef, ""); + } + } + # No CPAN module, just check for the driver + else { + eval "use DBI"; + push(@needs, "DBI") if ($@); + push(@needs, $driver_info->{prefer}) if (!$driver_info->{avail}); + if (@needs) { + print &ui_alert_box( + &text(@needs == 2 + ? 'index_nomods_manual' + : 'index_nomod_manual', @needs), 'warn', + undef, undef, ""); } } } diff --git a/mysql/lang/en b/mysql/lang/en index d76619928..ab6903010 100644 --- a/mysql/lang/en +++ b/mysql/lang/en @@ -30,6 +30,8 @@ index_version=$2 version $1 index_version2=$3 version $1 on $2 index_nomod=The Perl module $1 is not installed on your system, so Webmin will not be able to reliably access your MySQL database. Click here to install it now. index_nomods=The Perl modules $1 and $2 are not installed on your system, so Webmin will not be able to reliably access your MySQL database. Click here to install them now. +index_nomod_manual=The Perl module $1 is not installed on your system, so Webmin will not be able to reliably access your MySQL database. Install it manually using your package manager. +index_nomods_manual=The Perl modules $1 and $2 are not installed on your system, so Webmin will not be able to reliably access your MySQL database. Install them manually using your package manager. index_mysqlver=The command $1 returned : index_eenvpass=The MySQL client program $1 does not accept passwords passed using the MYSQL_PWD environment variable. To ensure that Webmin is able to fully communicate with MySQL, this option should be turned off on the module configuration page. Alternately, you can remove any password set in the root user's .my.cnf file. index_ecnf=The MySQL config file $1 was not found on your system. Use the module configuration page to set the correct path. diff --git a/mysql/mysql-lib.pl b/mysql/mysql-lib.pl index 95459de96..f7d060f9a 100755 --- a/mysql/mysql-lib.pl +++ b/mysql/mysql-lib.pl @@ -67,13 +67,44 @@ $password_func = $config{'passwd_mode'} ? "old_password" : "password"; 'enum', 'set'); @priv_cols = ('Host', 'User', 'Password', 'Select_priv', 'Insert_priv', 'Update_priv', 'Delete_priv', 'Create_priv', 'Drop_priv', 'Reload_priv', 'Shutdown_priv', 'Process_priv', 'File_priv', 'Grant_priv', 'References_priv', 'Index_priv', 'Alter_priv', 'Show_db_priv', 'Super_priv', 'Create_tmp_table_priv', 'Lock_tables_priv', 'Execute_priv', 'Repl_slave_priv', 'Repl_client_priv', 'Create_view_priv', 'Show_view_priv', 'Create_routine_priv', 'Alter_routine_priv', 'Create_user_priv'); - +$driver_info = &dbi_driver_info(); if (!$config{'nodbi'}) { - # Check if we have DBI::mysql - eval <install_driver("mysql"); -EOF + # Check if we have DBI::mysql or DBI::MariaDB + eval { require DBI; + $driver_handle = DBI->install_driver($driver_info->{drv}); }; + } + +# dbi_driver_info() +# Based on the current database variant, returns info about the DBI driver. +# Falls back to MySQL if the preferred driver is not available. +sub dbi_driver_info +{ +my %dbmap = ( + 'mysql' => { drv => 'mysql', opt => 'mysql', mod => 'DBD::mysql' }, + 'mariadb' => { drv => 'MariaDB', opt => 'mariadb', mod => 'DBD::MariaDB' } +); +my $want = ($mysql_version && $mysql_version =~ /mariadb/i) + ? 'mariadb' + : 'mysql'; + +# Try preferred driver +my $m = $dbmap{$want}->{'mod'}; +my $ok = eval "require $m; 1;"; +$dbmap{$want}->{'avail'} = $ok ? 1 : 0; +$dbmap{$want}->{'prefer'} = $dbmap{$want}->{'mod'}; +return $dbmap{$want} if $ok; + +# If MariaDB preferred but unavailable, fallback to MySQL +if ($want eq 'mariadb') { + $m = $dbmap{'mysql'}->{'mod'}; + $ok = eval "require $m; 1;"; + $dbmap{'mysql'}->{'avail'} = $ok ? 1 : 0; + $dbmap{'mysql'}->{'prefer'} = $dbmap{$want}->{'mod'}; + return $dbmap{'mysql'}; + } + +# Preferred driver unavailable, no fallback +return $dbmap{$want}; } # Fix text if we're running MariaDB @@ -324,15 +355,16 @@ $sql = &escape_backslashes_in_quotes($sql); if ($driver_handle && !$config{'nodbi'}) { # Use the DBI interface local $cstr = "database=$_[0]"; + local $drv = $driver_info->{opt}; $cstr .= ";host=$config{'host'}" if ($config{'host'}); $cstr .= ";port=$config{'port'}" if ($config{'port'}); - $cstr .= ";mysql_socket=$config{'sock'}" if ($config{'sock'}); - $cstr .= ";mysql_read_default_file=$config{'my_cnf'}" + $cstr .= ";${drv}_socket=$config{'sock'}" if ($config{'sock'}); + $cstr .= ";${drv}_read_default_file=$config{'my_cnf'}" if (-r $config{'my_cnf'}); if ($config{'ssl'}) { - $cstr .= ";mysql_ssl=1"; + $cstr .= ";${drv}_ssl=1"; if ($DBD::mysql::VERSION >= 4.043) { - $cstr .= ";mysql_ssl_optional=1"; + $cstr .= ";${drv}_ssl_optional=1"; } } local $dbh = $driver_handle->connect($cstr, $mysql_login, $mysql_pass,