Fix schema-sync SQL normalization for MySQL compatibility

This commit is contained in:
DevSoftTech Server 2026-02-28 23:17:19 +05:30
parent a5e4ac6ced
commit b7f04316a4

View File

@ -192,7 +192,7 @@ class Setup extends BaseController
continue; continue;
} }
$createSql = preg_replace('/^CREATE\s+TABLE\s+/i', 'CREATE TABLE IF NOT EXISTS ', trim($createSql), 1) ?? $createSql; $createSql = $this->ensureCreateTableIfNotExists((string) $createSql);
if (!str_ends_with(trim($createSql), ';')) { if (!str_ends_with(trim($createSql), ';')) {
$createSql .= ';'; $createSql .= ';';
} }
@ -327,7 +327,7 @@ class Setup extends BaseController
if (!isset($clientTables[$table])) { if (!isset($clientTables[$table])) {
$createSql = (string) ($masterTableDef['create_sql'] ?? ''); $createSql = (string) ($masterTableDef['create_sql'] ?? '');
if ($createSql !== '') { if ($createSql !== '') {
$createSql = preg_replace('/^CREATE\s+TABLE\s+/i', 'CREATE TABLE IF NOT EXISTS ', trim($createSql), 1) ?? $createSql; $createSql = $this->ensureCreateTableIfNotExists((string) $createSql);
if (!str_ends_with($createSql, ';')) { if (!str_ends_with($createSql, ';')) {
$createSql .= ';'; $createSql .= ';';
} }
@ -376,7 +376,7 @@ class Setup extends BaseController
$errors = []; $errors = [];
foreach ($sqlList as $stmt) { foreach ($sqlList as $stmt) {
$stmt = trim((string) $stmt); $stmt = $this->normalizeSyncSql((string) $stmt);
if ($stmt === '') { if ($stmt === '') {
continue; continue;
} }
@ -586,7 +586,7 @@ class Setup extends BaseController
return ''; return '';
} }
$create = preg_replace('/^CREATE\s+TABLE\s+/i', 'CREATE TABLE IF NOT EXISTS ', trim($create), 1) ?? $create; $create = $this->ensureCreateTableIfNotExists((string) $create);
if (!str_ends_with($create, ';')) { if (!str_ends_with($create, ';')) {
$create .= ';'; $create .= ';';
} }
@ -655,14 +655,20 @@ class Setup extends BaseController
$default = $this->columnDefaultSql($col); $default = $this->columnDefaultSql($col);
$collation = trim((string) ($col['Collation'] ?? '')); $collation = trim((string) ($col['Collation'] ?? ''));
$comment = trim((string) ($col['Comment'] ?? '')); $comment = trim((string) ($col['Comment'] ?? ''));
$applyCollation = strtolower(trim((string) env('setup.sync.apply_column_collation', 'false')));
$canApplyCollation = in_array($applyCollation, ['1', 'true', 'yes', 'on'], true);
$sql = '`' . $name . '` ' . $type; $sql = '`' . $name . '` ' . $type;
if ($collation !== '') { if ($collation !== '' && $canApplyCollation) {
$sql .= ' COLLATE ' . $collation; $sql .= ' COLLATE ' . $this->normalizeCollationName($collation);
} }
$sql .= $null . $default; $sql .= $null . $default;
if ($extra !== '') { if ($extra !== '') {
$sql .= ' ' . strtoupper($extra); $extra = preg_replace('/\bDEFAULT_GENERATED\b/i', '', $extra) ?? $extra;
$extra = trim(preg_replace('/\s+/', ' ', $extra) ?? $extra);
if ($extra !== '') {
$sql .= ' ' . strtoupper($extra);
}
} }
if ($comment !== '') { if ($comment !== '') {
$sql .= " COMMENT '" . str_replace("'", "''", $comment) . "'"; $sql .= " COMMENT '" . str_replace("'", "''", $comment) . "'";
@ -699,11 +705,51 @@ class Setup extends BaseController
strtoupper((string) ($col['Null'] ?? 'YES')), strtoupper((string) ($col['Null'] ?? 'YES')),
(string) ($col['Default'] ?? ''), (string) ($col['Default'] ?? ''),
strtolower((string) ($col['Extra'] ?? '')), strtolower((string) ($col['Extra'] ?? '')),
strtolower((string) ($col['Collation'] ?? '')),
(string) ($col['Comment'] ?? ''), (string) ($col['Comment'] ?? ''),
]) ?: ''; ]) ?: '';
} }
private function ensureCreateTableIfNotExists(string $sql): string
{
$sql = trim($sql);
if ($sql === '') {
return '';
}
$sql = preg_replace('/^CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?/i', 'CREATE TABLE IF NOT EXISTS ', $sql, 1) ?? $sql;
return $this->normalizeSyncSql($sql);
}
private function normalizeCollationName(string $collation): string
{
$collation = trim($collation);
if ($collation === '') {
return '';
}
if (preg_match('/^utf8mb4_0900_/i', $collation) === 1) {
return (string) env('setup.sync.collation_fallback', 'utf8mb4_general_ci');
}
return $collation;
}
private function normalizeSyncSql(string $sql): string
{
$sql = trim($sql);
if ($sql === '') {
return '';
}
$sql = preg_replace('/\bDEFAULT_GENERATED\b/i', '', $sql) ?? $sql;
$sql = preg_replace('/\bCOLLATE\s+utf8mb4_0900_[a-z0-9_]+\b/i', 'COLLATE ' . $this->normalizeCollationName('utf8mb4_0900_ai_ci'), $sql) ?? $sql;
$sql = preg_replace('/^CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)+/i', 'CREATE TABLE IF NOT EXISTS ', $sql, 1) ?? $sql;
$sql = preg_replace('/\s+/', ' ', $sql) ?? $sql;
$sql = preg_replace('/\s+;$/', ';', $sql) ?? $sql;
return trim($sql);
}
private function indexDefinitionSql(array $idx): string private function indexDefinitionSql(array $idx): string
{ {
$name = (string) ($idx['name'] ?? ''); $name = (string) ($idx['name'] ?? '');