Commit 0e8f16e1 authored by mkanat%kerio.com's avatar mkanat%kerio.com

Bug 284172: checksetup cannot run CREATE DATABASE on PostgreSQL

Patch By Max Kanat-Alexander <mkanat@kerio.com> r=glob, a=justdave
parent d0d2e9fd
...@@ -173,7 +173,8 @@ sub _handle_error { ...@@ -173,7 +173,8 @@ sub _handle_error {
# List of abstract methods we are checking the derived class implements # List of abstract methods we are checking the derived class implements
our @_abstract_methods = qw(new sql_regexp sql_not_regexp sql_limit our @_abstract_methods = qw(new sql_regexp sql_not_regexp sql_limit
sql_to_days sql_date_format sql_interval sql_to_days sql_date_format sql_interval
bz_lock_tables bz_unlock_tables); bz_lock_tables bz_unlock_tables
REQUIRED_VERSION PROGRAM_NAME);
# This overriden import method will check implementation of inherited classes # This overriden import method will check implementation of inherited classes
# for missing implementation of abstract methods # for missing implementation of abstract methods
...@@ -200,17 +201,10 @@ sub import { ...@@ -200,17 +201,10 @@ sub import {
$Exporter::ExportLevel-- if $is_exporter; $Exporter::ExportLevel-- if $is_exporter;
} }
# note that when multiple databases are supported, version number does not # XXX - Needs to be documented.
# make sense anymore (as it is DB-dependent). This needs to be removed in sub bz_server_version {
# the future and places where it's used fixed. my ($self) = @_;
my $cached_server_version; return $self->get_info(18); # SQL_DBMS_VER
sub server_version {
return $cached_server_version if defined($cached_server_version);
my $dbh = Bugzilla->dbh;
my $sth = $dbh->prepare('SELECT VERSION()');
$sth->execute();
($cached_server_version) = $sth->fetchrow_array();
return $cached_server_version;
} }
sub bz_get_field_defs { sub bz_get_field_defs {
...@@ -522,6 +516,26 @@ Access to the old SendSQL-based database routines are also provided by ...@@ -522,6 +516,26 @@ Access to the old SendSQL-based database routines are also provided by
importing the C<:deprecated> tag. These routines should not be used in new importing the C<:deprecated> tag. These routines should not be used in new
code. code.
=head1 CONSTANTS
Subclasses of Bugzilla::DB are required to define certain constants. These
constants are required to be subroutines or "use constant" variables.
=over 4
=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.
=head1 CONNECTION =head1 CONNECTION
A new database handle to the required database can be created using this A new database handle to the required database can be created using this
......
...@@ -47,11 +47,15 @@ use Carp; ...@@ -47,11 +47,15 @@ use Carp;
# This module extends the DB interface via inheritance # This module extends the DB interface via inheritance
use base qw(Bugzilla::DB); use base qw(Bugzilla::DB);
use constant REQUIRED_VERSION => '3.23.41';
use constant PROGRAM_NAME => 'MySQL';
sub new { sub new {
my ($class, $user, $pass, $host, $dbname, $port, $sock) = @_; my ($class, $user, $pass, $host, $dbname, $port, $sock) = @_;
# construct the DSN from the parameters we got # construct the DSN from the parameters we got
my $dsn = "DBI:mysql:host=$host;database=$dbname;port=$port"; my $dsn = "DBI:mysql:host=$host;database=$dbname";
$dsn .= ";port=$port" if $port;
$dsn .= ";mysql_socket=$sock" if $sock; $dsn .= ";mysql_socket=$sock" if $sock;
my $self = $class->db_new($dsn, $user, $pass); my $self = $class->db_new($dsn, $user, $pass);
......
...@@ -47,12 +47,21 @@ use Carp; ...@@ -47,12 +47,21 @@ use Carp;
# This module extends the DB interface via inheritance # This module extends the DB interface via inheritance
use base qw(Bugzilla::DB); use base qw(Bugzilla::DB);
use constant REQUIRED_VERSION => '7.02.0000';
use constant PROGRAM_NAME => 'PostgreSQL';
sub new { sub new {
my ($class, $user, $pass, $host, $dbname, $port) = @_; my ($class, $user, $pass, $host, $dbname, $port) = @_;
# The default database name for PostgreSQL. We have
# to connect to SOME database, even if we have
# no $dbname parameter.
$dbname ||= 'template1';
# construct the DSN from the parameters we got # construct the DSN from the parameters we got
my $dsn = "DBI:Pg:host=$host;dbname=$dbname;port=$port"; my $dsn = "DBI:Pg:host=$host;dbname=$dbname";
$dsn .= ";port=$port" if $port;
my $self = $class->db_new($dsn, $user, $pass); my $self = $class->db_new($dsn, $user, $pass);
# all class local variables stored in DBI derived class needs to have # all class local variables stored in DBI derived class needs to have
......
...@@ -954,8 +954,8 @@ sub init { ...@@ -954,8 +954,8 @@ sub init {
# mysql 4.0.1 and lower do not support CAST # mysql 4.0.1 and lower do not support CAST
# mysql 3.*.* had a case-sensitive INSTR # mysql 3.*.* had a case-sensitive INSTR
# (checksetup has a check for unsupported versions) # (checksetup has a check for unsupported versions)
my $server_version = Bugzilla::DB->server_version; my $server_version = $dbh->bz_server_version;
if ($server_version =~ /^3\./) { if ($dbh->isa('Bugzilla::DB::Mysql') && $server_version =~ /^3\./) {
$term = "INSTR($ff ,$q)"; $term = "INSTR($ff ,$q)";
} else { } else {
$term = "INSTR(CAST($ff AS BINARY), CAST($q AS BINARY))"; $term = "INSTR(CAST($ff AS BINARY), CAST($q AS BINARY))";
......
...@@ -81,7 +81,7 @@ ...@@ -81,7 +81,7 @@
# check for more required modules --MODULES-- # check for more required modules --MODULES--
# change the defaults for local configuration vars --LOCAL-- # change the defaults for local configuration vars --LOCAL--
# update the assigned file permissions --CHMOD-- # update the assigned file permissions --CHMOD--
# add more MySQL-related checks --MYSQL-- # add more database-related checks --DATABASE--
# change table definitions --TABLE-- # change table definitions --TABLE--
# add more groups --GROUPS-- # add more groups --GROUPS--
# create initial administrator account --ADMIN-- # create initial administrator account --ADMIN--
...@@ -294,7 +294,7 @@ my $modules = [ ...@@ -294,7 +294,7 @@ my $modules = [
}, },
{ {
name => 'DBI', name => 'DBI',
version => '1.36' version => '1.38'
}, },
{ {
name => 'DBD::mysql', name => 'DBD::mysql',
...@@ -672,9 +672,15 @@ LocalVar('db_host', q[ ...@@ -672,9 +672,15 @@ LocalVar('db_host', q[
# How to access the SQL database: # How to access the SQL database:
# #
$db_host = 'localhost'; # where is the database? $db_host = 'localhost'; # where is the database?
$db_port = 3306; # which port to use
$db_name = 'bugs'; # name of the MySQL database $db_name = 'bugs'; # name of the MySQL database
$db_user = 'bugs'; # user to attach to the MySQL database $db_user = 'bugs'; # user to attach to the MySQL database
# Sometimes the database server is running on a non-standard
# port. If that's the case for your database server, set this
# to the port number that your database server is running on.
# Setting this to 0 means "use the default port for my database
# server."
$db_port = 0;
]); ]);
LocalVar('db_pass', q[ LocalVar('db_pass', q[
# #
...@@ -688,15 +694,17 @@ $db_pass = ''; ...@@ -688,15 +694,17 @@ $db_pass = '';
]); ]);
LocalVar('db_sock', q[ LocalVar('db_sock', q[
# Enter a path to the unix socket for mysql. If this is blank, then mysql\'s # MySQL Only: Enter a path to the unix socket for mysql. If this is
# compiled-in default will be used. You probably want that. # blank, then mysql\'s compiled-in default will be used. You probably
# want that.
$db_sock = ''; $db_sock = '';
]); ]);
LocalVar('db_check', q[ LocalVar('db_check', q[
# #
# Should checksetup.pl try to verify that your MySQL setup is correct? # Should checksetup.pl try to verify that your database setup is correct?
# (with some combinations of MySQL/Msql-mysql/Perl/moonphase this doesn't work) # (with some combinations of database servers/Perl modules/moonphase this
# doesn't work)
# #
$db_check = 1; $db_check = 1;
]); ]);
...@@ -1470,11 +1478,11 @@ require "globals.pl"; ...@@ -1470,11 +1478,11 @@ require "globals.pl";
$::ENV{'PATH'} = $origPath; $::ENV{'PATH'} = $origPath;
########################################################################### ###########################################################################
# Check MySQL setup # Check Database setup
########################################################################### ###########################################################################
# #
# Check if we have access to --MYSQL-- # Check if we have access to the --DATABASE--
# #
# No need to "use" this here. It should already be loaded from the # No need to "use" this here. It should already be loaded from the
...@@ -1486,34 +1494,38 @@ $::ENV{'PATH'} = $origPath; ...@@ -1486,34 +1494,38 @@ $::ENV{'PATH'} = $origPath;
if ($my_db_check) { if ($my_db_check) {
# Do we have the database itself? # Do we have the database itself?
my $sql_want = "3.23.41"; # minimum version of MySQL
my $dbh = Bugzilla::DB::connect_main("no database connection"); my $dbh = Bugzilla::DB::connect_main("no database connection");
printf("Checking for %15s %-9s ", "MySQL Server", "(v$sql_want)") unless $silent; my $sql_want = $dbh->REQUIRED_VERSION;
my $qh = $dbh->prepare("SELECT VERSION()"); my $sql_server = $dbh->PROGRAM_NAME;
$qh->execute;
my ($sql_vers) = $qh->fetchrow_array; printf("Checking for %15s %-9s ", $sql_server, "(v$sql_want)") unless $silent;
$qh->finish; my $sql_vers = $dbh->bz_server_version;
# Check what version of MySQL is installed and let the user know # Check what version of MySQL is installed and let the user know
# if the version is too old to be used with Bugzilla. # if the version is too old to be used with Bugzilla.
if ( vers_cmp($sql_vers,$sql_want) > -1 ) { if ( vers_cmp($sql_vers,$sql_want) > -1 ) {
print "ok: found v$sql_vers\n" unless $silent; print "ok: found v$sql_vers\n" unless $silent;
} else { } else {
die "\nYour MySQL server v$sql_vers is too old.\n" . die "\nYour $sql_server v$sql_vers is too old.\n" .
" Bugzilla requires version $sql_want or later of MySQL.\n" . " Bugzilla requires version $sql_want or later of $sql_server.\n" .
" Please visit http://www.mysql.com/ and download a newer version.\n"; " Please download and install a newer version.\n";
} }
if (( $sql_vers =~ /^4\.0\.(\d+)/ ) && ($1 < 2)) { # This message is specific to MySQL.
if ($dbh->isa('Bugzilla::DB::Mysql') && ($sql_vers =~ /^4\.0\.(\d+)/) && ($1 < 2)) {
die "\nYour MySQL server is incompatible with Bugzilla.\n" . die "\nYour MySQL server is incompatible with Bugzilla.\n" .
" Bugzilla does not support versions 4.x.x below 4.0.2.\n" . " Bugzilla does not support versions 4.x.x below 4.0.2.\n" .
" Please visit http://www.mysql.com/ and download a newer version.\n"; " Please visit http://www.mysql.com/ and download a newer version.\n";
} }
my @databases = $dbh->func('_ListDBs'); # See if we can connect to the database.
unless (grep /^$my_db_name$/, @databases) { my $conn_success = eval {
my $check_dbh = Bugzilla::DB::connect_main();
$check_dbh->disconnect;
};
if (!$conn_success) {
print "Creating database $my_db_name ...\n"; print "Creating database $my_db_name ...\n";
if (!$dbh->func('createdb', $my_db_name, 'admin')) { # Try to create the DB, and if we fail print an error.
if (!eval { $dbh->do("CREATE DATABASE $my_db_name") }) {
my $error = $dbh->errstr; my $error = $dbh->errstr;
die <<"EOF" die <<"EOF"
...@@ -1523,11 +1535,12 @@ $error ...@@ -1523,11 +1535,12 @@ $error
This might have several reasons: This might have several reasons:
* MySQL is not running. * $sql_server is not running.
* MySQL is running, but the rights are not set correct. Go and read the * $sql_server is running, but there is a problem either in the
Bugzilla Guide in the doc directory and all parts of the MySQL server configuration or the database access rights. Read the Bugzilla
documentation. Guide in the doc directory. The section about database configuration
* There is a subtle problem with Perl, DBI, DBD::mysql and MySQL. Make should help.
* There is a subtle problem with Perl, DBI, or $sql_server. Make
sure all settings in '$localconfig' are correct. If all else fails, set sure all settings in '$localconfig' are correct. If all else fails, set
'\$db_check' to zero.\n '\$db_check' to zero.\n
EOF EOF
......
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