Commit c922073c authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 302876: Database Version-Checking needs to be more modular and more generic

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=wicked, a=myk
parent 7adc23f4
......@@ -101,6 +101,8 @@ use base qw(Exporter);
FIELD_TYPE_FREETEXT
BUG_STATE_OPEN
DB_MODULE
);
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
......@@ -277,3 +279,13 @@ use constant BUG_STATE_OPEN => ('NEW', 'REOPENED', 'ASSIGNED',
'UNCONFIRMED');
1;
# Data about what we require for different databases.
use constant DB_MODULE => {
'mysql' => {db => 'Bugzilla::DB::Mysql', db_version => '4.0.14',
dbd => 'DBD::mysql', dbd_version => '2.9003',
name => 'MySQL'},
'pg' => {db => 'Bugzilla::DB::Pg', db_version => '8.00.0000',
dbd => 'DBD::Pg', dbd_version => '1.45',
name => 'PostgreSQL'},
};
......@@ -48,6 +48,7 @@ use base qw(Exporter DBI::db);
Exporter::export_ok_tags('deprecated');
use Bugzilla::Config qw(:DEFAULT :db);
use Bugzilla::Constants;
use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::DB::Schema;
......@@ -164,14 +165,11 @@ sub connect_main {
sub _connect {
my ($driver, $host, $dbname, $port, $sock, $user, $pass) = @_;
# DB specific module have the same name as DB driver, here we
# just make sure we are not case sensitive
(my $db_module = $driver) =~ s/(\w+)/\u\L$1/g;
my $pkg_module = "Bugzilla::DB::" . $db_module;
my $pkg_module = DB_MODULE->{lc($driver)}->{db};
# do the actual import
eval ("require $pkg_module")
|| die ("'$db_module' is not a valid choice for \$db_driver in "
|| die ("'$driver' is not a valid choice for \$db_driver in "
. " localconfig: " . $@);
# instantiate the correct DB specific module
......@@ -622,8 +620,9 @@ sub bz_rename_column {
sub _bz_schema {
my ($self) = @_;
return $self->{private_bz_schema} if exists $self->{private_bz_schema};
$self->{private_bz_schema} =
Bugzilla::DB::Schema->new($self->MODULE_NAME);
my @module_parts = split('::', ref $self);
my $module_name = pop @module_parts;
$self->{private_bz_schema} = Bugzilla::DB::Schema->new($module_name);
return $self->{private_bz_schema};
}
......@@ -989,28 +988,6 @@ constants are required to be subroutines or "use constant" variables.
The C<\%attr> argument that must be passed to bind_param in order to
correctly escape a C<LONGBLOB> type.
=item C<REQUIRED_VERSION>
This is the minimum required version of the database server that the
Bugzilla::DB subclass requires. It should be in a format suitable for
passing to vers_cmp during installation.
=item C<PROGRAM_NAME>
The human-readable name of this database. For example, for MySQL, this
would be 'MySQL.' You should not depend on this variable to know what
type of database you are running on; this is intended merely for displaying
to the admin to let them know what DB they're running.
=item C<MODULE_NAME>
The name of the Bugzilla::DB module that we are. For example, for the MySQL
Bugzilla::DB module, this would be "Mysql." For PostgreSQL it would be "Pg."
=item C<DBD_VERSION>
The minimum version of the DBD module that we require for this database.
=back
......@@ -1559,4 +1536,6 @@ PopGlobalSQLState
L<DBI>
L<Bugzilla::Constants> - The C<DB_MODULE> constant.
=cut
......@@ -49,11 +49,6 @@ use Bugzilla::Error;
# This module extends the DB interface via inheritance
use base qw(Bugzilla::DB);
use constant REQUIRED_VERSION => '4.0.14';
use constant PROGRAM_NAME => 'MySQL';
use constant MODULE_NAME => 'Mysql';
use constant DBD_VERSION => '2.9003';
sub new {
my ($class, $user, $pass, $host, $dbname, $port, $sock) = @_;
......
......@@ -50,10 +50,6 @@ use DBD::Pg;
use base qw(Bugzilla::DB);
use constant BLOB_TYPE => { pg_type => DBD::Pg::PG_BYTEA };
use constant REQUIRED_VERSION => '8.00.0000';
use constant PROGRAM_NAME => 'PostgreSQL';
use constant MODULE_NAME => 'Pg';
use constant DBD_VERSION => '1.45';
sub new {
my ($class, $user, $pass, $host, $dbname, $port) = @_;
......
......@@ -376,6 +376,17 @@ foreach my $module (@{$modules}) {
}
}
print ("\nYou need one of the following DBD modules installed, depending on\n"
. "which database you are using with Bugzilla:\n") unless $silent;
my $have_one_dbd = 0;
my $db_modules = DB_MODULE;
foreach my $db (keys %$db_modules) {
if (have_vers($db_modules->{$db}->{dbd}, $db_modules->{$db}->{dbd_version})) {
$have_one_dbd = 1;
}
}
print "\nThe following Perl modules are optional:\n" unless $silent;
my $gd = have_vers("GD","1.20");
my $chartbase = have_vers("Chart::Base","1.0");
......@@ -433,8 +444,23 @@ if (!$patchreader && !$silent) {
print "PatchReader: " . install_command("PatchReader") . "\n";
}
if (%missing) {
if (!$have_one_dbd) {
print "\n\n";
print "Bugzilla requires that at least one DBD module be installed in\n",
"order to access a database. You can install the correct one by\n",
"picking the command listed below for your database:\n";
foreach my $db (keys %$db_modules) {
print " " . $db_modules->{$db}->{name} . ": "
. install_command($db_modules->{$db}->{dbd}) . "\n";
print " Minimum version required: "
. $db_modules->{$db}->{dbd_version} . "\n";
}
print "\n";
}
if (%missing) {
print "\n";
print "Bugzilla requires some Perl modules which are either missing from\n",
"your system, or the version on your system is too old.\n",
"They can be installed by running (as $::root) the following:\n";
......@@ -445,9 +471,10 @@ if (%missing) {
}
}
print "\n";
exit;
}
exit if (%missing || !$have_one_dbd);
}
}
......@@ -1487,37 +1514,27 @@ $::ENV{'PATH'} = $origPath;
# Check if we have access to the --DATABASE--
#
# No need to "use" this here. It should already be loaded from the
# version-checking routines above, and this file won't even compile if
# DBI isn't installed so the user gets nasty errors instead of our
# pretty one saying they need to install it. -- justdave@syndicomm.com
#use DBI;
if ($my_db_check) {
# Do we have the database itself?
# Unfortunately, $my_db_driver doesn't map perfectly between DBD
# and Bugzilla::DB. We need to fix the case a bit.
(my $dbd_name = trim($my_db_driver)) =~ s/(\w+)/\u\L$1/g;
# And MySQL is special, because it's all lowercase in DBD.
$dbd_name = 'mysql' if $dbd_name eq 'Mysql';
my $dbd = "DBD::$dbd_name";
unless (eval("require $dbd")) {
print "Bugzilla requires that perl's $dbd be installed.\n"
. "To install this module, you can do:\n "
. " " . install_command($dbd) . "\n";
exit;
# Only certain values are allowed for $db_driver.
if (!exists DB_MODULE->{lc($my_db_driver)}) {
die "$my_db_driver is not a valid choice for \$db_driver in",
" localconfig";
}
my $dbh = Bugzilla::DB::connect_main("no database connection");
my $sql_want = $dbh->REQUIRED_VERSION;
my $sql_server = $dbh->PROGRAM_NAME;
my $dbd_ver = $dbh->DBD_VERSION;
unless (have_vers($dbd, $dbd_ver)) {
die "Bugzilla requires at least version $dbd_ver of $dbd.";
# Check the existence and version of the DBD that we need.
my $actual_dbd = DB_MODULE->{lc($my_db_driver)}->{dbd};
my $actual_dbd_ver = DB_MODULE->{lc($my_db_driver)}->{dbd_version};
my $sql_server = DB_MODULE->{lc($my_db_driver)}->{name};
my $sql_want = DB_MODULE->{lc($my_db_driver)}->{db_version};
unless (have_vers($actual_dbd, $actual_dbd_ver)) {
print "For $sql_server, Bugzilla requires that perl's"
. " $actual_dbd be installed.\nTo install this module,"
. " you can do:\n " . install_command($actual_dbd) . "\n";
exit;
}
# And now check the version of the database server itself.
my $dbh = Bugzilla::DB::connect_main("no database connection");
printf("Checking for %15s %-9s ", $sql_server, "(v$sql_want)") unless $silent;
my $sql_vers = $dbh->bz_server_version;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment