| | const fs = require('fs'); |
| | const path = require('path'); |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | const sqlitePatterns = [ |
| | /AUTOINCREMENT/i, |
| | /DATETIME/i, |
| | /INTEGER\s+NOT\s+NULL\s+PRIMARY\s+KEY\s+AUTOINCREMENT/i |
| | ]; |
| |
|
| | |
| | |
| | |
| | function verifySqlFile(filePath) { |
| | try { |
| | const sqlContent = fs.readFileSync(filePath, 'utf8'); |
| | const issues = []; |
| |
|
| | |
| | sqlitePatterns.forEach(pattern => { |
| | if (pattern.test(sqlContent)) { |
| | issues.push(`发现 SQLite 语法: ${pattern.source}`); |
| | } |
| | }); |
| |
|
| | |
| | if (!sqlContent.includes('SERIAL PRIMARY KEY') && sqlContent.includes('CREATE TABLE')) { |
| | |
| | const hasSerial = /\bSERIAL\b/.test(sqlContent); |
| | const hasPrimaryKey = /\bPRIMARY\s+KEY\b/.test(sqlContent); |
| |
|
| | if (!hasSerial && !hasPrimaryKey) { |
| | issues.push('缺少 SERIAL 或 PRIMARY KEY 定义'); |
| | } |
| | } |
| |
|
| | return { |
| | file: path.basename(filePath), |
| | issues: issues, |
| | isValid: issues.length === 0 |
| | }; |
| | } catch (error) { |
| | return { |
| | file: path.basename(filePath), |
| | issues: [`读取文件失败: ${error.message}`], |
| | isValid: false |
| | }; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function verifyMigrationsDirectory(migrationsDir) { |
| | const items = fs.readdirSync(migrationsDir); |
| | const results = []; |
| |
|
| | items.forEach(item => { |
| | const itemPath = path.join(migrationsDir, item); |
| | const stat = fs.statSync(itemPath); |
| |
|
| | if (stat.isDirectory() && item !== 'migration_lock.toml') { |
| | |
| | const subResults = verifyMigrationsDirectory(itemPath); |
| | results.push(...subResults); |
| | } else if (item === 'migration.sql') { |
| | |
| | results.push(verifySqlFile(itemPath)); |
| | } |
| | }); |
| |
|
| | return results; |
| | } |
| |
|
| | |
| | |
| | |
| | function generateReport(results) { |
| | const validFiles = results.filter(r => r.isValid); |
| | const invalidFiles = results.filter(r => !r.isValid); |
| |
|
| | console.log('=== PostgreSQL 转换验证报告 ===\n'); |
| |
|
| | console.log(`总文件数: ${results.length}`); |
| | console.log(`有效文件: ${validFiles.length}`); |
| | console.log(`有问题的文件: ${invalidFiles.length}\n`); |
| |
|
| | if (invalidFiles.length > 0) { |
| | console.log('=== 有问题的文件 ==='); |
| | invalidFiles.forEach(result => { |
| | console.log(`\n📄 ${result.file}:`); |
| | result.issues.forEach(issue => { |
| | console.log(` ❌ ${issue}`); |
| | }); |
| | }); |
| | } |
| |
|
| | console.log('\n=== 有效文件 ==='); |
| | validFiles.forEach(result => { |
| | console.log(` ✅ ${result.file}`); |
| | }); |
| |
|
| | return { |
| | total: results.length, |
| | valid: validFiles.length, |
| | invalid: invalidFiles.length |
| | }; |
| | } |
| |
|
| | |
| | |
| | |
| | function main() { |
| | const migrationsDir = path.join(__dirname, 'migrations'); |
| |
|
| | console.log('开始验证 PostgreSQL 转换...\n'); |
| |
|
| | const results = verifyMigrationsDirectory(migrationsDir); |
| | const report = generateReport(results); |
| |
|
| | if (report.invalid === 0) { |
| | console.log('\n🎉 所有文件都已正确转换为 PostgreSQL 语法!'); |
| | } else { |
| | console.log(`\n⚠️ 发现 ${report.invalid} 个文件需要手动检查。`); |
| | } |
| |
|
| | return report; |
| | } |
| |
|
| | |
| | if (require.main === module) { |
| | main(); |
| | } |
| |
|
| | module.exports = { verifySqlFile, verifyMigrationsDirectory, generateReport }; |
| |
|