UNPKG

plugin-postgresql-connector

Version:

NocoBase plugin for connecting to external PostgreSQL databases

240 lines (208 loc) 6.64 kB
import { useState, useCallback, useEffect } from 'react'; import { useRequest } from '@nocobase/client'; import { message } from 'antd'; export interface ConnectionConfig { name: string; host: string; port: number; database: string; username: string; password: string; ssl: boolean; } export interface Connection extends ConnectionConfig { id: string; isActive: boolean; createdAt?: string; updatedAt?: string; } export const useConnection = () => { const [selectedConnection, setSelectedConnection] = useState<string>(''); const [connections, setConnections] = useState<Connection[]>([]); // Fetch all connections const { data: connectionsData, loading: loadingConnections, run: refreshConnections, } = useRequest({ url: '/postgresql-connections', }); // Test connection const { run: testConnection, loading: testingConnection } = useRequest( (config: ConnectionConfig) => ({ url: '/postgresql-connections/test', method: 'POST', data: config, }), { manual: true, onSuccess: () => { message.success('Kết nối thành công!'); }, onError: (error) => { message.error(`Kết nối thất bại: ${error.message}`); throw error; }, } ); // Create new connection const { run: createConnection, loading: creatingConnection } = useRequest( (config: ConnectionConfig) => ({ url: '/postgresql-connections', method: 'POST', data: config, }), { manual: true, onSuccess: (data) => { message.success('Tạo kết nối thành công!'); refreshConnections(); return data; }, onError: (error) => { message.error(`Tạo kết nối thất bại: ${error.message}`); throw error; }, } ); // Update connection const { run: updateConnection, loading: updatingConnection } = useRequest( ({ id, config }: { id: string; config: ConnectionConfig }) => ({ url: `/postgresql-connections/${id}`, method: 'PUT', data: config, }), { manual: true, onSuccess: (data) => { message.success('Cập nhật kết nối thành công!'); refreshConnections(); return data; }, onError: (error) => { message.error(`Cập nhật kết nối thất bại: ${error.message}`); throw error; }, } ); // Delete connection const { run: deleteConnection, loading: deletingConnection } = useRequest( (id: string) => ({ url: `/postgresql-connections/${id}`, method: 'DELETE', }), { manual: true, onSuccess: () => { message.success('Xóa kết nối thành công!'); if (selectedConnection === id) { setSelectedConnection(''); } refreshConnections(); }, onError: (error) => { message.error(`Xóa kết nối thất bại: ${error.message}`); throw error; }, } ); // Get connection by ID const getConnectionById = useCallback((id: string): Connection | undefined => { return connections.find(conn => conn.id === id); }, [connections]); // Get active connections const getActiveConnections = useCallback((): Connection[] => { return connections.filter(conn => conn.isActive); }, [connections]); // Check if connection exists const connectionExists = useCallback((name: string): boolean => { return connections.some(conn => conn.name === name && conn.isActive); }, [connections]); // Validate connection config const validateConnectionConfig = useCallback((config: Partial<ConnectionConfig>): string[] => { const errors: string[] = []; if (!config.name?.trim()) { errors.push('Tên kết nối không được để trống'); } else if (config.name.length < 3) { errors.push('Tên kết nối phải có ít nhất 3 ký tự'); } if (!config.host?.trim()) { errors.push('Host không được để trống'); } if (!config.port || config.port < 1 || config.port > 65535) { errors.push('Port phải từ 1 đến 65535'); } if (!config.database?.trim()) { errors.push('Tên database không được để trống'); } if (!config.username?.trim()) { errors.push('Username không được để trống'); } if (!config.password?.trim()) { errors.push('Password không được để trống'); } return errors; }, []); // Test and create connection const testAndCreateConnection = useCallback(async (config: ConnectionConfig) => { try { // First test the connection await testConnection(config); // If test successful, create the connection const result = await createConnection(config); return result; } catch (error) { throw error; } }, [testConnection, createConnection]); // Test and update connection const testAndUpdateConnection = useCallback(async (id: string, config: ConnectionConfig) => { try { // First test the connection await testConnection(config); // If test successful, update the connection const result = await updateConnection({ id, config }); return result; } catch (error) { throw error; } }, [testConnection, updateConnection]); // Update connections list when data changes useEffect(() => { if (connectionsData?.data) { setConnections(connectionsData.data); } }, [connectionsData]); // Auto-select first connection if none selected useEffect(() => { if (!selectedConnection && connections.length > 0) { setSelectedConnection(connections[0].id); } }, [connections, selectedConnection]); return { // State connections, selectedConnection, setSelectedConnection, // Loading states loadingConnections, testingConnection, creatingConnection, updatingConnection, deletingConnection, // Actions refreshConnections, testConnection, createConnection, updateConnection, deleteConnection, testAndCreateConnection, testAndUpdateConnection, // Utilities getConnectionById, getActiveConnections, connectionExists, validateConnectionConfig, }; }; export default useConnection;