import { ipcMain } from 'electron' import { MySqlService } from '../services/database/mysql' import { SqlServerService } from '../services/database/sql-server' import { createLogger } from '../services/logger' import { DatabaseQueryError, ValidationError } from '../types/errors' import type { MySqlConfig, MySqlQueryResult, SqlServerConfig, SqlServerQueryResult } from '../types/ipc-api.types' const log = createLogger('DatabaseHandler') // Store MySQL service instances per window/connection const mysqlServices = new Map() // Store SQL Server service instances per window/connection const sqlServerServices = new Map() /** * Get or create MySQL service for a connection ID */ function getMySqlService(connectionId: string): MySqlService | undefined { return mysqlServices.get(connectionId) } /** * Set MySQL service for a connection ID */ function setMySqlService(connectionId: string, service: MySqlService): void { mysqlServices.set(connectionId, service) } /** * Delete MySQL service for a connection ID */ function deleteMySqlService(connectionId: string): void { mysqlServices.delete(connectionId) } /** * Get or create SQL Server service for a connection ID */ function getSqlServerService(connectionId: string): SqlServerService | undefined { return sqlServerServices.get(connectionId) } /** * Set SQL Server service for a connection ID */ function setSqlServerService(connectionId: string, service: SqlServerService): void { sqlServerServices.set(connectionId, service) } /** * Delete SQL Server service for a connection ID */ function deleteSqlServerService(connectionId: string): void { sqlServerServices.delete(connectionId) } /** * Register IPC handlers for database operations */ export function registerDatabaseHandlers(): void { // Connect to MySQL ipcMain.handle('database:mysql:connect', async (event, config: MySqlConfig): Promise => { try { // Use window ID as connection identifier const windowId = (event.sender as { id: number }).id.toString() log.info('Connecting to MySQL', { windowId }) const service = new MySqlService(config) await service.connect() setMySqlService(windowId, service) log.info('MySQL connected', { windowId }) } catch (error) { const message = error instanceof Error ? error.message : 'Failed to connect to MySQL' log.error('MySQL connection failed', { error: message }) throw new DatabaseQueryError( message, 'DB_CONNECTION_FAILED', error instanceof Error ? error : undefined ) } }) // Disconnect from MySQL ipcMain.handle('database:mysql:disconnect', async (event): Promise => { try { const windowId = (event.sender as { id: number }).id.toString() const service = getMySqlService(windowId) if (service) { await service.disconnect() deleteMySqlService(windowId) log.info('MySQL disconnected', { windowId }) } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to disconnect from MySQL' log.error('MySQL disconnect failed', { error: message }) throw new DatabaseQueryError( message, 'DB_CONNECTION_FAILED', error instanceof Error ? error : undefined ) } }) // Check if MySQL is connected ipcMain.handle('database:mysql:isConnected', async (event): Promise => { const windowId = (event.sender as { id: number }).id.toString() const service = getMySqlService(windowId) return service ? service.isConnected() : false }) // Execute MySQL query ipcMain.handle( 'database:mysql:query', async (event, sql: string, params?: unknown[]): Promise => { try { const windowId = (event.sender as { id: number }).id.toString() const service = getMySqlService(windowId) if (!service) { throw new ValidationError( 'Not connected to MySQL. Call connect() first.', 'VAL_INVALID_INPUT' ) } log.debug('Executing MySQL query', { windowId, sql: sql.substring(0, 100) }) return await service.query(sql, params) } catch (error) { const message = error instanceof Error ? error.message : 'MySQL query failed' log.error('MySQL query failed', { error: message }) throw new DatabaseQueryError( message, 'DB_QUERY_FAILED', error instanceof Error ? error : undefined ) } } ) // Connect to SQL Server ipcMain.handle( 'database:sqlserver:connect', async (event, config: SqlServerConfig): Promise => { try { const windowId = (event.sender as { id: number }).id.toString() log.info('Connecting to SQL Server', { windowId }) const service = new SqlServerService(config) await service.connect() setSqlServerService(windowId, service) log.info('SQL Server connected', { windowId }) } catch (error) { const message = error instanceof Error ? error.message : 'Failed to connect to SQL Server' log.error('SQL Server connection failed', { error: message }) throw new DatabaseQueryError( message, 'DB_CONNECTION_FAILED', error instanceof Error ? error : undefined ) } } ) // Disconnect from SQL Server ipcMain.handle('database:sqlserver:disconnect', async (event): Promise => { try { const windowId = (event.sender as { id: number }).id.toString() const service = getSqlServerService(windowId) if (service) { await service.disconnect() deleteSqlServerService(windowId) log.info('SQL Server disconnected', { windowId }) } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to disconnect from SQL Server' log.error('SQL Server disconnect failed', { error: message }) throw new DatabaseQueryError( message, 'DB_CONNECTION_FAILED', error instanceof Error ? error : undefined ) } }) // Check if SQL Server is connected ipcMain.handle('database:sqlserver:isConnected', async (event): Promise => { const windowId = (event.sender as { id: number }).id.toString() const service = getSqlServerService(windowId) return service ? service.isConnected() : false }) // Execute SQL Server query ipcMain.handle( 'database:sqlserver:query', async ( event, sqlString: string, params?: Record ): Promise => { try { const windowId = (event.sender as { id: number }).id.toString() const service = getSqlServerService(windowId) if (!service) { throw new ValidationError( 'Not connected to SQL Server. Call connect() first.', 'VAL_INVALID_INPUT' ) } log.debug('Executing SQL Server query', { windowId, sql: sqlString.substring(0, 100) }) return await service.query(sqlString, params) } catch (error) { const message = error instanceof Error ? error.message : 'SQL Server query failed' log.error('SQL Server query failed', { error: message }) throw new DatabaseQueryError( message, 'DB_QUERY_FAILED', error instanceof Error ? error : undefined ) } } ) }