#!/usr/bin/env node /** * 数据库初始化脚本 * 用于验证数据库连接和创建基础表结构 */ const mysql = require('mysql2/promise'); const databaseConfig = require('../config/database'); const path = require('path'); const fs = require('fs'); class DatabaseInitializer { constructor() { this.connection = null; } /** * 创建数据库连接 */ async createConnection() { try { this.connection = await mysql.createConnection({ host: databaseConfig.host, port: databaseConfig.port, user: databaseConfig.username, password: databaseConfig.password, database: databaseConfig.database, charset: 'utf8mb4', timezone: '+08:00' }); console.log('✅ 数据库连接成功'); return true; } catch (error) { console.error('❌ 数据库连接失败:', error.message); return false; } } /** * 验证数据库连接 */ async validateConnection() { try { const [rows] = await this.connection.execute('SELECT NOW() as current_time, VERSION() as mysql_version'); console.log('📊 数据库信息:'); console.log(` 当前时间: ${rows[0].current_time}`); console.log(` MySQL版本: ${rows[0].mysql_version}`); return true; } catch (error) { console.error('❌ 数据库验证失败:', error.message); return false; } } /** * 检查表是否存在 * @param {string} tableName - 表名 */ async checkTableExists(tableName) { try { const [rows] = await this.connection.execute( `SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = ?`, [databaseConfig.database, tableName] ); return rows[0].count > 0; } catch (error) { console.error(`❌ 检查表 ${tableName} 存在失败:`, error.message); return false; } } /** * 执行SQL文件 * @param {string} filePath - SQL文件路径 */ async executeSqlFile(filePath) { try { const sqlContent = fs.readFileSync(filePath, 'utf8'); const statements = sqlContent.split(';').filter(stmt => stmt.trim()); for (const statement of statements) { if (statement.trim()) { await this.connection.execute(statement); } } console.log(`✅ 成功执行SQL文件: ${path.basename(filePath)}`); return true; } catch (error) { console.error(`❌ 执行SQL文件失败:`, error.message); return false; } } /** * 关闭数据库连接 */ async closeConnection() { if (this.connection) { await this.connection.end(); console.log('🔌 数据库连接已关闭'); } } /** * 主初始化方法 */ async initialize() { console.log('🚀 开始数据库初始化...'); console.log(`📋 环境: ${process.env.NODE_ENV || 'development'}`); console.log(`🗄️ 数据库: ${databaseConfig.database}`); console.log(`🌐 主机: ${databaseConfig.host}:${databaseConfig.port}`); console.log('─'.repeat(50)); // 创建连接 const connected = await this.createConnection(); if (!connected) { process.exit(1); } // 验证连接 const validated = await this.validateConnection(); if (!validated) { await this.closeConnection(); process.exit(1); } console.log('✅ 数据库连接验证通过'); console.log('─'.repeat(50)); // 检查并创建uploads表 const uploadsTableExists = await this.checkTableExists('uploads'); if (!uploadsTableExists) { console.log('📁 创建uploads表...'); await this.createUploadsTable(); } else { console.log('✅ uploads表已存在'); } console.log('📋 数据库初始化完成'); console.log('✅ 所有检查通过,数据库连接正常'); await this.closeConnection(); } /** * 创建uploads表 */ async createUploadsTable() { const createTableSQL = ` CREATE TABLE uploads ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT UNSIGNED NOT NULL, original_name VARCHAR(255) NOT NULL, stored_name VARCHAR(255) NOT NULL, file_path VARCHAR(500) NOT NULL, file_size BIGINT NOT NULL, mime_type VARCHAR(100) NOT NULL, file_type ENUM('image', 'document', 'other') DEFAULT 'image', upload_type VARCHAR(50) NOT NULL COMMENT '上传类型: avatar, product, identification, etc', status ENUM('active', 'deleted') DEFAULT 'active', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, INDEX idx_user_id (user_id), INDEX idx_upload_type (upload_type), INDEX idx_created_at (created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件上传记录表' `; try { await this.connection.execute(createTableSQL); console.log('✅ uploads表创建成功'); return true; } catch (error) { console.error('❌ 创建uploads表失败:', error.message); return false; } } } // 执行初始化 const initializer = new DatabaseInitializer(); // 处理命令行参数 const args = process.argv.slice(2); if (args.includes('--help') || args.includes('-h')) { console.log(` 使用方法: node scripts/initDatabase.js [选项] 选项: --help, -h 显示帮助信息 --check 只检查连接,不执行初始化 示例: node scripts/initDatabase.js # 完整初始化 node scripts/initDatabase.js --check # 只检查连接 `); process.exit(0); } initializer.initialize().catch(error => { console.error('❌ 初始化过程中发生错误:', error.message); process.exit(1); });