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:
Torsten Schulz (local)
2025-09-01 11:27:09 +02:00
parent 3a02ffb3e3
commit 52556a4292
3 changed files with 103 additions and 2 deletions

View 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();