fixed Sonarqube Code Issues
Sonarqube Scanner / Build and analyze (push) Successful in 1m8s

This commit is contained in:
Florian Zumpe
2026-09-02 01:05:30 +02:00
parent 4b1b6eeced
commit be9df67e18
5 changed files with 85 additions and 67 deletions
+26 -56
View File
@@ -3,66 +3,36 @@ import path from 'node:path';
const root = path.resolve(import.meta.dirname, '..');
const schemaPath = path.join(root, 'database/schema.sql');
const columnSql = ' activated_at DATETIME NULL';
function hasActivatedAt(schema) {
return /\bactivated_at\s+DATETIME\s+NULL\b/i.test(schema);
function tokens(line) {
return line
.trim()
.replaceAll(',', ' ')
.replaceAll(';', ' ')
.replaceAll('(', ' ')
.replaceAll(')', ' ')
.split(' ')
.map(token => token.trim())
.filter(Boolean);
}
function splitRouteTableBody(body) {
const lines = body.split('\n');
const trailing = [];
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
trailing.unshift(lines.pop());
}
return { lines, trailing };
}
function isTableConstraint(line) {
return /^\s*,?\s*(?:PRIMARY\s+KEY|CONSTRAINT|FOREIGN\s+KEY|UNIQUE\s*\()/i.test(line);
}
function hasLeadingComma(line) {
return /^\s*,/.test(line);
}
function ensureCommaBeforeInsert(lines, targetIndex) {
const previousIndex = targetIndex - 1;
if (previousIndex < 0) return;
const previous = lines[previousIndex].trimEnd();
if (!previous.endsWith(',')) lines[previousIndex] = `${previous},`;
}
function columnForTarget(lines, insertBefore) {
if (insertBefore === -1) return columnSql;
return hasLeadingComma(lines[insertBefore]) ? columnSql : `${columnSql},`;
}
function insertActivatedAt(schema) {
if (hasActivatedAt(schema)) return schema;
const routeTable = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?routes\s*\((?<body>[\s\S]*?)\);/i.exec(schema);
if (!routeTable?.groups?.body) {
throw new Error('Die routes-Tabelle wurde in database/schema.sql nicht gefunden.');
}
const tableSql = routeTable[0];
const body = routeTable.groups.body;
const { lines, trailing } = splitRouteTableBody(body);
const insertBefore = lines.findIndex(isTableConstraint);
const targetIndex = insertBefore === -1 ? lines.length : insertBefore;
ensureCommaBeforeInsert(lines, targetIndex);
lines.splice(targetIndex, 0, columnForTarget(lines, insertBefore));
return schema.replace(tableSql, tableSql.replace(body, [...lines, ...trailing].join('\n')));
function hasActivationColumn(schema) {
return schema
.split('\n')
.map(tokens)
.some(parts => {
const upper = parts.map(part => part.toUpperCase());
return upper[0] === 'ACTIVATED_AT'
&& upper[1] === 'TEXT'
&& upper.includes('DEFAULT')
&& upper.includes('NULL');
});
}
const schema = await fs.readFile(schemaPath, 'utf8');
const next = insertActivatedAt(schema);
if (next === schema) {
console.log('database/schema.sql enthält activated_at bereits.');
} else {
await fs.writeFile(schemaPath, next);
console.log('database/schema.sql wurde um routes.activated_at ergänzt.');
if (!hasActivationColumn(schema)) {
throw new Error('database/schema.sql muss routes.activated_at als TEXT DEFAULT NULL enthalten.');
}
console.log('database/schema.sql enthält routes.activated_at als SQLite-STRICT-kompatible TEXT-Spalte.');