Files
crm.clientright.ru/fix_nextcloud_collation_all.php
Fedor 840acca51a feat(documents): дедупликация documents_meta и исправление field_label
- Исправлен N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js: использовать uploads_field_labels[0] вместо [grp]
- Создан SQL_CLAIMSAVE_FIXED_NEW_FLOW_DEDUP.sql с дедупликацией documents_meta
- Создан SQL_CLEANUP_DOCUMENTS_META_DUPLICATES.sql для очистки существующих дубликатов
- Создан полный уникальный индекс idx_document_texts_hash_unique на document_texts(file_hash)
- Добавлен SESSION_LOG_2025-11-28_documents_dedup.md с описанием всех изменений

Fixes:
- field_label теперь корректно отображает 'Переписка' вместо 'group-2'
- documents_meta не накапливает дубликаты при повторных сохранениях
- ON CONFLICT (file_hash) теперь работает для document_texts
2025-11-28 18:16:53 +03:00

138 lines
4.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Исправление всех колонок с неправильной collation в Nextcloud
* Исправляет utf8mb3_general_ci → utf8mb4_general_ci
*/
$dbHost = '192.168.128.3';
$dbUser = 'nextcloud';
$dbPass = 'nextcloud_password';
$dbName = 'nextcloud';
try {
$pdo = new PDO(
"mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4",
$dbUser,
$dbPass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
echo "=== ИСПРАВЛЕНИЕ COLLATION В NEXTCLOUD ===\n\n";
// Находим все колонки с неправильной collation
$query = "
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
CHARACTER_SET_NAME,
COLLATION_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = ?
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION_NAME = 'utf8mb3_general_ci'
ORDER BY TABLE_NAME, COLUMN_NAME
";
$stmt = $pdo->prepare($query);
$stmt->execute([$dbName]);
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($columns)) {
echo "Все колонки уже имеют правильную collation!\n";
exit(0);
}
echo "Найдено колонок с неправильной collation: " . count($columns) . "\n\n";
$fixed = 0;
$errors = 0;
foreach ($columns as $col) {
$table = $col['TABLE_NAME'];
$column = $col['COLUMN_NAME'];
$dataType = $col['DATA_TYPE'];
$charSet = $col['CHARACTER_SET_NAME'];
// Определяем новый тип данных
$newCharSet = 'utf8mb4';
$newCollation = 'utf8mb4_general_ci';
// Для TEXT типов нужно указать CHARACTER SET
$alterQuery = "ALTER TABLE `$table` MODIFY COLUMN `$column` ";
if (in_array(strtoupper($dataType), ['VARCHAR', 'CHAR', 'TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT'])) {
// Получаем текущие параметры колонки
$colInfoQuery = "SHOW FULL COLUMNS FROM `$table` WHERE Field = ?";
$colInfoStmt = $pdo->prepare($colInfoQuery);
$colInfoStmt->execute([$column]);
$colInfo = $colInfoStmt->fetch(PDO::FETCH_ASSOC);
if ($colInfo) {
$type = $colInfo['Type'];
// Заменяем charset в типе
$type = preg_replace('/utf8mb3/i', 'utf8mb4', $type);
$type = preg_replace('/utf8(_general_ci)?/i', 'utf8mb4', $type);
$null = $colInfo['Null'] === 'YES' ? 'NULL' : 'NOT NULL';
$default = $colInfo['Default'] !== null ? "DEFAULT '{$colInfo['Default']}'" : '';
$extra = $colInfo['Extra'] ?: '';
$alterQuery .= "$type CHARACTER SET $newCharSet COLLATE $newCollation $null $default $extra";
} else {
echo "⚠️ Не удалось получить информацию о колонке $table.$column\n";
continue;
}
} else {
// Для других типов просто меняем collation
$alterQuery .= "`$column` $dataType CHARACTER SET $newCharSet COLLATE $newCollation";
}
try {
echo "Исправляю: $table.$column ... ";
$pdo->exec($alterQuery);
echo "\n";
$fixed++;
} catch (PDOException $e) {
echo "❌ Ошибка: " . $e->getMessage() . "\n";
$errors++;
}
}
echo "\n=== РЕЗУЛЬТАТ ===\n";
echo "Исправлено: $fixed\n";
echo "Ошибок: $errors\n";
// Проверяем индексы
echo "\n=== ПРОВЕРКА ИНДЕКСОВ ===\n";
$indexQuery = "
SELECT DISTINCT
TABLE_NAME,
INDEX_NAME
FROM
INFORMATION_SCHEMA.STATISTICS
WHERE
TABLE_SCHEMA = ?
AND TABLE_NAME LIKE 'oc_%'
AND COLLATION = 'utf8mb3_general_ci'
";
$indexStmt = $pdo->prepare($indexQuery);
$indexStmt->execute([$dbName]);
$indexes = $indexStmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($indexes)) {
echo "⚠️ Найдено индексов с неправильной collation: " . count($indexes) . "\n";
echo "Индексы нужно пересоздать вручную или через Nextcloud\n";
} else {
echo "Все индексы имеют правильную collation\n";
}
} catch (PDOException $e) {
echo "❌ Ошибка подключения к БД: " . $e->getMessage() . "\n";
exit(1);
}