plugin-postgresql-connector
Version:
NocoBase plugin for connecting to external PostgreSQL databases
247 lines • 8.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useQuery = void 0;
const react_1 = require("react");
const client_1 = require("@nocobase/client");
const antd_1 = require("antd");
const useQuery = (connectionId) => {
const [queryResult, setQueryResult] = (0, react_1.useState)(null);
const [savedQueries, setSavedQueries] = (0, react_1.useState)([]);
const [queryHistory, setQueryHistory] = (0, react_1.useState)([]);
const [executionError, setExecutionError] = (0, react_1.useState)(null);
// Execute SQL query
const { run: executeQuery, loading: executingQuery } = (0, client_1.useRequest)((data) => ({
url: '/postgresql-query/execute',
method: 'POST',
data,
}), {
manual: true,
onSuccess: (data) => {
setQueryResult(data.data);
setExecutionError(null);
addToHistory(data.data.query);
antd_1.message.success(`Query thực thi thành công! (${data.data.executionTime}ms)`);
},
onError: (error) => {
setExecutionError(error.message);
setQueryResult(null);
antd_1.message.error(`Query thất bại: ${error.message}`);
},
});
// Execute stored procedure
const { run: executeProcedure, loading: executingProcedure } = (0, client_1.useRequest)((data) => ({
url: '/postgresql-query/executeProcedure',
method: 'POST',
data,
}), {
manual: true,
onSuccess: (data) => {
setQueryResult(data.data);
setExecutionError(null);
antd_1.message.success(`Procedure thực thi thành công! (${data.data.executionTime}ms)`);
},
onError: (error) => {
setExecutionError(error.message);
antd_1.message.error(`Procedure thất bại: ${error.message}`);
},
});
// Execute function
const { run: executeFunction, loading: executingFunction } = (0, client_1.useRequest)((data) => ({
url: '/postgresql-query/executeFunction',
method: 'POST',
data,
}), {
manual: true,
onSuccess: (data) => {
setQueryResult(data.data);
setExecutionError(null);
antd_1.message.success(`Function thực thi thành công! (${data.data.executionTime}ms)`);
},
onError: (error) => {
setExecutionError(error.message);
antd_1.message.error(`Function thất bại: ${error.message}`);
},
});
// Get table data
const { run: getTableData, loading: loadingTableData } = (0, client_1.useRequest)((data) => ({
url: '/postgresql-query/getTableData',
method: 'GET',
params: data,
}), {
manual: true,
onSuccess: (data) => {
setQueryResult(data.data);
setExecutionError(null);
},
onError: (error) => {
setExecutionError(error.message);
antd_1.message.error(`Không thể tải dữ liệu table: ${error.message}`);
},
});
// Save query
const { run: saveQuery, loading: savingQuery } = (0, client_1.useRequest)((data) => ({
url: '/postgresql-saved-queries',
method: 'POST',
data,
}), {
manual: true,
onSuccess: () => {
antd_1.message.success('Query đã được lưu thành công!');
if (connectionId) {
fetchSavedQueries(connectionId);
}
},
onError: (error) => {
antd_1.message.error(`Lưu query thất bại: ${error.message}`);
},
});
// Fetch saved queries
const { run: fetchSavedQueries, loading: loadingSavedQueries } = (0, client_1.useRequest)((connId) => ({
url: '/postgresql-saved-queries',
params: { connectionId: connId },
}), {
manual: true,
onSuccess: (data) => {
setSavedQueries(data.data || []);
},
onError: (error) => {
antd_1.message.error(`Không thể tải saved queries: ${error.message}`);
},
});
// Delete saved query
const { run: deleteSavedQuery, loading: deletingQuery } = (0, client_1.useRequest)((queryId) => ({
url: `/postgresql-saved-queries/${queryId}`,
method: 'DELETE',
}), {
manual: true,
onSuccess: () => {
antd_1.message.success('Query đã được xóa!');
if (connectionId) {
fetchSavedQueries(connectionId);
}
},
onError: (error) => {
antd_1.message.error(`Xóa query thất bại: ${error.message}`);
},
});
// Utility functions
const addToHistory = (0, react_1.useCallback)((query) => {
setQueryHistory(prev => {
const newHistory = [query, ...prev.filter(q => q !== query)];
return newHistory.slice(0, 50); // Keep last 50 queries
});
}, []);
const clearHistory = (0, react_1.useCallback)(() => {
setQueryHistory([]);
}, []);
const detectQueryType = (0, react_1.useCallback)((query) => {
const upperQuery = query.toUpperCase().trim();
if (upperQuery.startsWith('SELECT'))
return 'SELECT';
if (upperQuery.startsWith('INSERT'))
return 'INSERT';
if (upperQuery.startsWith('UPDATE'))
return 'UPDATE';
if (upperQuery.startsWith('DELETE'))
return 'DELETE';
if (upperQuery.includes('CALL '))
return 'PROCEDURE';
if (upperQuery.includes('SELECT ') && upperQuery.includes('('))
return 'FUNCTION';
return 'SELECT';
}, []);
const formatQuery = (0, react_1.useCallback)((query) => {
// Basic SQL formatting
return query
.replace(/\s+/g, ' ')
.replace(/,\s*/g, ',\n ')
.replace(/\bFROM\b/gi, '\nFROM')
.replace(/\bWHERE\b/gi, '\nWHERE')
.replace(/\bJOIN\b/gi, '\nJOIN')
.replace(/\bORDER BY\b/gi, '\nORDER BY')
.replace(/\bGROUP BY\b/gi, '\nGROUP BY')
.replace(/\bHAVING\b/gi, '\nHAVING')
.trim();
}, []);
const validateQuery = (0, react_1.useCallback)((query) => {
const errors = [];
if (!query.trim()) {
errors.push('Query không được để trống');
return errors;
}
// Check for dangerous queries
const upperQuery = query.toUpperCase();
const dangerousKeywords = ['DROP', 'TRUNCATE', 'ALTER', 'CREATE'];
dangerousKeywords.forEach(keyword => {
if (upperQuery.includes(keyword)) {
errors.push(`Query chứa từ khóa nguy hiểm: ${keyword}`);
}
});
// Check for basic SQL syntax
if (!upperQuery.match(/\b(SELECT|INSERT|UPDATE|DELETE|CALL)\b/)) {
errors.push('Query không hợp lệ - thiếu keyword chính');
}
return errors;
}, []);
const exportQueryResult = (0, react_1.useCallback)((format) => {
if (!queryResult?.rows?.length) {
antd_1.message.warning('Không có dữ liệu để export');
return;
}
// This would integrate with export utilities
antd_1.message.info(`Export ${format.toUpperCase()} feature coming soon`);
}, [queryResult]);
const getQueryStats = (0, react_1.useCallback)(() => {
if (!queryResult)
return null;
return {
rowCount: queryResult.rowCount,
columnCount: queryResult.fields?.length || 0,
executionTime: queryResult.executionTime,
dataSize: JSON.stringify(queryResult.rows).length,
};
}, [queryResult]);
// Auto-fetch saved queries when connectionId changes
(0, react_1.useEffect)(() => {
if (connectionId) {
fetchSavedQueries(connectionId);
}
}, [connectionId, fetchSavedQueries]);
return {
// State
queryResult,
savedQueries,
queryHistory,
executionError,
// Loading states
executingQuery,
executingProcedure,
executingFunction,
loadingTableData,
savingQuery,
loadingSavedQueries,
deletingQuery,
// Actions
executeQuery,
executeProcedure,
executeFunction,
getTableData,
saveQuery,
fetchSavedQueries,
deleteSavedQuery,
// Utilities
addToHistory,
clearHistory,
detectQueryType,
formatQuery,
validateQuery,
exportQueryResult,
getQueryStats,
// State setters
setQueryResult,
setExecutionError,
};
};
exports.useQuery = useQuery;
exports.default = exports.useQuery;
//# sourceMappingURL=useQuery.js.map