feat: implement SQL dump import functionality with multi-statement support
This commit is contained in:
parent
41b444a190
commit
0a983d0654
34
controller/dev/DevManagementController.js
Normal file
34
controller/dev/DevManagementController.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const DevManagementService = require('../../services/dev/DevManagementService');
|
||||||
|
const { logger } = require('../../middleware/logger');
|
||||||
|
|
||||||
|
function previewSql(sql, max = 180) {
|
||||||
|
if (!sql) return '';
|
||||||
|
const s = String(sql).replace(/\s+/g, ' ').trim();
|
||||||
|
return s.length > max ? `${s.slice(0, max)}…` : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.importSqlDump = async (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.file || !req.file.buffer) {
|
||||||
|
return res.status(400).json({ success: false, error: 'SQL dump file is required' });
|
||||||
|
}
|
||||||
|
const sql = req.file.buffer.toString('utf8');
|
||||||
|
if (!sql.trim()) {
|
||||||
|
return res.status(400).json({ success: false, error: 'SQL dump file is empty' });
|
||||||
|
}
|
||||||
|
const start = Date.now();
|
||||||
|
const { rows, fields } = await DevManagementService.executeDump(sql);
|
||||||
|
const durationMs = Date.now() - start;
|
||||||
|
|
||||||
|
const isMulti = Array.isArray(fields) && fields.length > 0 && Array.isArray(fields[0]);
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
success: true,
|
||||||
|
data: { result: rows, isMulti: !!isMulti },
|
||||||
|
meta: { durationMs }
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('[DevManagementController.importSqlDump] error', { msg: e?.message, sql: previewSql(req.file?.buffer?.toString('utf8')) });
|
||||||
|
return res.status(500).json({ success: false, error: e?.message || 'SQL execution failed' });
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -99,5 +99,12 @@ module.exports = {
|
|||||||
// Get a connection from the pool
|
// Get a connection from the pool
|
||||||
async getConnection() {
|
async getConnection() {
|
||||||
return await pool.getConnection();
|
return await pool.getConnection();
|
||||||
|
},
|
||||||
|
// Get a dedicated connection that allows multiple statements (for SQL dumps)
|
||||||
|
async getMultiStatementConnection() {
|
||||||
|
return await mysql.createConnection({
|
||||||
|
...dbConfig,
|
||||||
|
multipleStatements: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -28,6 +28,7 @@ const AffiliateController = require('../controller/affiliate/AffiliateController
|
|||||||
const AbonemmentController = require('../controller/abonemments/AbonemmentController');
|
const AbonemmentController = require('../controller/abonemments/AbonemmentController');
|
||||||
const NewsController = require('../controller/news/NewsController');
|
const NewsController = require('../controller/news/NewsController');
|
||||||
const InvoiceController = require('../controller/invoice/InvoiceController'); // NEW
|
const InvoiceController = require('../controller/invoice/InvoiceController'); // NEW
|
||||||
|
const DevManagementController = require('../controller/dev/DevManagementController');
|
||||||
|
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
const upload = multer({ storage: multer.memoryStorage() });
|
const upload = multer({ storage: multer.memoryStorage() });
|
||||||
@ -113,6 +114,7 @@ function adminOnly(req, res, next) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NEW: ensure service sees a "company" user_type for admin users
|
// NEW: ensure service sees a "company" user_type for admin users
|
||||||
function forceCompanyForAdmin(req, res, next) {
|
function forceCompanyForAdmin(req, res, next) {
|
||||||
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
||||||
@ -161,6 +163,9 @@ router.post('/admin/affiliates', authMiddleware, adminOnly, upload.single('logo'
|
|||||||
// NEW: Admin create news with image upload
|
// NEW: Admin create news with image upload
|
||||||
router.post('/admin/news', authMiddleware, adminOnly, upload.single('image'), NewsController.create);
|
router.post('/admin/news', authMiddleware, adminOnly, upload.single('image'), NewsController.create);
|
||||||
|
|
||||||
|
// NEW: Dev Management SQL dump import (admin + super_admin)
|
||||||
|
router.post('/admin/dev/sql', authMiddleware, adminOnly, upload.single('file'), DevManagementController.importSqlDump);
|
||||||
|
|
||||||
// Abonement POSTs
|
// Abonement POSTs
|
||||||
router.post('/abonements/subscribe', authMiddleware, AbonemmentController.subscribe);
|
router.post('/abonements/subscribe', authMiddleware, AbonemmentController.subscribe);
|
||||||
router.post('/abonements/:id/pause', authMiddleware, AbonemmentController.pause);
|
router.post('/abonements/:id/pause', authMiddleware, AbonemmentController.pause);
|
||||||
|
|||||||
15
services/dev/DevManagementService.js
Normal file
15
services/dev/DevManagementService.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const db = require('../../database/database');
|
||||||
|
|
||||||
|
async function executeDump(sql) {
|
||||||
|
const conn = await db.getMultiStatementConnection();
|
||||||
|
try {
|
||||||
|
const [rows, fields] = await conn.query(sql);
|
||||||
|
return { rows, fields };
|
||||||
|
} finally {
|
||||||
|
try { await conn.end(); } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
executeDump
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user