#!/usr/bin/env node // ===================================================== // 觸發器遷移腳本 // ===================================================== const mysql = require('mysql2/promise'); const fs = require('fs'); const path = require('path'); // 資料庫配置 const dbConfig = { host: process.env.DB_HOST || 'mysql.theaken.com', port: parseInt(process.env.DB_PORT || '33306'), user: process.env.DB_USER || 'AI_Platform', password: process.env.DB_PASSWORD || 'Aa123456', database: process.env.DB_NAME || 'db_AI_Platform', charset: 'utf8mb4', timezone: '+08:00', acquireTimeout: 60000, timeout: 60000, reconnect: true, connectionLimit: 10, queueLimit: 0, }; async function migrateTriggers() { let connection; try { console.log('🚀 開始觸發器遷移...'); // 創建連接 connection = await mysql.createConnection({ ...dbConfig, multipleStatements: true }); console.log('✅ 資料庫連接成功'); // 觸發器 SQL const triggers = [ { name: 'calculate_app_total_score', sql: `CREATE TRIGGER calculate_app_total_score BEFORE INSERT ON app_judge_scores FOR EACH ROW BEGIN SET NEW.total_score = ( NEW.innovation_score + NEW.technical_score + NEW.usability_score + NEW.presentation_score + NEW.impact_score ) / 5.0; END` }, { name: 'calculate_app_total_score_update', sql: `CREATE TRIGGER calculate_app_total_score_update BEFORE UPDATE ON app_judge_scores FOR EACH ROW BEGIN SET NEW.total_score = ( NEW.innovation_score + NEW.technical_score + NEW.usability_score + NEW.presentation_score + NEW.impact_score ) / 5.0; END` }, { name: 'calculate_proposal_total_score', sql: `CREATE TRIGGER calculate_proposal_total_score BEFORE INSERT ON proposal_judge_scores FOR EACH ROW BEGIN SET NEW.total_score = ( NEW.problem_identification_score + NEW.solution_feasibility_score + NEW.innovation_score + NEW.impact_score + NEW.presentation_score ) / 5.0; END` }, { name: 'calculate_proposal_total_score_update', sql: `CREATE TRIGGER calculate_proposal_total_score_update BEFORE UPDATE ON proposal_judge_scores FOR EACH ROW BEGIN SET NEW.total_score = ( NEW.problem_identification_score + NEW.solution_feasibility_score + NEW.innovation_score + NEW.impact_score + NEW.presentation_score ) / 5.0; END` } ]; console.log('⚡ 執行觸發器 SQL...'); for (const trigger of triggers) { try { await connection.query(trigger.sql); console.log(`✅ 創建觸發器: ${trigger.name}`); } catch (error) { if (error.code === 'ER_TRG_ALREADY_EXISTS') { console.log(`⚠️ 觸發器已存在: ${trigger.name}`); } else { throw error; } } } console.log('✅ 觸發器創建成功!'); // 檢查觸發器 console.log('🔍 檢查觸發器...'); const [triggerList] = await connection.execute('SHOW TRIGGERS'); console.log(`⚙️ 共創建了 ${triggerList.length} 個觸發器:`); triggerList.forEach((trigger, index) => { console.log(` ${index + 1}. ${trigger.Trigger}`); }); console.log('🎉 觸發器遷移完成!'); } catch (error) { console.error('❌ 觸發器遷移失敗:', error.message); console.error('詳細錯誤:', error); process.exit(1); } finally { if (connection) { await connection.end(); console.log('🔌 資料庫連接已關閉'); } } } // 執行遷移 if (require.main === module) { migrateTriggers().catch(console.error); } module.exports = { migrateTriggers };