Bug 38489: (follow-up) Improve idempotency of update

We needed better idempotency around checking for fields before
attempting to use them during migration and then dropping them.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Martin Renvoize 2025-10-15 17:27:29 +01:00 committed by Lucas Gass
parent eb5c38a5ab
commit b9bee6a07c
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
1 changed files with 81 additions and 74 deletions

View File

@ -41,10 +41,17 @@ return {
"Added 'local' transport type to file_transports table"
);
# Migrate then drop the old transport-related columns from vendor_edi_accounts
my @columns_to_drop =
qw(host username password upload_port download_port upload_directory download_directory transport);
my $all_exist = @columns_to_drop == grep { column_exists( 'vendor_edi_accounts', "$_" ) } @columns_to_drop;
# Migrate existing EDI transport configurations to file_transports
my $migration_count = 0;
my $edi_accounts_sth = $dbh->prepare(
q{
if ($all_exist) {
my $migration_count = 0;
my $edi_accounts_sth = $dbh->prepare(
q{
SELECT id, description, host, username, password, upload_port, download_port,
upload_directory, download_directory, transport
FROM vendor_edi_accounts
@ -52,91 +59,91 @@ return {
AND host IS NOT NULL
AND host != ''
}
);
$edi_accounts_sth->execute();
);
$edi_accounts_sth->execute();
my $insert_transport_sth = $dbh->prepare(
q{
my $insert_transport_sth = $dbh->prepare(
q{
INSERT INTO file_transports (name, host, port, transport, user_name, password,
upload_directory, download_directory, auth_mode, passive, debug)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'password', 1, 0)
}
);
);
my $update_edi_account_sth = $dbh->prepare(
q{
my $update_edi_account_sth = $dbh->prepare(
q{
UPDATE vendor_edi_accounts SET file_transport_id = ? WHERE id = ?
}
);
);
while ( my $row = $edi_accounts_sth->fetchrow_hashref ) {
while ( my $row = $edi_accounts_sth->fetchrow_hashref ) {
# Determine appropriate port (default to SFTP=22, FTP=21, Local=NULL)
my $port = $row->{upload_port} || $row->{download_port};
unless ($port) {
if ( uc( $row->{transport} ) eq 'SFTP' ) {
$port = 22;
} elsif ( uc( $row->{transport} ) eq 'FILE' ) {
$port = undef; # Local transport doesn't use ports
} else {
$port = 21; # FTP default
# Determine appropriate port
# (default to SFTP=22, FTP=21, Local=NULL)
my $port = $row->{upload_port} || $row->{download_port};
unless ($port) {
if ( uc( $row->{transport} ) eq 'SFTP' ) {
$port = 22;
} elsif ( uc( $row->{transport} ) eq 'FILE' ) {
$port = undef; # Local transport doesn't use ports
} else {
$port = 21; # FTP default
}
}
# Map transport type
# (normalize case and handle FILE -> local)
my $transport_type = lc( $row->{transport} );
$transport_type = 'local' if $transport_type eq 'file';
$transport_type = 'ftp'
unless $transport_type =~ /^(sftp|local)$/;
# Create transport name from EDI account description
my $transport_name = sprintf( "EDI Transport for %s", $row->{description} );
# Handle host for local transport
my $host = $row->{host};
$host = 'localhost' if $transport_type eq 'local' && !$host;
# Insert new file transport
$insert_transport_sth->execute(
$transport_name,
$host,
$port,
$transport_type,
$row->{username},
$row->{password}, # Password is already encrypted in EDI accounts
$row->{upload_directory},
$row->{download_directory}
);
my $transport_id = $dbh->last_insert_id(
undef, undef, 'file_transports',
'file_transport_id'
);
# Update EDI account to reference the new transport
$update_edi_account_sth->execute(
$transport_id,
$row->{id}
);
$migration_count++;
}
# Map transport type (normalize case and handle FILE -> local)
my $transport_type = lc( $row->{transport} );
$transport_type = 'local' if $transport_type eq 'file';
$transport_type = 'ftp'
unless $transport_type =~ /^(sftp|local)$/;
if ( $migration_count > 0 ) {
say_success(
$out,
"Successfully migrated $migration_count EDI transport configurations to file_transports"
);
} else {
say_info(
$out,
"No EDI transport configurations found to migrate"
);
}
# Create transport name from EDI account description
my $transport_name = sprintf( "EDI Transport for %s", $row->{description} );
# Handle host for local transport
my $host = $row->{host};
$host = 'localhost' if $transport_type eq 'local' && !$host;
# Insert new file transport
$insert_transport_sth->execute(
$transport_name,
$host,
$port,
$transport_type,
$row->{username},
$row->{password}, # Password is already encrypted in EDI accounts
$row->{upload_directory},
$row->{download_directory}
);
my $transport_id = $dbh->last_insert_id(
undef, undef, 'file_transports',
'file_transport_id'
);
# Update EDI account to reference the new transport
$update_edi_account_sth->execute( $transport_id, $row->{id} );
$migration_count++;
}
if ( $migration_count > 0 ) {
say_success(
$out,
"Successfully migrated $migration_count EDI transport configurations to file_transports"
);
} else {
say_info(
$out,
"No EDI transport configurations found to migrate"
);
}
# Drop the old transport-related columns from vendor_edi_accounts
my @columns_to_drop =
qw(host username password upload_port download_port upload_directory download_directory transport);
for my $column (@columns_to_drop) {
if ( column_exists( 'vendor_edi_accounts', $column ) ) {
for my $column (@columns_to_drop) {
$dbh->do("ALTER TABLE vendor_edi_accounts DROP COLUMN $column");
say_success(
$out,