Files
uldp-degree-mangement-system/utils/migrationHelper.js
r2xrzh9q2z-lab d1b931d547 first commit
2026-02-02 11:07:09 +07:00

169 lines
4.7 KiB
JavaScript

const Migration = require('../models/migration');
/**
* Kiểm tra xem migration đã chạy chưa
* @param {string} migrationName - Tên của migration
* @returns {Promise<boolean>} - true nếu đã chạy, false nếu chưa
*/
async function hasRun(migrationName) {
try {
const migration = await Migration.findOne({ name: migrationName });
return !!migration;
} catch (error) {
console.error(`Error checking migration ${migrationName}:`, error);
throw error;
}
}
/**
* Đánh dấu migration đã chạy
* @param {string} migrationName - Tên của migration
* @param {number} batch - Số batch (mặc định là batch hiện tại + 1)
* @returns {Promise<Object>} - Migration document đã tạo
*/
async function markAsRun(migrationName, batch = null) {
try {
// Nếu không có batch, lấy batch cao nhất + 1
if (batch === null) {
const lastBatch = await Migration.findOne().sort({ batch: -1 });
batch = lastBatch ? lastBatch.batch + 1 : 1;
}
const migration = await Migration.create({
name: migrationName,
batch: batch,
ranAt: new Date()
});
return migration;
} catch (error) {
// Nếu migration đã tồn tại (unique constraint), trả về migration hiện có
if (error.code === 11000) {
return await Migration.findOne({ name: migrationName });
}
console.error(`Error marking migration ${migrationName} as run:`, error);
throw error;
}
}
/**
* Lấy danh sách tất cả các migration đã chạy
* @returns {Promise<Array>} - Danh sách các migration đã chạy
*/
async function getRanMigrations() {
try {
const migrations = await Migration.find().sort({ batch: 1, ranAt: 1 });
return migrations;
} catch (error) {
console.error('Error getting ran migrations:', error);
throw error;
}
}
/**
* Lấy danh sách các migration đã chạy theo batch
* @param {number} batch - Số batch
* @returns {Promise<Array>} - Danh sách các migration trong batch
*/
async function getMigrationsByBatch(batch) {
try {
const migrations = await Migration.find({ batch }).sort({ ranAt: 1 });
return migrations;
} catch (error) {
console.error(`Error getting migrations for batch ${batch}:`, error);
throw error;
}
}
/**
* Xóa migration khỏi bảng tracking (rollback)
* @param {string} migrationName - Tên của migration
* @returns {Promise<boolean>} - true nếu xóa thành công
*/
async function rollback(migrationName) {
try {
const result = await Migration.deleteOne({ name: migrationName });
return result.deletedCount > 0;
} catch (error) {
console.error(`Error rolling back migration ${migrationName}:`, error);
throw error;
}
}
/**
* Xóa tất cả migration trong một batch (rollback batch)
* @param {number} batch - Số batch cần rollback
* @returns {Promise<number>} - Số lượng migration đã xóa
*/
async function rollbackBatch(batch) {
try {
const result = await Migration.deleteMany({ batch });
return result.deletedCount;
} catch (error) {
console.error(`Error rolling back batch ${batch}:`, error);
throw error;
}
}
/**
* Lấy batch số cao nhất
* @returns {Promise<number>} - Batch số cao nhất
*/
async function getLastBatch() {
try {
const lastBatch = await Migration.findOne().sort({ batch: -1 });
return lastBatch ? lastBatch.batch : 0;
} catch (error) {
console.error('Error getting last batch:', error);
throw error;
}
}
/**
* Chạy migration với tracking tự động
* @param {string} migrationName - Tên của migration
* @param {Function} migrationFunction - Hàm migration cần chạy
* @returns {Promise<Object>} - Kết quả migration
*/
async function runMigration(migrationName, migrationFunction) {
try {
// Kiểm tra xem đã chạy chưa
if (await hasRun(migrationName)) {
console.log(`⏭️ Migration ${migrationName} đã chạy, bỏ qua...`);
return { skipped: true, name: migrationName };
}
console.log(`🔄 Đang chạy migration: ${migrationName}...`);
// Chạy migration function
await migrationFunction();
// Đánh dấu đã chạy
const migration = await markAsRun(migrationName);
console.log(`✅ Migration ${migrationName} đã chạy thành công! (Batch: ${migration.batch})`);
return {
success: true,
name: migrationName,
batch: migration.batch,
ranAt: migration.ranAt
};
} catch (error) {
console.error(`❌ Lỗi khi chạy migration ${migrationName}:`, error);
throw error;
}
}
module.exports = {
hasRun,
markAsRun,
getRanMigrations,
getMigrationsByBatch,
rollback,
rollbackBatch,
getLastBatch,
runMigration
};