forked from UKSOURCE/cms.hailearning.edu.vn
first commit
This commit is contained in:
168
utils/migrationHelper.js
Normal file
168
utils/migrationHelper.js
Normal file
@@ -0,0 +1,168 @@
|
||||
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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user