modified: backend/.env.example
new file: backend/src/controllers/sqlInterfaceController.ts new file: backend/src/routes/sqlInterface.ts modified: backend/src/server.ts modified: docker-compose.external-db.yml modified: frontend/src/App.tsx modified: frontend/src/components/Sidebar.tsx new file: frontend/src/pages/SqlInterface.tsx modified: frontend/src/services/api.ts
This commit is contained in:
@@ -15,4 +15,4 @@ JWT_EXPIRES_IN=24h
|
||||
|
||||
# API Rate Limiting
|
||||
RATE_LIMIT_WINDOW_MS=900000
|
||||
RATE_LIMIT_MAX_REQUESTS=100
|
||||
RATE_LIMIT_MAX_REQUESTS=100
|
||||
|
||||
46
backend/src/controllers/sqlInterfaceController.ts
Normal file
46
backend/src/controllers/sqlInterfaceController.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { databasePoolManager } from '../services/DatabasePoolManager';
|
||||
|
||||
export const executeQuery = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { database_id, query } = req.body;
|
||||
|
||||
if (!database_id) {
|
||||
return res.status(400).json({ error: 'Database ID is required' });
|
||||
}
|
||||
|
||||
if (!query || typeof query !== 'string' || query.trim() === '') {
|
||||
return res.status(400).json({ error: 'Query is required' });
|
||||
}
|
||||
|
||||
const pool = databasePoolManager.getPool(database_id);
|
||||
if (!pool) {
|
||||
return res.status(404).json({ error: 'Database not found or not active' });
|
||||
}
|
||||
|
||||
const startTime = Date.now();
|
||||
const result = await pool.query(query);
|
||||
const executionTime = Date.now() - startTime;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
fields: result.fields?.map(f => ({
|
||||
name: f.name,
|
||||
dataTypeID: f.dataTypeID,
|
||||
})),
|
||||
executionTime,
|
||||
command: result.command,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('SQL execution error:', error);
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: error.message || 'Query execution failed',
|
||||
position: error.position,
|
||||
detail: error.detail,
|
||||
hint: error.hint,
|
||||
});
|
||||
}
|
||||
};
|
||||
11
backend/src/routes/sqlInterface.ts
Normal file
11
backend/src/routes/sqlInterface.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import express from 'express';
|
||||
import { authMiddleware } from '../middleware/auth';
|
||||
import { executeQuery } from '../controllers/sqlInterfaceController';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use(authMiddleware);
|
||||
|
||||
router.post('/execute', executeQuery);
|
||||
|
||||
export default router;
|
||||
@@ -18,6 +18,7 @@ import databaseRoutes from './routes/databases';
|
||||
import databaseManagementRoutes from './routes/databaseManagement';
|
||||
import userRoutes from './routes/users';
|
||||
import logsRoutes from './routes/logs';
|
||||
import sqlInterfaceRoutes from './routes/sqlInterface';
|
||||
import dynamicRoutes from './routes/dynamic';
|
||||
|
||||
const app: Express = express();
|
||||
@@ -87,6 +88,7 @@ app.use('/api/databases', databaseRoutes);
|
||||
app.use('/api/db-management', databaseManagementRoutes);
|
||||
app.use('/api/users', userRoutes);
|
||||
app.use('/api/logs', logsRoutes);
|
||||
app.use('/api/sql', sqlInterfaceRoutes);
|
||||
|
||||
// Dynamic API routes (user-created endpoints)
|
||||
app.use('/api/v1', dynamicRoutes);
|
||||
|
||||
Reference in New Issue
Block a user