Files
yourpart3/backend/utils/cleanupDatabaseConstraints.js
Torsten Schulz (local) e168adeb51 feat(match3): Erweiterung der Match3-Admin-Funktionalitäten und -Modelle
- Implementierung neuer Endpunkte für die Verwaltung von Match3-Kampagnen, Levels, Objectives und Tile-Typen im Admin-Bereich.
- Anpassung der Admin-Services zur Unterstützung von Benutzerberechtigungen und Fehlerbehandlung.
- Einführung von neuen Modellen und Assoziationen für Match3-Levels und Tile-Typen in der Datenbank.
- Verbesserung der Internationalisierung für Match3-spezifische Texte in Deutsch und Englisch.
- Aktualisierung der Frontend-Routen und -Komponenten zur Verwaltung von Match3-Inhalten.
2025-08-23 06:00:29 +02:00

235 lines
11 KiB
JavaScript

import { sequelize } from './sequelize.js';
/**
* Bereinigt doppelte Constraints und Indexe in der Datenbank
* Dies sollte nur einmal ausgeführt werden, um bestehende Probleme zu beheben
*/
async function cleanupDatabaseConstraints() {
try {
console.log('🧹 Starte Bereinigung der Datenbank-Constraints...');
// 1. Doppelte UNIQUE Constraints entfernen
console.log('🔍 Suche nach doppelten UNIQUE Constraints...');
const duplicateUniqueConstraints = await sequelize.query(`
SELECT
tc.table_schema,
tc.table_name,
kcu.column_name,
COUNT(*) as constraint_count,
array_agg(tc.constraint_name) as constraint_names
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'UNIQUE'
AND tc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
GROUP BY tc.table_schema, tc.table_name, kcu.column_name
HAVING COUNT(*) > 1
ORDER BY tc.table_name, kcu.column_name;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Gefunden: ${duplicateUniqueConstraints.length} Spalten mit doppelten UNIQUE Constraints`);
// Entferne doppelte UNIQUE Constraints
for (const duplicate of duplicateUniqueConstraints) {
console.log(`🗑️ Entferne doppelte UNIQUE Constraints für ${duplicate.table_schema}.${duplicate.table_name}.${duplicate.column_name}`);
// Behalte den ersten Constraint, entferne die anderen
const constraintNames = duplicate.constraint_names;
for (let i = 1; i < constraintNames.length; i++) {
const constraintName = constraintNames[i];
try {
await sequelize.query(`
ALTER TABLE ${duplicate.table_schema}.${duplicate.table_name}
DROP CONSTRAINT IF EXISTS "${constraintName}"
`);
console.log(` ✅ Entfernt: ${constraintName}`);
} catch (error) {
console.log(` ⚠️ Konnte nicht entfernen: ${constraintName} - ${error.message}`);
}
}
}
// 2. Doppelte CHECK Constraints entfernen (korrigierte Abfrage)
console.log('🔍 Suche nach doppelten CHECK Constraints...');
try {
const duplicateCheckConstraints = await sequelize.query(`
SELECT
ttc.table_schema,
ttc.table_name,
tc.constraint_name,
tc.check_clause
FROM information_schema.check_constraints tc
JOIN information_schema.table_constraints ttc
ON tc.constraint_name = ttc.constraint_name
WHERE ttc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
ORDER BY ttc.table_name, tc.constraint_name;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Gefunden: ${duplicateCheckConstraints.length} CHECK Constraints`);
} catch (error) {
console.log(`⚠️ Konnte CHECK Constraints nicht abfragen: ${error.message}`);
}
// 3. Doppelte Foreign Key Constraints entfernen
console.log('🔍 Suche nach doppelten Foreign Key Constraints...');
const duplicateFKs = await sequelize.query(`
SELECT
tc.constraint_name,
tc.table_name,
tc.table_schema,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
ORDER BY tc.table_name, tc.constraint_name;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Gefunden: ${duplicateFKs.length} Foreign Key Constraints`);
// 4. Doppelte Indexe entfernen
console.log('🔍 Suche nach doppelten Indexen...');
const duplicateIndexes = await sequelize.query(`
SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname IN ('match3', 'community', 'falukant_data', 'falukant_type', 'falukant_predefine', 'falukant_log', 'chat', 'forum', 'logs', 'type', 'service')
AND indexname LIKE '%_index_%'
ORDER BY tablename, indexname;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Gefunden: ${duplicateIndexes.length} potenziell doppelte Indexe`);
// 5. Spezifische Match3-Constraints prüfen
console.log('🔍 Prüfe Match3-spezifische Constraints...');
const match3Constraints = await sequelize.query(`
SELECT
constraint_name,
table_name,
constraint_type
FROM information_schema.table_constraints
WHERE table_schema = 'match3'
ORDER BY table_name, constraint_type;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Match3 Constraints: ${match3Constraints.length} gefunden`);
match3Constraints.forEach(constraint => {
console.log(` - ${constraint.table_name}: ${constraint.constraint_type} (${constraint.constraint_name})`);
});
// 6. Spezifische Chat-Constraints prüfen (da das Problem dort auftritt)
console.log('🔍 Prüfe Chat-spezifische Constraints...');
try {
const chatConstraints = await sequelize.query(`
SELECT
tc.constraint_name,
tc.table_name,
tc.constraint_type,
kcu.column_name
FROM information_schema.table_constraints tc
LEFT JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.table_schema = 'chat'
ORDER BY tc.table_name, tc.constraint_type, kcu.column_name;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Chat Constraints: ${chatConstraints.length} gefunden`);
chatConstraints.forEach(constraint => {
console.log(` - ${constraint.table_name}: ${constraint.constraint_type} (${constraint.constraint_name}) auf Spalte: ${constraint.column_name}`);
});
} catch (error) {
console.log(`⚠️ Konnte Chat Constraints nicht abfragen: ${error.message}`);
}
// 7. Spezifische Überprüfung der chat.rights Tabelle
console.log('🔍 Spezielle Überprüfung der chat.rights Tabelle...');
try {
const rightsConstraints = await sequelize.query(`
SELECT
tc.constraint_name,
tc.constraint_type,
kcu.column_name
FROM information_schema.table_constraints tc
LEFT JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.table_schema = 'chat'
AND tc.table_name = 'rights'
ORDER BY tc.constraint_type, kcu.column_name;
`, { type: sequelize.QueryTypes.SELECT });
console.log(`📊 Chat Rights Constraints: ${rightsConstraints.length} gefunden`);
rightsConstraints.forEach(constraint => {
console.log(` - ${constraint.constraint_type} (${constraint.constraint_name}) auf Spalte: ${constraint.column_name}`);
});
// Entferne alle doppelten UNIQUE Constraints auf der tr-Spalte
const trUniqueConstraints = rightsConstraints.filter(c =>
c.constraint_type === 'UNIQUE' && c.column_name === 'tr'
);
if (trUniqueConstraints.length > 1) {
console.log(`🗑️ Entferne ${trUniqueConstraints.length - 1} doppelte UNIQUE Constraints auf chat.rights.tr`);
// Behalte den ersten, entferne die anderen
for (let i = 1; i < trUniqueConstraints.length; i++) {
const constraintName = trUniqueConstraints[i].constraint_name;
try {
await sequelize.query(`
ALTER TABLE chat.rights
DROP CONSTRAINT IF EXISTS "${constraintName}"
`);
console.log(` ✅ Entfernt: ${constraintName}`);
} catch (error) {
console.log(` ⚠️ Konnte nicht entfernen: ${constraintName} - ${error.message}`);
}
}
}
} catch (error) {
console.log(`⚠️ Konnte chat.rights Constraints nicht abfragen: ${error.message}`);
}
// 8. Empfehlungen ausgeben
console.log('\n💡 Empfehlungen:');
console.log('1. Überprüfe die oben gelisteten Constraints auf Duplikate');
console.log('2. Verwende updateSchema() nur bei expliziten Schema-Änderungen');
console.log('3. Normale syncModels() läuft jetzt ohne alter: true');
console.log('4. Bei Problemen: Manuelle Bereinigung der doppelten Constraints');
console.log('✅ Datenbank-Constraint-Bereinigung abgeschlossen');
} catch (error) {
console.error('❌ Fehler bei der Constraint-Bereinigung:', error);
throw error;
}
}
// Führe das Skript aus, wenn es direkt aufgerufen wird
if (import.meta.url === `file://${process.argv[1]}`) {
cleanupDatabaseConstraints()
.then(() => {
console.log('🎯 Datenbank-Constraint-Bereinigung abgeschlossen');
process.exit(0);
})
.catch((error) => {
console.error('💥 Datenbank-Constraint-Bereinigung fehlgeschlagen:', error);
process.exit(1);
});
}
export default cleanupDatabaseConstraints;