mirror of
https://github.com/webmin/webmin.git
synced 2026-03-13 14:12:05 +00:00
Fix query monitor MariaDB driver handling
This commit is contained in:
@@ -1,30 +1,69 @@
|
||||
# query-monitor.pl
|
||||
# Try an SQL query on a MySQL or PostgreSQL server
|
||||
# Try an SQL query on a database server
|
||||
|
||||
my %allowed_query_drivers = map { $_, 1 } ("mysql", "Pg", "Oracle");
|
||||
# SQL drivers offered in the UI and permitted by strict validation.
|
||||
my @query_driver_options = (
|
||||
[ "mysql", "MySQL" ],
|
||||
[ "MariaDB", "MariaDB" ],
|
||||
[ "Pg", "PostgreSQL" ],
|
||||
[ "Oracle", "Oracle" ]
|
||||
);
|
||||
my %allowed_query_drivers = map { $_->[0], 1 } @query_driver_options;
|
||||
|
||||
# canonical_query_driver(driver)
|
||||
# Normalize a stored driver name to the canonical DBI driver key.
|
||||
sub canonical_query_driver
|
||||
{
|
||||
my ($driver) = @_;
|
||||
# Accept legacy lowercase value while storing/using canonical DBI name.
|
||||
return $driver eq 'mariadb' ? 'MariaDB' : $driver;
|
||||
}
|
||||
|
||||
# query_driver_candidates(driver)
|
||||
# Returns preferred and fallback DBI driver names for the selected driver.
|
||||
sub query_driver_candidates
|
||||
{
|
||||
my ($driver) = @_;
|
||||
$driver = &canonical_query_driver($driver);
|
||||
# Match mysql/mysql-lib.pl behavior : prefer selected family, then fallback.
|
||||
return ($driver eq 'mysql') ? ( "mysql", "MariaDB" ) :
|
||||
($driver eq 'MariaDB') ? ( "MariaDB", "mysql" ) :
|
||||
( $driver );
|
||||
}
|
||||
|
||||
# get_query_status(&service)
|
||||
# Attempts DB connect and query execution and returns monitor status hash.
|
||||
sub get_query_status
|
||||
{
|
||||
if (!$allowed_query_drivers{$_[0]->{'driver'}}) {
|
||||
my $driver = &canonical_query_driver($_[0]->{'driver'});
|
||||
if (!$allowed_query_drivers{$driver}) {
|
||||
return { 'up' => -1,
|
||||
'desc' => &text('query_edriver',
|
||||
"<tt>DBD::$_[0]->{'driver'}</tt>") };
|
||||
"<tt>DBD::$driver</tt>") };
|
||||
}
|
||||
|
||||
# Load the driver
|
||||
local $drh;
|
||||
eval <<EOF;
|
||||
use DBI;
|
||||
\$drh = DBI->install_driver(\$_[0]->{'driver'});
|
||||
EOF
|
||||
eval { require DBI; };
|
||||
if ($@) {
|
||||
return { 'up' => -1,
|
||||
'desc' => &text('query_edriver',
|
||||
"<tt>DBD::$_[0]->{'driver'}</tt>") };
|
||||
"<tt>DBD::$driver</tt>") };
|
||||
}
|
||||
my @drivers = &query_driver_candidates($driver);
|
||||
# Try fallback-compatible drivers to tolerate either DBD::mysql or DBD::MariaDB.
|
||||
foreach my $try (@drivers) {
|
||||
eval { $drh = DBI->install_driver($try); };
|
||||
last if (!$@ && $drh);
|
||||
}
|
||||
if (!$drh) {
|
||||
return { 'up' => -1,
|
||||
'desc' => &text('query_edriver',
|
||||
"<tt>DBD::$driver</tt>") };
|
||||
}
|
||||
|
||||
# Connect to the database server
|
||||
local $dbistr = &make_dbistr($_[0]->{'driver'}, $_[0]->{'db'}, $_[0]->{'host'});
|
||||
local $dbistr = &make_dbistr($driver, $_[0]->{'db'}, $_[0]->{'host'});
|
||||
local $dbh = $drh->connect($dbistr,
|
||||
$_[0]->{'user'}, $_[0]->{'pass'}, { });
|
||||
if (!$dbh) {
|
||||
@@ -53,13 +92,13 @@ if ($_[0]->{'result'} ne '' && $r[0] ne $_[0]->{'result'}) {
|
||||
return { 'up' => 1 };
|
||||
}
|
||||
|
||||
# show_query_dialog(&service)
|
||||
# Displays the SQL query monitor configuration form fields.
|
||||
sub show_query_dialog
|
||||
{
|
||||
print &ui_table_row($text{'query_driver'},
|
||||
&ui_select("driver", $_[0]->{'driver'},
|
||||
[ [ "mysql", "MySQL" ],
|
||||
[ "Pg", "PostgreSQL" ],
|
||||
[ "Oracle", "Oracle" ] ]));
|
||||
&ui_select("driver", &canonical_query_driver($_[0]->{'driver'}),
|
||||
\@query_driver_options));
|
||||
|
||||
print &ui_table_row($text{'query_db'},
|
||||
&ui_textbox("db", $_[0]->{'db'}, 20));
|
||||
@@ -81,16 +120,26 @@ print &ui_table_row($text{'query_result'},
|
||||
$text{'query_ignore'}), 3);
|
||||
}
|
||||
|
||||
# parse_query_dialog(&service)
|
||||
# Validates query monitor inputs and stores normalized settings.
|
||||
sub parse_query_dialog
|
||||
{
|
||||
$allowed_query_drivers{$in{'driver'}} ||
|
||||
&error(&text('query_edriver', "<tt>DBD::$in{'driver'}</tt>"));
|
||||
eval {
|
||||
require DBI;
|
||||
DBI->install_driver($in{'driver'});
|
||||
};
|
||||
&error(&text('query_edriver', "<tt>DBD::$in{'driver'}</tt>")) if ($@);
|
||||
$_[0]->{'driver'} = $in{'driver'};
|
||||
my $driver = &canonical_query_driver($in{'driver'});
|
||||
$allowed_query_drivers{$driver} ||
|
||||
&error(&text('query_edriver', "<tt>DBD::$driver</tt>"));
|
||||
eval { require DBI; };
|
||||
&error(&text('query_edriver', "<tt>DBD::$driver</tt>")) if ($@);
|
||||
my $ok;
|
||||
foreach my $try (&query_driver_candidates($driver)) {
|
||||
# Validation mirrors runtime loading : any valid fallback driver is accepted.
|
||||
eval { DBI->install_driver($try); };
|
||||
if (!$@) {
|
||||
$ok = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
&error(&text('query_edriver', "<tt>DBD::$driver</tt>")) if (!$ok);
|
||||
$_[0]->{'driver'} = $driver;
|
||||
|
||||
$in{'db'} =~ /^\S+$/ || &error($text{'query_edb'});
|
||||
$_[0]->{'db'} = $in{'db'};
|
||||
@@ -122,11 +171,14 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
# make_dbistr(driver, database, host)
|
||||
# Builds the DBI connection string for the selected SQL driver.
|
||||
sub make_dbistr
|
||||
{
|
||||
local ($driver, $db, $host) = @_;
|
||||
local $rv;
|
||||
if ($driver eq "mysql") {
|
||||
if ($driver eq "mysql" || $driver eq "MariaDB") {
|
||||
# Both DBI drivers use "database=" style DSN here.
|
||||
$rv = "database=$db";
|
||||
}
|
||||
elsif ($driver eq "Pg") {
|
||||
@@ -140,5 +192,3 @@ if ($host) {
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user