PHP Script для исправления колонок MySQL для работы в строгом режиме - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь создать сценарий для генерации запросов ALTER TABLE, чтобы столбцы всей схемы настраивались так, чтобы они были совместимы с строгим режимом MySQL.

Я хочу, чтобы это было как можно проще.внесение самых основных изменений, возможных для значений NOT / NOT NULL и Default, для обеспечения совместимости в строгом режиме, но в то же время сводит к минимуму вероятность взлома любых существующих запросов или связанного кода PHP, который зависит от работы определения схемы.

Какие-нибудь советы / вещи, которые я пропустил / вещи, которые я, возможно, делаю неправильно ..?Кстати, я не думаю, что мне нужно охватывать абсолютно все типы столбцов, доступные в MySQL, поскольку я просто не использую некоторые из них.Но некоторые дополнительные операторы 'case:' не будут ошибаться ..;)

<?
include "common.inc.php";
include "header.inc.php";

$r_resultTables = dbQuery("SHOW TABLES");

echo '<textarea style="width: 95%; height: 80vh;">';
while ($a_rowTable = dbFetchRow($r_resultTables)) {
    $table = dbEscape($a_rowTable[0]);

    $tableNameAdded = false;

    $r_result = dbQuery("SHOW FULL FIELDS FROM `$table`");
    while ($a_row = dbFetchAssoc($r_result)) {

        $comment = null;
        $default = (($a_row['Default'] != NULL) ? "DEFAULT '" . $a_row['Default'] . "'" : '');
        $extra = null;

        $type = strtok($a_row['Type'],'(');

        $field = dbEscape($a_row['Field']);

        // Is the field allowed to be null?
        if ($a_row['Null'] == 'YES') {
            $nullable = 'NULL';
        } else {
            $nullable = 'NOT NULL';
        }

        // skip nullable fields with no set default (they will default to NULL)
        if (($a_row['Default'] === NULL) AND ($a_row['Null'] == 'YES')) {
            continue;
        }

        // skip PK fields
        if ($a_row['Key'] == 'PRI') { continue; }

        // fields that need a set default if they don't have one
        if ($a_row['Default'] === NULL) {
            switch ($type) {
                case 'int':
                case 'smallint':
                case 'tinyint':
                case 'mediumint':
                case 'bigint':
                case 'decimal':
                case 'numeric':
                case 'float':
                case 'double':
                    $comment = "Numeric field should have '0' as default (if missing)";
                    $default = "DEFAULT '0'";
                    break;
                case 'char':
                case 'varchar':
                    $comment = "(VAR)CHAR fields should have empty string as default (if missing)";
                    $default = "DEFAULT ''";
                    break;
            }
        }

        // fields that need changing anyway if they're not already nullable, or can be skipped
        switch ($type) {
            case 'datetime':
            case 'date':
            case 'timestamp':
            case 'year':
            case 'time':
                if (substr($a_row['Default'],0,2) == '00') {
                    $comment = "Date/Time types cannot default to zeroes, should be NULLable (if missing)";
                    $extra = "UPDATE `$table` SET `$field` = NULL WHERE `$field` = '" . $a_row['Default'] . "';";
                    $default = "DEFAULT NULL";
                } elseif ($a_row['Default'] == 'CURRENT_TIMESTAMP') {
                    continue 2;
                } else {
                    $comment = "Date/Time types should be NULLable if missing";
                }
                $nullable = 'NULL';
                break;
            case 'enum':
            case 'set':
                continue 2; // ENUM and SET types don't need any change
                break;
            case 'tinytext':
            case 'text':
            case 'mediumtext':
            case 'longtext':
                continue 2; // TEXT types cannot have a default value
                break;
            default:
                if ($a_row['Default'] !== NULL) { continue 2; } // skip any other types that already have defaults
                break;
        }

        if (!$tableNameAdded) {
            echo "\r\n# `$table`\r\n\r\n";
            $tableNameAdded = true;
        }

        // Alter table query
        if ($comment) { echo '# `' . $field . '` - ' . $comment . "\r\n"; } else { echo "# UNKNOWN\r\n" .  '# '; }
        echo  "ALTER TABLE `$table` CHANGE `$field` `$field` $a_row[Type] $nullable $default;\r\n";
        if ($extra) { echo $extra . "\r\n"; }
        echo "\r\n";
    }
}
echo '</textarea>';

include "footer.inc.php";

Использование информации о значениях по умолчанию здесь: https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html

И информация о строгом режиме отсюда: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

...