const axios = require('axios'); const mongoose = require('mongoose').set('debug', false) const Schema = mongoose.Schema; const tools = require('../tools/general'); mongoose.Promise = global.Promise; mongoose.level = "F"; class MssqlMigrator { /** * Costruttore della classe MssqlMigrator * @param {string} serverUrl - URL del server che esegue le query MSSQL * @param {string} apiKey - API Key per l'autenticazione */ constructor() { this.serverUrl = process.env.SERVER_A_URL; this.apiKey = process.env.API_KEY_MSSQL; } /** * Migra una lista di tabelle MSSQL in MongoDB usando Mongoose * @param {string[]} tableNames - Lista dei nomi delle tabelle MSSQL * @returns {string} logs - Lista dei log di esecuzione */ async migrateTables(tableNames) { try { const numtables = tableNames.length; let indtab = 0; let indtabok = 0; const logs = []; for (const rectable of tableNames) { try { const tableName = rectable.table; const usaDataOra = rectable.usaDataOra; const fieldId = rectable.fieldId; const percentuale = ((indtab / numtables) * 100).toFixed(2); logs.push(`\n>> Recupero dati da MSSQL per la tabella: ${tableName} - (Completamento: ${percentuale}%)`); console.log(logs[logs.length - 1]); let dataQuery = `SELECT * FROM ${tableName}`; if (usaDataOra) { dataQuery = `SELECT T.* FROM ${tableName} T`; dataQuery += ` JOIN ( SELECT ${fieldId}, MAX(DataOra) AS data FROM ${tableName} GROUP BY ${fieldId} ) b ON T.${fieldId} = b.${fieldId} AND T.DataOra = b.data; `; } console.log('query', dataQuery); let dataResponse = null; try { dataResponse = await axios.post( `${this.serverUrl}/query`, { query: dataQuery }, { headers: { 'x-api-key': this.apiKey } }, null, { timeout: 900000 }); } catch (error) { console.error('Error: ', error.response?.data?.error || error.message || error); if (error.message === 'socket hang up') { console.log('Error: hangup, waiting 5 seconds and retrying...'); await new Promise(resolve => setTimeout(resolve, 5000)); dataResponse = await axios.post( `${this.serverUrl}/query`, { query: dataQuery }, { headers: { 'x-api-key': this.apiKey } }, null, { timeout: 900000 }); } else { console.error('Unexpected error while fetching data from MSSQL:', error.message); // throw error; } } const records = dataResponse?.data; if (!records || records.length === 0) { logs.push(`⚠️ Nessun record trovato per la tabella: ${tableName}`); console.log(logs[logs.length - 1]); continue; } const sample = records[0]; const schemaDef = {}; for (const key of Object.keys(sample)) { const value = sample[key]; if (typeof value === 'string' && key.startsWith('Data') && !isNaN(Date.parse(value))) { schemaDef[key] = Date; } else if (typeof value === 'number') { schemaDef[key] = Number; } else if (typeof value === 'boolean') { schemaDef[key] = Boolean; } else if (value instanceof Date) { schemaDef[key] = Date; } else { schemaDef[key] = mongoose.Schema.Types.Mixed; } } const dynamicSchema = new mongoose.Schema(schemaDef, { strict: false }); const modelName = tableName.charAt(0).toUpperCase() + tableName.slice(1); // Se il modello esiste già, lo riutilizziamo const DynamicModel = mongoose.models[modelName] || mongoose.model(modelName, dynamicSchema); // ❗ Elimina tutti i documenti esistenti prima dell'inserimento await DynamicModel.deleteMany({}); logs.push(`✅ Inserimento di ${records.length} record nella collezione MongoDB: ${modelName}`); console.log(logs[logs.length - 1]); await DynamicModel.insertMany(records); indtabok++; } catch (error) { logs.push(`❌ Errore con la tabella ${tableName}:`, error.message); console.log(logs[logs.length - 1]); } indtab++; } logs.push(`\n🎉 ${indtabok} tabelle su ${numtables} sono state migrate.`); console.log(logs[logs.length - 1]); return logs.join('\n'); } catch (error) { logs.push(`❌ Errore migrateTables:`, error.message); console.log(logs[logs.length - 1]); } } } module.exports = MssqlMigrator;