/** * Alter a text column definition preserving its character set. * * @param type $change * @param type $substep */ function textfield_alter($change, $substep) { global $db_prefix; $db = database(); $request = $db->query('', ' SHOW FULL COLUMNS FROM {db_prefix}' . $change['table'] . ' LIKE {string:column}', array('column' => $change['column'], 'db_error_skip' => true)); if ($db->num_rows($request) === 0) { die('Unable to find column ' . $change['column'] . ' inside table ' . $db_prefix . $change['table']); } $table_row = $db->fetch_assoc($request); $db->free_result($request); // If something of the current column definition is different, fix it. $column_fix = $table_row['Type'] !== $change['type'] || (strtolower($table_row['Null']) === 'yes') !== $change['null_allowed'] || ($table_row['Default'] === null) !== !isset($change['default']) || isset($change['default']) && $change['default'] !== $table_row['Default']; // Columns that previously allowed null, need to be converted first. $null_fix = strtolower($table_row['Null']) === 'yes' && !$change['null_allowed']; // Get the character set that goes with the collation of the column. if ($column_fix && !empty($table_row['Collation'])) { $request = $db->query('', ' SHOW COLLATION LIKE {string:collation}', array('collation' => $table_row['Collation'], 'db_error_skip' => true)); // No results? Just forget it all together. if ($db->num_rows($request) === 0) { unset($table_row['Collation']); } else { $collation_info = $db->fetch_assoc($request); } $db->free_result($request); } if ($column_fix) { // Make sure there are no NULL's left. if ($null_fix) { $db->query('', ' UPDATE {db_prefix}' . $change['table'] . ' SET ' . $change['column'] . ' = {string:default} WHERE ' . $change['column'] . ' IS NULL', array('default' => isset($change['default']) ? $change['default'] : '', 'db_error_skip' => true)); } // Do the actual alteration. $db->query('', ' ALTER TABLE {db_prefix}' . $change['table'] . ' CHANGE COLUMN ' . $change['column'] . ' ' . $change['column'] . ' ' . $change['type'] . (isset($collation_info['Charset']) ? ' CHARACTER SET ' . $collation_info['Charset'] . ' COLLATE ' . $collation_info['Collation'] : '') . ($change['null_allowed'] ? '' : ' NOT NULL') . (isset($change['default']) ? ' default {string:default}' : ''), array('default' => isset($change['default']) ? $change['default'] : '', 'db_error_skip' => true)); } nextSubstep($substep); }
function textfield_alter($change, $substep) { global $db_prefix; // Versions of MySQL < 4.1 wouldn't benefit from character set detection. if (version_compare('4.1.0', preg_replace('~\\-.+?$~', '', min(mysql_get_server_info(), mysql_get_client_info()))) > 0) { $column_fix = true; $null_fix = !$change['null_allowed']; } else { $request = upgrade_query("\n\t\t\tSHOW FULL COLUMNS \n\t\t\tFROM {$db_prefix}{$change['table']}\n\t\t\tLIKE '{$change['column']}'"); if (mysql_num_rows($request) === 0) { die('Unable to find column ' . $change['column'] . ' inside table ' . $db_prefix . $change['table']); } $table_row = mysql_fetch_assoc($request); mysql_free_result($request); // If something of the current column definition is different, fix it. $column_fix = $table_row['Type'] !== $change['type'] || (strtolower($table_row['Null']) === 'yes') !== $change['null_allowed'] || ($table_row['Default'] == NULL) !== !isset($change['default']) || isset($change['default']) && $change['default'] !== $table_row['Default']; // Columns that previously allowed null, need to be converted first. $null_fix = strtolower($table_row['Null']) === 'yes' && !$change['null_allowed']; // Get the character set that goes with the collation of the column. if ($column_fix && !empty($table_row['Collation'])) { $request = upgrade_query("\n\t\t\t\tSHOW COLLATION\n\t\t\t\tLIKE '{$table_row['Collation']}'"); // No results? Just forget it all together. if (mysql_num_rows($request) === 0) { unset($table_row['Collation']); } else { $collation_info = mysql_fetch_assoc($request); } mysql_free_result($request); } } if ($column_fix) { // Make sure there are no NULL's left. if ($null_fix) { upgrade_query("\n\t\t\t\tUPDATE {$db_prefix}{$change['table']}\n\t\t\t\tSET {$change['column']} = '" . (isset($change['default']) ? addslashes($change['default']) : '') . "'\n\t\t\t\tWHERE {$change['column']} IS NULL"); } // Do the actual alteration. upgrade_query("\n\t\t\tALTER TABLE {$db_prefix}{$change['table']}\n\t\t\tCHANGE COLUMN {$change['column']} {$change['column']} {$change['type']}" . (isset($collation_info['Charset']) ? " CHARACTER SET {$collation_info['Charset']} COLLATE {$collation_info['Collation']}" : '') . ($change['null_allowed'] ? '' : ' NOT NULL') . (isset($change['default']) ? " default '" . addslashes($change['default']) . "'" : '')); } nextSubstep($substep); }