fix(installer): drop legacy remote columns in PHP, not PREPARE-based SQL
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 34s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 34s
02.56.01.sql used PREPARE/EXECUTE/DEALLOCATE to conditionally drop the 26 legacy remote_storage/ftp_*/sftp_*/gdrive_*/s3_* columns portably. Joomla's installer rejects those statements on MySQL 8 (error 1295: "This command is not supported in the prepared statement protocol yet"), aborting the whole component install when updating from an old schema. Neutralize 02.56.01.sql (now a no-op comment) and move the purge into Pkg_MokoSuiteBackupInstallerScript::dropLegacyRemoteColumns(): gate on INFORMATION_SCHEMA, then issue one plain ALTER dropping only the columns that still exist — portable on MariaDB and MySQL 8, idempotent, non-fatal. Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
This commit is contained in:
@@ -177,6 +177,10 @@ class Pkg_MokoSuiteBackupInstallerScript
|
||||
briefly used the "Type - Name" convention. Self-healing on every update. */
|
||||
$this->removeOrphanedComponent();
|
||||
|
||||
/* Drop legacy single-remote storage columns portably (replaces the old
|
||||
PREPARE/EXECUTE migration that MySQL 8 rejected in Joomla's installer). */
|
||||
$this->dropLegacyRemoteColumns();
|
||||
|
||||
/* Install completion notice (install and update) */
|
||||
$this->installSuccessful();
|
||||
|
||||
@@ -273,6 +277,54 @@ class Pkg_MokoSuiteBackupInstallerScript
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the 26 legacy single-remote storage columns from the profiles table if
|
||||
* they are still present. Replaces sql/updates/mysql/02.56.01.sql, whose
|
||||
* PREPARE/EXECUTE/DEALLOCATE approach is rejected by Joomla's installer on
|
||||
* MySQL 8 (error 1295) and aborted the whole install. Done here in PHP: gate on
|
||||
* INFORMATION_SCHEMA, then issue a plain ALTER for only the columns that exist —
|
||||
* portable across MariaDB and MySQL 8. Idempotent and non-fatal.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dropLegacyRemoteColumns(): void
|
||||
{
|
||||
try {
|
||||
$db = Factory::getDbo();
|
||||
$table = $db->getPrefix() . 'mokosuitebackup_profiles';
|
||||
|
||||
$columns = [
|
||||
'remote_storage',
|
||||
'ftp_host', 'ftp_port', 'ftp_username', 'ftp_password', 'ftp_path', 'ftp_passive', 'ftp_ssl',
|
||||
'sftp_host', 'sftp_port', 'sftp_username', 'sftp_auth_type', 'sftp_password', 'sftp_key_data', 'sftp_passphrase', 'sftp_path',
|
||||
'gdrive_client_id', 'gdrive_client_secret', 'gdrive_refresh_token', 'gdrive_folder_id',
|
||||
's3_endpoint', 's3_region', 's3_access_key', 's3_secret_key', 's3_bucket', 's3_path',
|
||||
];
|
||||
|
||||
// Which legacy columns still exist on this install?
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->select($db->quoteName('COLUMN_NAME'))
|
||||
->from($db->quoteName('INFORMATION_SCHEMA.COLUMNS'))
|
||||
->where($db->quoteName('TABLE_SCHEMA') . ' = DATABASE()')
|
||||
->where($db->quoteName('TABLE_NAME') . ' = ' . $db->quote($table))
|
||||
->where($db->quoteName('COLUMN_NAME') . ' IN (' . implode(',', array_map([$db, 'quote'], $columns)) . ')')
|
||||
);
|
||||
$present = $db->loadColumn();
|
||||
|
||||
if (empty($present)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$drops = array_map(fn($c) => 'DROP COLUMN ' . $db->quoteName($c), $present);
|
||||
$db->setQuery('ALTER TABLE ' . $db->quoteName($table) . ' ' . implode(', ', $drops));
|
||||
$db->execute();
|
||||
} catch (\Throwable $e) {
|
||||
/* Best-effort — a leftover column is harmless and must never abort the install */
|
||||
Log::add('MokoSuiteBackup legacy-remote-column drop failed: ' . $e->getMessage(), Log::WARNING, 'jerror');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively delete a directory (version-independent, no Folder dependency).
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user