Add queryWithTimeout helper for database operations in syncDatabase.js

- Introduced a new helper function to execute database queries with a timeout, improving error handling for long-running queries.
- Updated multiple cleanup operations to utilize the new helper, enhancing code readability and maintainability.
- Added descriptive logging for each cleanup operation to provide better insights into the database synchronization process.
This commit is contained in:
Torsten Schulz (local)
2026-01-22 17:18:27 +01:00
parent 10690b5a6e
commit 586aaec506

View File

@@ -1,6 +1,27 @@
// syncDatabase.js
import { initializeDatabase, syncModelsWithUpdates, syncModelsAlways, sequelize } from './sequelize.js';
// Helper: Query mit Timeout
const queryWithTimeout = async (query, timeoutMs = 30000, description = 'Query') => {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms`)), timeoutMs);
});
try {
const result = await Promise.race([
sequelize.query(query),
timeoutPromise
]);
return result;
} catch (error) {
if (error.message.includes('Timeout')) {
console.warn(`⚠️ ${description} hat Timeout nach ${timeoutMs}ms - überspringe...`);
return [null, 0]; // Return empty result
}
throw error;
}
};
import initializeTypes from './initializeTypes.js';
import initializeSettings from './initializeSettings.js';
import initializeUserRights from './initializeUserRights.js';
@@ -604,12 +625,12 @@ const syncDatabaseForDeployment = async () => {
try {
// Cleanup user_param_visibility (optimiert mit LEFT JOIN)
console.log(" → Prüfe user_param_visibility...");
const result1 = await sequelize.query(`
const result1 = await queryWithTimeout(`
DELETE FROM community.user_param_visibility
WHERE param_id NOT IN (
SELECT id FROM community.user_param
);
`, { timeout: 30000 });
`, 30000, 'user_param_visibility cleanup');
const deletedCount1 = result1[1] || 0;
if (deletedCount1 > 0) {
console.log(`${deletedCount1} verwaiste user_param_visibility Einträge entfernt`);
@@ -617,12 +638,12 @@ const syncDatabaseForDeployment = async () => {
// Cleanup stock mit ungültigen branch_id (0 oder nicht existierend)
console.log(" → Prüfe stock...");
const result2 = await sequelize.query(`
const result2 = await queryWithTimeout(`
DELETE FROM falukant_data.stock
WHERE branch_id = 0 OR branch_id NOT IN (
SELECT id FROM falukant_data.branch
);
`, { timeout: 30000 });
`, 30000, 'stock cleanup');
const deletedCount2 = result2[1] || 0;
if (deletedCount2 > 0) {
console.log(`${deletedCount2} verwaiste stock Einträge entfernt`);
@@ -630,14 +651,14 @@ const syncDatabaseForDeployment = async () => {
// Cleanup knowledge mit ungültigen character_id oder product_id
console.log(" → Prüfe knowledge...");
const result3 = await sequelize.query(`
const result3 = await queryWithTimeout(`
DELETE FROM falukant_data.knowledge
WHERE character_id NOT IN (
SELECT id FROM falukant_data.character
) OR product_id NOT IN (
SELECT id FROM falukant_type.product
);
`, { timeout: 30000 });
`, 30000, 'knowledge cleanup');
const deletedCount3 = result3[1] || 0;
if (deletedCount3 > 0) {
console.log(`${deletedCount3} verwaiste knowledge Einträge entfernt`);
@@ -645,12 +666,12 @@ const syncDatabaseForDeployment = async () => {
// Cleanup notification mit ungültigen user_id
console.log(" → Prüfe notification...");
const result4 = await sequelize.query(`
const result4 = await queryWithTimeout(`
DELETE FROM falukant_log.notification
WHERE user_id NOT IN (
SELECT id FROM falukant_data.falukant_user
);
`, { timeout: 30000 });
`, 30000, 'notification cleanup');
const deletedCount4 = result4[1] || 0;
if (deletedCount4 > 0) {
console.log(`${deletedCount4} verwaiste notification Einträge entfernt`);
@@ -658,14 +679,14 @@ const syncDatabaseForDeployment = async () => {
// Cleanup promotional_gift mit ungültigen sender_character_id oder recipient_character_id
console.log(" → Prüfe promotional_gift...");
const result5 = await sequelize.query(`
const result5 = await queryWithTimeout(`
DELETE FROM falukant_log.promotional_gift
WHERE sender_character_id NOT IN (
SELECT id FROM falukant_data.character
) OR recipient_character_id NOT IN (
SELECT id FROM falukant_data.character
);
`, { timeout: 30000 });
`, 30000, 'promotional_gift cleanup');
const deletedCount5 = result5[1] || 0;
if (deletedCount5 > 0) {
console.log(`${deletedCount5} verwaiste promotional_gift Einträge entfernt`);
@@ -673,14 +694,14 @@ const syncDatabaseForDeployment = async () => {
// Cleanup user_house mit ungültigen house_type_id oder user_id
console.log(" → Prüfe user_house...");
const result6 = await sequelize.query(`
const result6 = await queryWithTimeout(`
DELETE FROM falukant_data.user_house
WHERE house_type_id NOT IN (
SELECT id FROM falukant_type.house
) OR user_id NOT IN (
SELECT id FROM falukant_data.falukant_user
);
`, { timeout: 30000 });
`, 30000, 'user_house cleanup');
const deletedCount6 = result6[1] || 0;
if (deletedCount6 > 0) {
console.log(`${deletedCount6} verwaiste user_house Einträge entfernt`);
@@ -688,7 +709,7 @@ const syncDatabaseForDeployment = async () => {
// Cleanup child_relation mit ungültigen father_character_id, mother_character_id oder child_character_id
console.log(" → Prüfe child_relation...");
const result7 = await sequelize.query(`
const result7 = await queryWithTimeout(`
DELETE FROM falukant_data.child_relation
WHERE father_character_id NOT IN (
SELECT id FROM falukant_data.character
@@ -697,7 +718,7 @@ const syncDatabaseForDeployment = async () => {
) OR child_character_id NOT IN (
SELECT id FROM falukant_data.character
);
`, { timeout: 30000 });
`, 30000, 'child_relation cleanup');
const deletedCount7 = result7[1] || 0;
if (deletedCount7 > 0) {
console.log(`${deletedCount7} verwaiste child_relation Einträge entfernt`);
@@ -705,7 +726,7 @@ const syncDatabaseForDeployment = async () => {
// Cleanup political_office mit ungültigen character_id, office_type_id oder region_id
console.log(" → Prüfe political_office...");
const result8 = await sequelize.query(`
const result8 = await queryWithTimeout(`
DELETE FROM falukant_data.political_office
WHERE character_id NOT IN (
SELECT id FROM falukant_data.character
@@ -714,7 +735,7 @@ const syncDatabaseForDeployment = async () => {
) OR region_id NOT IN (
SELECT id FROM falukant_data.region
);
`, { timeout: 30000 });
`, 30000, 'political_office cleanup');
const deletedCount8 = result8[1] || 0;
if (deletedCount8 > 0) {
console.log(`${deletedCount8} verwaiste political_office Einträge entfernt`);
@@ -722,7 +743,7 @@ const syncDatabaseForDeployment = async () => {
// Cleanup church_office mit ungültigen character_id, office_type_id oder region_id
console.log(" → Prüfe church_office...");
const result11 = await sequelize.query(`
const result11 = await queryWithTimeout(`
DELETE FROM falukant_data.church_office
WHERE character_id NOT IN (
SELECT id FROM falukant_data.character
@@ -731,7 +752,7 @@ const syncDatabaseForDeployment = async () => {
) OR region_id NOT IN (
SELECT id FROM falukant_data.region
);
`, { timeout: 30000 });
`, 30000, 'church_office cleanup');
const deletedCount11 = result11[1] || 0;
if (deletedCount11 > 0) {
console.log(`${deletedCount11} verwaiste church_office Einträge entfernt`);
@@ -739,7 +760,7 @@ const syncDatabaseForDeployment = async () => {
// Cleanup church_application mit ungültigen character_id, office_type_id, region_id oder supervisor_id
console.log(" → Prüfe church_application...");
const result12 = await sequelize.query(`
const result12 = await queryWithTimeout(`
DELETE FROM falukant_data.church_application
WHERE character_id NOT IN (
SELECT id FROM falukant_data.character
@@ -750,7 +771,7 @@ const syncDatabaseForDeployment = async () => {
) OR supervisor_id NOT IN (
SELECT id FROM falukant_data.character
);
`, { timeout: 30000 });
`, 30000, 'church_application cleanup');
const deletedCount12 = result12[1] || 0;
if (deletedCount12 > 0) {
console.log(`${deletedCount12} verwaiste church_application Einträge entfernt`);
@@ -758,20 +779,20 @@ const syncDatabaseForDeployment = async () => {
// Cleanup vehicle.condition: Legacy-Nulls + Range clamp (UI zeigt sonst "Unbekannt")
console.log(" → Prüfe vehicle.condition...");
const result9 = await sequelize.query(`
const result9 = await queryWithTimeout(`
UPDATE falukant_data.vehicle
SET condition = 100
WHERE condition IS NULL;
`, { timeout: 30000 });
`, 30000, 'vehicle condition NULL update');
const updatedNullConditions = result9[1] || 0;
if (updatedNullConditions > 0) {
console.log(`${updatedNullConditions} vehicle.condition NULL → 100 gesetzt`);
}
const result10 = await sequelize.query(`
const result10 = await queryWithTimeout(`
UPDATE falukant_data.vehicle
SET condition = GREATEST(0, LEAST(100, condition))
WHERE condition < 0 OR condition > 100;
`, { timeout: 30000 });
`, 30000, 'vehicle condition clamp');
const clampedConditions = result10[1] || 0;
if (clampedConditions > 0) {
console.log(`${clampedConditions} vehicle.condition Werte auf 0..100 geklemmt`);