Skip to content

Commit

Permalink
Issue #601: reactivate the check for BLOB columns
Browse files Browse the repository at this point in the history
  • Loading branch information
bschmalhofer committed Nov 1, 2020
1 parent 2c99916 commit 53f718b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
24 changes: 15 additions & 9 deletions Kernel/System/MigrateFromOTRS/CloneDB/Driver/Base.pm
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ sub DataTransfer {
my %TableIsSkipped = $MigrationBaseObject->DBSkipTables()->%*;
my %RenameTables = $MigrationBaseObject->DBRenameTables()->%*;

# Conversion of BLOBs is only relevant when DirectBlob settings are different.
my %BlobConversionNeeded;
if (
$TargetDBObject->GetDatabaseFunction('DirectBlob')
!= $SourceDBObject->GetDatabaseFunction('DirectBlob')
)
{
%BlobConversionNeeded = $Self->BlobColumnsList()->%*;
}

# Because of InnodB max key size in MySQL 5.6 or earlier
my $MaxMb4CharsInIndexKey = 191; # int( 767 / 4 )
my $MaxLenghtShortenedColumns = 190; # 191 - 1
Expand Down Expand Up @@ -447,7 +457,7 @@ sub DataTransfer {

# no batch insert when BLOBs must be encoded or decoded
# This check is basically redundant because the DB::Types have already been checked.
return 0 unless $TargetDBObject->GetDatabaseFunction('DirectBlob') == $SourceDBObject->GetDatabaseFunction('DirectBlob');
return 0 if %BlobConversionNeeded;

# Let's try batch inserts
return 1;
Expand Down Expand Up @@ -761,18 +771,14 @@ END_SQL

# No need to shorten any columns, as that was already in the SELECT

# If the two databases have different blob handling (base64), convert
# columns that need it.
if (
$TargetDBObject->GetDatabaseFunction('DirectBlob')
!= $SourceDBObject->GetDatabaseFunction('DirectBlob')
)
{
# If the two databases have different blob handling (base64),
# convert columns that need conversion.
if ( $BlobConversionNeeded{$SourceTable} ) {
COLUMN:
for my $ColumnCounter ( 1 .. $#SourceColumns ) {
my $Column = $SourceColumns[$ColumnCounter];

next COLUMN unless $Self->{BlobColumns}->{ lc "$SourceTable.$Column" };
next COLUMN unless $BlobConversionNeeded{$SourceTable}->{$Column};

if ( !$SourceDBObject->GetDatabaseFunction('DirectBlob') ) {
$Row[$ColumnCounter] = decode_base64( $Row[$ColumnCounter] );
Expand Down
23 changes: 12 additions & 11 deletions Kernel/System/MigrateFromOTRS/CloneDB/Driver/mysql.pm
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ sub ColumnsList {
return \@Result;
}

# Get all binary columns and return table.column
# Get all binary columns and return a lookup hash with table and column name as keys.
sub BlobColumnsList {
my $Self = shift;
my %Param = @_;
Expand All @@ -148,19 +148,20 @@ sub BlobColumnsList {
}

$Param{DBObject}->Prepare(
SQL => "
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND DATA_TYPE = 'longblob';",

Bind => [
\$Param{DBName}, \$Param{Table},
],
SQL => <<'END_SQL',
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ?
AND TABLE_NAME = ?
AND DATA_TYPE = 'longblob';
END_SQL
Bind => [ \$Param{DBName}, \$Param{Table}, ],
) || return {};

my %Result;
while ( my @Row = $Param{DBObject}->FetchrowArray() ) {
my $TCString = "$Param{Table}.$Row[0]";
$Result{$TCString} = '1';
while ( my ($Column, $Type) = $Param{DBObject}->FetchrowArray() ) {
$Result{ $Param{Table} } //= {};
$Result{ $Param{Table} }->{ $Column } = $Type;
}

return \%Result;
Expand Down
22 changes: 12 additions & 10 deletions Kernel/System/MigrateFromOTRS/CloneDB/Driver/oracle.pm
Original file line number Diff line number Diff line change
Expand Up @@ -243,20 +243,22 @@ sub BlobColumnsList {
}

$Param{DBObject}->Prepare(
SQL => "
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND DATA_TYPE = 'CLOB';",

Bind => [
\$Param{DBName}, \$Param{Table},
],
SQL => <<'END_SQL',
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ?
AND TABLE_NAME = ?
AND DATA_TYPE = 'CLOB';
END_SQL
Bind => [ \$Param{DBName}, \$Param{Table} ],
) || return {};

my %Result;
while ( my @Row = $Param{DBObject}->FetchrowArray() ) {
my $TCString = "$Param{Table}.$Row[0]";
$Result{$TCString} = $Row[1];
while ( my ($Column, $Type) = $Param{DBObject}->FetchrowArray() ) {
$Result{ $Param{Table} } //= {};
$Result{ $Param{Table} }->{ $Column } = $Type;
}

return \%Result;
}

Expand Down

0 comments on commit 53f718b

Please sign in to comment.