modified: backend/src/services/DatabasePoolManager.ts
modified: backend/src/services/ScriptExecutor.ts modified: backend/src/types/index.ts modified: frontend/src/components/CodeEditor.tsx modified: frontend/src/components/EndpointModal.tsx deleted: frontend/src/pages/Databases.tsx modified: frontend/src/pages/Settings.tsx modified: frontend/src/types/index.ts
This commit is contained in:
@@ -80,6 +80,38 @@ class DatabasePoolManager {
|
||||
return this.pools.get(databaseId);
|
||||
}
|
||||
|
||||
async getDatabaseConfig(databaseId: string): Promise<DatabaseConfig | null> {
|
||||
try {
|
||||
const result = await mainPool.query(
|
||||
'SELECT * FROM databases WHERE id = $1',
|
||||
[databaseId]
|
||||
);
|
||||
if (result.rows.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const row = result.rows[0];
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
type: row.type,
|
||||
host: row.host,
|
||||
port: row.port,
|
||||
database_name: row.database_name,
|
||||
username: row.username,
|
||||
password: row.password,
|
||||
ssl: row.ssl,
|
||||
is_active: row.is_active,
|
||||
aql_base_url: row.aql_base_url,
|
||||
aql_auth_type: row.aql_auth_type,
|
||||
aql_auth_value: row.aql_auth_value,
|
||||
aql_headers: row.aql_headers,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching database config:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllDatabaseConfigs(): Promise<DatabaseConfig[]> {
|
||||
try {
|
||||
const result = await mainPool.query(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { spawn } from 'child_process';
|
||||
import { sqlExecutor } from './SqlExecutor';
|
||||
import { aqlExecutor } from './AqlExecutor';
|
||||
import { ScriptQuery, EndpointParameter } from '../types';
|
||||
import { databasePoolManager } from './DatabasePoolManager';
|
||||
|
||||
interface ScriptContext {
|
||||
databaseId: string;
|
||||
@@ -23,32 +25,60 @@ export class ScriptExecutor {
|
||||
}
|
||||
|
||||
const allParams = { ...context.requestParams, ...additionalParams };
|
||||
|
||||
let processedQuery = query.sql;
|
||||
const paramValues: any[] = [];
|
||||
const paramMatches = query.sql.match(/\$\w+/g) || [];
|
||||
const uniqueParams = [...new Set(paramMatches.map(p => p.substring(1)))];
|
||||
|
||||
uniqueParams.forEach((paramName, index) => {
|
||||
const regex = new RegExp(`\\$${paramName}\\b`, 'g');
|
||||
processedQuery = processedQuery.replace(regex, `$${index + 1}`);
|
||||
const value = allParams[paramName];
|
||||
paramValues.push(value !== undefined ? value : null);
|
||||
});
|
||||
|
||||
const dbId = (query as any).database_id || context.databaseId;
|
||||
|
||||
if (!dbId) {
|
||||
throw new Error(`Database ID not found for query '${queryName}'. Query database_id: ${(query as any).database_id}, Context databaseId: ${context.databaseId}. Please specify database_id in the Script Queries configuration for query '${queryName}'.`);
|
||||
}
|
||||
|
||||
const result = await sqlExecutor.executeQuery(dbId, processedQuery, paramValues);
|
||||
// Получаем конфигурацию базы данных для определения типа
|
||||
const dbConfig = await databasePoolManager.getDatabaseConfig(dbId);
|
||||
if (!dbConfig) {
|
||||
throw new Error(`Database configuration not found for ID: ${dbId}`);
|
||||
}
|
||||
|
||||
return {
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
};
|
||||
// Проверяем тип базы данных и выполняем соответствующий запрос
|
||||
if (dbConfig.type === 'aql') {
|
||||
// AQL запрос
|
||||
const result = await aqlExecutor.executeAqlQuery(dbId, {
|
||||
method: query.aql_method || 'GET',
|
||||
endpoint: query.aql_endpoint || '',
|
||||
body: query.aql_body || '',
|
||||
queryParams: query.aql_query_params || {},
|
||||
parameters: allParams,
|
||||
});
|
||||
|
||||
return {
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
};
|
||||
} else {
|
||||
// SQL запрос
|
||||
if (!query.sql) {
|
||||
throw new Error(`SQL query is required for database '${dbConfig.name}' (type: ${dbConfig.type})`);
|
||||
}
|
||||
|
||||
let processedQuery = query.sql;
|
||||
const paramValues: any[] = [];
|
||||
const paramMatches = query.sql.match(/\$\w+/g) || [];
|
||||
const uniqueParams = [...new Set(paramMatches.map(p => p.substring(1)))];
|
||||
|
||||
uniqueParams.forEach((paramName, index) => {
|
||||
const regex = new RegExp(`\\$${paramName}\\b`, 'g');
|
||||
processedQuery = processedQuery.replace(regex, `$${index + 1}`);
|
||||
const value = allParams[paramName];
|
||||
paramValues.push(value !== undefined ? value : null);
|
||||
});
|
||||
|
||||
const result = await sqlExecutor.executeQuery(dbId, processedQuery, paramValues);
|
||||
|
||||
return {
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Создаем асинхронную функцию из кода пользователя
|
||||
@@ -149,21 +179,6 @@ print(json.dumps(result))
|
||||
}
|
||||
|
||||
const allParams = { ...context.requestParams, ...request.additional_params };
|
||||
|
||||
// Преобразуем параметры
|
||||
let processedQuery = query.sql;
|
||||
const paramValues: any[] = [];
|
||||
const paramMatches = query.sql.match(/\$\w+/g) || [];
|
||||
const uniqueParams = [...new Set(paramMatches.map(p => p.substring(1)))];
|
||||
|
||||
uniqueParams.forEach((paramName, index) => {
|
||||
const regex = new RegExp(`\\$${paramName}\\b`, 'g');
|
||||
processedQuery = processedQuery.replace(regex, `$${index + 1}`);
|
||||
const value = allParams[paramName];
|
||||
paramValues.push(value !== undefined ? value : null);
|
||||
});
|
||||
|
||||
// Используем database_id из запроса, если указан, иначе из контекста
|
||||
const dbId = (query as any).database_id || context.databaseId;
|
||||
|
||||
if (!dbId) {
|
||||
@@ -173,17 +188,65 @@ print(json.dumps(result))
|
||||
continue;
|
||||
}
|
||||
|
||||
const result = await sqlExecutor.executeQuery(
|
||||
dbId,
|
||||
processedQuery,
|
||||
paramValues
|
||||
);
|
||||
// Получаем конфигурацию базы данных для определения типа
|
||||
const dbConfig = await databasePoolManager.getDatabaseConfig(dbId);
|
||||
if (!dbConfig) {
|
||||
python.stdin.write(JSON.stringify({
|
||||
error: `Database configuration not found for ID: ${dbId}`
|
||||
}) + '\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
python.stdin.write(JSON.stringify({
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
}) + '\n');
|
||||
// Проверяем тип базы данных и выполняем соответствующий запрос
|
||||
if (dbConfig.type === 'aql') {
|
||||
// AQL запрос
|
||||
const result = await aqlExecutor.executeAqlQuery(dbId, {
|
||||
method: query.aql_method || 'GET',
|
||||
endpoint: query.aql_endpoint || '',
|
||||
body: query.aql_body || '',
|
||||
queryParams: query.aql_query_params || {},
|
||||
parameters: allParams,
|
||||
});
|
||||
|
||||
python.stdin.write(JSON.stringify({
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
}) + '\n');
|
||||
} else {
|
||||
// SQL запрос
|
||||
if (!query.sql) {
|
||||
python.stdin.write(JSON.stringify({
|
||||
error: `SQL query is required for database '${dbConfig.name}' (type: ${dbConfig.type})`
|
||||
}) + '\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Преобразуем параметры
|
||||
let processedQuery = query.sql;
|
||||
const paramValues: any[] = [];
|
||||
const paramMatches = query.sql.match(/\$\w+/g) || [];
|
||||
const uniqueParams = [...new Set(paramMatches.map(p => p.substring(1)))];
|
||||
|
||||
uniqueParams.forEach((paramName, index) => {
|
||||
const regex = new RegExp(`\\$${paramName}\\b`, 'g');
|
||||
processedQuery = processedQuery.replace(regex, `$${index + 1}`);
|
||||
const value = allParams[paramName];
|
||||
paramValues.push(value !== undefined ? value : null);
|
||||
});
|
||||
|
||||
const result = await sqlExecutor.executeQuery(
|
||||
dbId,
|
||||
processedQuery,
|
||||
paramValues
|
||||
);
|
||||
|
||||
python.stdin.write(JSON.stringify({
|
||||
data: result.rows,
|
||||
rowCount: result.rowCount,
|
||||
executionTime: result.executionTime,
|
||||
}) + '\n');
|
||||
}
|
||||
} catch (error: any) {
|
||||
python.stdin.write(JSON.stringify({ error: error.message }) + '\n');
|
||||
}
|
||||
|
||||
@@ -86,8 +86,13 @@ export interface EndpointParameter {
|
||||
|
||||
export interface ScriptQuery {
|
||||
name: string;
|
||||
sql: string;
|
||||
sql?: string;
|
||||
database_id?: string;
|
||||
// AQL fields for script queries
|
||||
aql_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
||||
aql_endpoint?: string;
|
||||
aql_body?: string;
|
||||
aql_query_params?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface QueryResult {
|
||||
|
||||
Reference in New Issue
Block a user