Files
2024-10-14 00:08:40 +02:00

224 lines
6.6 KiB
Perl

# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Dev::Tools::Database::XML2SQL;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
## nofilter(TidyAll::Plugin::OTRS::Perl::ObjectManagerCreation)
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::DB',
'Kernel::System::Main',
'Kernel::System::XML',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Convert OTRS database XML to SQL.');
$Self->AddOption(
Name => 'database-type',
Description => "Specify the database to generate SQL for (mysql|postgresql|oracle|all).",
Required => 1,
HasValue => 1,
ValueRegex => qr/^(mysql|postgresql|oracle|all)$/smx,
);
$Self->AddOption(
Name => 'source-path',
Description => "Read XML from the specified file (otherwise STDIN will be used).",
Required => 0,
HasValue => 1,
ValueRegex => qr/.*/smx,
);
$Self->AddOption(
Name => 'target-directory',
Description => "Specify the output directory (otherwise the result will be printed on the console).",
Required => 0,
HasValue => 1,
ValueRegex => qr/.*/smx,
);
$Self->AddOption(
Name => 'target-filename',
Description => "Specify the output filename.",
Required => 0,
HasValue => 1,
ValueRegex => qr/.*/smx,
);
$Self->AddOption(
Name => 'split-files',
Description => "Split foreign key creation into a separate (post) SQL file.",
Required => 0,
HasValue => 0,
);
return;
}
sub PreRun {
my ( $Self, %Param ) = @_;
my $TargetDirectory = $Self->GetOption('target-directory');
if ($TargetDirectory) {
if ( !-d $TargetDirectory ) {
die "Directory $TargetDirectory does not exist.\n";
}
my $TargetFilename = $Self->GetOption('target-filename');
if ( !$TargetFilename ) {
die "Please provide the option 'target-filename'.\n";
}
}
my $SourceFilename = $Self->GetOption('source-path');
if ( $SourceFilename && !-r $SourceFilename ) {
die "Source file $SourceFilename does not exist / cannot be read.\n";
}
return;
}
sub Run {
my ( $Self, %Param ) = @_;
my @DatabaseType = ( $Self->GetOption('database-type') );
if ( $Self->GetOption('database-type') eq 'all' ) {
@DatabaseType = qw(mysql postgresql oracle);
}
my $SourceFilename = $Self->GetOption('source-path');
my $SourceXML;
if ($SourceFilename) {
my $FileStringRef = $Kernel::OM->Get('Kernel::System::Main')->FileRead(
Location => $SourceFilename,
Mode => 'utf8',
Type => 'Local',
Result => 'SCALAR',
DisableWarnings => 1,
);
$SourceXML = ${$FileStringRef};
}
else {
# read xml data from STDIN
$SourceXML = do { local $/; <> };
}
for my $DatabaseType (@DatabaseType) {
local $Kernel::OM = Kernel::System::ObjectManager->new();
$Kernel::OM->Get('Kernel::Config')->Set(
Key => 'Database::Type',
Value => $DatabaseType,
);
$Kernel::OM->Get('Kernel::Config')->Set(
Key => 'Database::ShellOutput',
Value => 1,
);
# parse xml package
my @XMLARRAY = $Kernel::OM->Get('Kernel::System::XML')->XMLParse( String => $SourceXML );
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
my $Head = $DBObject->{Backend}->{'DB::Comment'}
. "----------------------------------------------------------\n";
$Head .= $DBObject->{Backend}->{'DB::Comment'}
. " driver: $DatabaseType\n";
$Head .= $DBObject->{Backend}->{'DB::Comment'}
. "----------------------------------------------------------\n";
# get sql from parsed xml
my @SQL;
if ( $DBObject->{Backend}->{'DB::ShellConnect'} ) {
push @SQL, $DBObject->{Backend}->{'DB::ShellConnect'};
}
push @SQL, $DBObject->SQLProcessor( Database => \@XMLARRAY );
# get port sql from parsed xml
my @SQLPost;
if ( $DBObject->{Backend}->{'DB::ShellConnect'} ) {
push @SQLPost, $DBObject->{Backend}->{'DB::ShellConnect'};
}
push @SQLPost, $DBObject->SQLProcessorPost();
my $TargetFilename = $Self->GetOption('target-filename');
my $TargetFilenamePost = $Self->GetOption('target-filename');
if ($TargetFilename) {
$TargetFilename = $Self->GetOption('target-directory') . "/$TargetFilename.$DatabaseType.sql";
$TargetFilenamePost = $Self->GetOption('target-directory') . "/$TargetFilenamePost-post.$DatabaseType.sql";
}
if ( $Self->GetOption('split-files') ) {
# write create script
$Self->Dump(
$TargetFilename,
\@SQL,
$Head,
$DBObject->{Backend}->{'DB::ShellCommit'},
);
# write post script
$Self->Dump(
$TargetFilenamePost,
\@SQLPost,
$Head,
$DBObject->{Backend}->{'DB::ShellCommit'},
);
}
else {
$Self->Dump(
$TargetFilename,
[ @SQL, @SQLPost ],
$Head,
$DBObject->{Backend}->{'DB::ShellCommit'},
);
}
}
return $Self->ExitCodeOk();
}
sub Dump {
my ( $Self, $Filename, $SQL, $Head, $Commit ) = @_;
if ($Filename) {
my $Content = $Head;
for my $Item ( @{$SQL} ) {
$Content .= $Item . $Commit . "\n";
}
$Self->Print("Writing: <yellow>$Filename</yellow>\n");
my $Written = $Kernel::OM->Get('Kernel::System::Main')->FileWrite(
Location => $Filename,
Content => \$Content,
Mode => 'utf8',
Type => 'Local',
);
if ( !$Written ) {
$Self->PrintError("Could not write $Filename.");
}
}
else {
print $Head;
for my $Item ( @{$SQL} ) {
print $Item . $Commit . "\n";
}
}
return 1;
}
1;