Fügt ein neues Skript zur Bereinigung aller Indizes in package.json hinzu und entfernt überflüssige Leerzeichen in diaryDateActivityService.js.
This commit is contained in:
100
backend/scripts/cleanupAllIndexes.js
Normal file
100
backend/scripts/cleanupAllIndexes.js
Normal file
@@ -0,0 +1,100 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const dbConfig = {
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
user: process.env.DB_USER || 'root',
|
||||
password: process.env.DB_PASSWORD || '',
|
||||
database: process.env.DB_NAME || 'trainingdiary',
|
||||
};
|
||||
|
||||
async function getTables(connection) {
|
||||
const [rows] = await connection.execute(
|
||||
`SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_TYPE='BASE TABLE'`,
|
||||
[dbConfig.database]
|
||||
);
|
||||
return rows.map(r => r.TABLE_NAME);
|
||||
}
|
||||
|
||||
async function getIndexSummary(connection, table) {
|
||||
const [rows] = await connection.execute(`SHOW INDEX FROM \`${table}\``);
|
||||
const byName = rows.reduce((acc, r) => {
|
||||
const key = r.Key_name;
|
||||
if (!acc[key]) acc[key] = { nonUnique: r.Non_unique === 1, seqMap: {}, columns: [] };
|
||||
acc[key].seqMap[r.Seq_in_index] = r.Column_name;
|
||||
return acc;
|
||||
}, {});
|
||||
// normalize columns order by seq
|
||||
for (const name of Object.keys(byName)) {
|
||||
const cols = Object.keys(byName[name].seqMap)
|
||||
.sort((a, b) => Number(a) - Number(b))
|
||||
.map(k => byName[name].seqMap[k]);
|
||||
byName[name].columns = cols;
|
||||
}
|
||||
return byName;
|
||||
}
|
||||
|
||||
async function cleanupDuplicates(connection, table) {
|
||||
const before = await getIndexSummary(connection, table);
|
||||
const keepSignatureToName = new Map();
|
||||
const dropNames = [];
|
||||
|
||||
for (const [name, info] of Object.entries(before)) {
|
||||
if (name === 'PRIMARY') continue; // niemals Primary droppen
|
||||
const uniqueFlag = info.nonUnique ? 'N' : 'U';
|
||||
const sig = `${uniqueFlag}|${info.columns.join(',')}`;
|
||||
if (!keepSignatureToName.has(sig)) {
|
||||
keepSignatureToName.set(sig, name);
|
||||
} else {
|
||||
// doppelter Index mit gleicher Spaltenliste und gleicher Einzigartigkeit
|
||||
dropNames.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const idxName of dropNames) {
|
||||
try {
|
||||
await connection.execute(`DROP INDEX \`${idxName}\` ON \`${table}\``);
|
||||
console.log(`[drop] ${table}: ${idxName}`);
|
||||
} catch (e) {
|
||||
console.warn(`[warn] ${table}: konnte Index ${idxName} nicht löschen: ${e.code || e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
const after = await getIndexSummary(connection, table);
|
||||
return { beforeCount: Object.keys(before).length, afterCount: Object.keys(after).length, dropped: dropNames.length };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let connection;
|
||||
try {
|
||||
console.log('Connecting to DB:', dbConfig);
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
|
||||
const tables = await getTables(connection);
|
||||
console.log(`Found ${tables.length} tables`);
|
||||
|
||||
let totalBefore = 0;
|
||||
let totalAfter = 0;
|
||||
let totalDropped = 0;
|
||||
|
||||
for (const table of tables) {
|
||||
const { beforeCount, afterCount, dropped } = await cleanupDuplicates(connection, table);
|
||||
totalBefore += beforeCount;
|
||||
totalAfter += afterCount;
|
||||
totalDropped += dropped;
|
||||
}
|
||||
|
||||
console.log('Summary:', { totalBefore, totalAfter, totalDropped });
|
||||
} catch (e) {
|
||||
console.error('Cleanup failed:', e);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
if (connection) await connection.end();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user