#!@PERL@ -w
-# BEGIN LICENSE BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# <jesse@bestpractical.com>
#
-# (Except where explictly superceded by other copyright notices)
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
-# END LICENSE BLOCK
-
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
use strict;
use vars qw($PROMPT $VERSION $Handle $Nobody $SystemUser $item);
use vars
$dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} )
|| die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr";
print "Now creating a database for RT.\n";
+ if ($RT::DatabaseType ne 'Oracle' ||
+ $args{'dba'} ne $RT::DatabaseUser) {
create_db();
+ } else {
+ print "...skipped as ".$args{'dba'} ." is not " . $RT::DatabaseUser . " or we're working with Oracle.\n";
+ }
- $dbh->disconnect;
- $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
- || die $DBI::errstr;
-
+ if ($RT::DatabaseType eq "mysql") {
+ # Check which version we're running
+ my ($version) = $dbh->selectrow_hashref("show variables like 'version'")->{Value} =~ /^(\d\.\d+)/;
+ print "*** Warning: RT is unsupported on MySQL versions before 4.0.x\n" if $version < 4;
+
+ # MySQL must have InnoDB support
+ my $innodb = $dbh->selectrow_hashref("show variables like 'have_innodb'")->{Value};
+ if ($innodb eq "NO") {
+ die "RT requires that MySQL be compiled with InnoDB table support.\n".
+ "See http://dev.mysql.com/doc/mysql/en/InnoDB.html\n";
+ } elsif ($innodb eq "DISABLED") {
+ die "RT requires that MySQL InnoDB table support be enabled.\n".
+ ($version < 4
+ ? "Add 'innodb_data_file_path=ibdata1:10M:autoextend' to the [mysqld] section of my.cnf\n"
+ : "Remove the 'skip-innodb' line from your my.cnf file, restart MySQL, and try again.\n");
+ }
+ }
+
+ # SQLite can't deal with the disconnect/reconnect
+ unless ($RT::DatabaseType eq 'SQLite') {
+
+ $dbh->disconnect;
+
+ if ($RT::DatabaseType eq "Oracle") {
+ $RT::DatabasePassword = $RT::DatabasePassword; #Warning avidance
+ $dbh = DBI->connect( $Handle->DSN, ${RT::DatabaseUser}, ${RT::DatabasePassword} ) || die $DBI::errstr;
+ } else {
+
+ $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) || die $DBI::errstr;
+ }
+ }
print "Now populating database schema.\n";
insert_schema();
print "Now inserting database ACLs\n";
- insert_acl();
+ insert_acl() unless ($RT::DatabaseType eq 'Oracle');
print "Now inserting RT core system objects\n";
insert_initial_data();
print "Now inserting RT data\n";
}
drop_db();
}
+elsif ( $args{'action'} eq 'insert_initial' ) {
+ insert_initial_data();
+}
elsif ( $args{'action'} eq 'insert' ) {
- insert_data( $args{'datafile'} );
+ insert_data( $args{'datafile'} || ($args{'datadir'}."/content"));
}
elsif ($args{'action'} eq 'acl') {
$dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} )
open( SCHEMA_LOCAL, "<" . $RT::LocalEtcPath . "/schema." . $RT::DatabaseType );
my $statement = "";
- foreach my $line (<SCHEMA>, <SCHEMA_LOCAL>) {
+ foreach my $line (<SCHEMA>, ($_ = ';;'), <SCHEMA_LOCAL>) {
$line =~ s/\#.*//g;
+ $line =~ s/--.*//g;
$statement .= $line;
if ( $line =~ /;(\s*)$/ ) {
$statement =~ s/;(\s*)$//g;
}
}
+ local $SIG{__WARN__} = sub {};
+ my $is_local = 0; # local/etc/schema needs to be nonfatal.
+ $dbh->begin_work or die $dbh->errstr;
foreach my $statement (@schema) {
- print STDERR $statement if $args{'debug'};
+ if ($statement =~ /^\s*;$/) { $is_local = 1; next; }
+ print STDERR "SQL: $statement\n" if defined $args{'debug'};
my $sth = $dbh->prepare($statement) or die $dbh->errstr;
- unless ( $sth->execute ) {
+ unless ( $sth->execute or $is_local ) {
die "Problem with statement:\n $statement\n" . $sth->errstr;
}
}
+ $dbh->commit or die $dbh->errstr;
}
else {
die "Couldn't find schema file for " . $RT::DatabaseType . "\n";
}
- print "schema sucessfully inserted\n";
+ print "Done setting up database schema.\n";
}
# {{{ sub drop_db
sub drop_db {
- return if ( $RT::DatabaseType eq 'SQLite' );
+ if ( $RT::DatabaseType eq 'Oracle' ) {
+ print <<END;
+
+To delete the tables and sequences of the RT Oracle database by running
+ \@etc/drop.Oracle
+through SQLPlus.
+
+END
+ return;
+ }
unless ( $args{'force'} ) {
print <<END;
print "Dropping $RT::DatabaseType database $RT::DatabaseName.\n";
+ if ( $RT::DatabaseType eq 'SQLite' ) {
+ unlink $RT::DatabaseName or warn $!;
+ return;
+ }
$dbh->do("Drop DATABASE $RT::DatabaseName") or warn $DBI::errstr;
}
$dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr;
}
}
+ elsif ($RT::DatabaseType eq 'Oracle') {
+ insert_acl();
+ }
+ elsif ( $RT::DatabaseType eq 'Informix' ) {
+ $ENV{DB_LOCALE} = 'en_us.utf8';
+ $dbh->do("CREATE DATABASE $RT::DatabaseName WITH BUFFERED LOG");
+ }
else {
$dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr;
}
# }}}
sub get_dba_password {
- print
-"In order to create a new database and grant RT access to that database,\n";
+ print "In order to create or update your RT database,";
print "this script needs to connect to your "
. $RT::DatabaseType
. " instance on "
. $RT::DatabaseHost . " as "
. $args{'dba'} . ".\n";
- print
-"Please specify that user's database password below. If the user has no database\n";
+ print "Please specify that user's database password below. If the user has no database\n";
print "password, just press return.\n\n";
print "Password: ";
ReadMode('noecho');
my $password = ReadLine(0);
ReadMode('normal');
+ print "\n";
return ($password);
}
}
elsif ( $RT::DatabaseType =~ /^mysql$/i ) {
do $base_path . "/acl.mysql"
- || die "Couldn't find ACLS for mysql in " . $RT::EtcPath . "\n" . $@;
+ || die "Couldn't find ACLS for mysql in $base_path\n" . $@;
+ }
+ elsif ( $RT::DatabaseType =~ /^Sybase$/i ) {
+ do $base_path . "/acl.Sybase"
+ || die "Couldn't find ACLS for Sybase in $base_path\n" . $@;
+ }
+ elsif ( $RT::DatabaseType =~ /^informix$/i ) {
+ do $base_path . "/acl.Informix"
+ || die "Couldn't find ACLS for Informix in $base_path\n" . $@;
}
elsif ( $RT::DatabaseType =~ /^SQLite$/i ) {
return;
die "Problem with statement:\n $statement\n" . $sth->errstr;
}
}
+ print "Done setting up database ACLs.\n";
}
# }}}
elsif ( $RT::DatabaseType eq 'Pg' ) {
$dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/;
}
+ elsif ( $RT::DatabaseType eq 'Informix' ) {
+ # with Informix, you want to connect sans database:
+ $dsn =~ s/Informix:$RT::DatabaseName/Informix:/;
+ }
return $dsn;
}
RealName => 'The RT System itself',
Comments =>
'Do not delete or modify this user. It is integral to RT\'s internal database structures',
- Creator => '1' );
+ Creator => '1',
+ LastUpdatedBy => '1' );
unless ($val) {
print "$msg\n";
exit(1);
}
print "done.\n";
- $RT::Handle->dbh->disconnect();
+ $RT::Handle->Disconnect() unless ($RT::DatabaseType eq 'SQLite');
}
ObjectType => 'RT::System',
ObjectId => '1' );
+ print "done.\n";
}
# Slurp in stuff to insert from the datafile. Possible things to go in here:-
$princ->LoadUserDefinedGroup( $item->{'GroupId'} );
} elsif ($item->{'GroupDomain'} eq 'SystemInternal') {
$princ->LoadSystemInternalGroup( $item->{'GroupType'} );
+ } elsif ($item->{'GroupDomain'} eq 'RT::System-Role') {
+ $princ->LoadSystemRoleGroup( $item->{'GroupType'} );
} elsif ($item->{'GroupDomain'} eq 'RT::Queue-Role' &&
$item->{'Queue'}) {
$princ->LoadQueueRoleGroup( Type => $item->{'GroupType'},
}
print "done.\n";
}
- $RT::Handle->Disconnect();
-
+ $RT::Handle->Disconnect() unless ($RT::DatabaseType eq 'SQLite');
+ print "Done setting up database content.\n";
}
=head2 ACLEquivGroupId
--action init Initialize the database
drop Drop the database.
This will ERASE ALL YOUR DATA
+ insert_initial
+ Insert RT's core system objects
insert Insert data into RT's database.
By default, will use RT's installation data.
To use a local or supplementary datafile, specify it