From c922073c79f949a867827e4f302d2ec433bbe85e Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Mon, 29 May 2006 10:02:45 +0000 Subject: Bug 302876: Database Version-Checking needs to be more modular and more generic Patch By Max Kanat-Alexander r=wicked, a=myk --- Bugzilla/Constants.pm | 12 +++++++++ Bugzilla/DB.pm | 37 ++++++-------------------- Bugzilla/DB/Mysql.pm | 5 ---- Bugzilla/DB/Pg.pm | 4 --- checksetup.pl | 73 +++++++++++++++++++++++++++++++-------------------- 5 files changed, 65 insertions(+), 66 deletions(-) diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index aed574f67..0c451c8c3 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -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'}, +}; diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 127218843..4a0099db4 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -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 type. -=item C - -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 - -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 - -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 - -The minimum version of the DBD module that we require for this database. - =back @@ -1559,4 +1536,6 @@ PopGlobalSQLState L +L - The C constant. + =cut diff --git a/Bugzilla/DB/Mysql.pm b/Bugzilla/DB/Mysql.pm index e03fbc910..9493fb099 100644 --- a/Bugzilla/DB/Mysql.pm +++ b/Bugzilla/DB/Mysql.pm @@ -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) = @_; diff --git a/Bugzilla/DB/Pg.pm b/Bugzilla/DB/Pg.pm index 5162466c5..7bf64ab9d 100644 --- a/Bugzilla/DB/Pg.pm +++ b/Bugzilla/DB/Pg.pm @@ -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) = @_; diff --git a/checksetup.pl b/checksetup.pl index a2564f0a6..cde8b4945 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -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; -- cgit v1.2.3-24-g4f1b