// packages/backend/src/repositories/proxy.repository.ts import { Database, Statement } from 'sqlite3'; // Import new async helpers and the instance getter import { getDbInstance, runDb, getDb as getDbRow, allDb } from '../database/connection'; // Remove top-level db instance // const db = getDb(); // 定义 Proxy 类型 (可以共享到 types 文件) export interface ProxyData { id: number; name: string; type: 'SOCKS5' | 'HTTP'; host: string; port: number; username?: string | null; auth_method: 'none' | 'password' | 'key'; encrypted_password?: string | null; encrypted_private_key?: string | null; encrypted_passphrase?: string | null; created_at: number; updated_at: number; } // Define the expected row structure from the database if it matches ProxyData type DbProxyRow = ProxyData; /** * 根据名称、类型、主机和端口查找代理 */ export const findProxyByNameTypeHostPort = async (name: string, type: string, host: string, port: number): Promise<{ id: number } | undefined> => { const sql = `SELECT id FROM proxies WHERE name = ? AND type = ? AND host = ? AND port = ?`; try { const db = await getDbInstance(); const row = await getDbRow<{ id: number }>(db, sql, [name, type, host, port]); return row; } catch (err: any) { console.error(`Repository: 查找代理时出错 (name=${name}, type=${type}, host=${host}, port=${port}):`, err.message); throw new Error(`查找代理时出错: ${err.message}`); } }; /** * 创建新代理 */ export const createProxy = async (data: Omit): Promise => { const now = Math.floor(Date.now() / 1000); const sql = `INSERT INTO proxies (name, type, host, port, username, auth_method, encrypted_password, encrypted_private_key, encrypted_passphrase, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; const params = [ data.name, data.type, data.host, data.port, data.username || null, data.auth_method || 'none', data.encrypted_password || null, data.encrypted_private_key || null, data.encrypted_passphrase || null, now, now ]; try { const db = await getDbInstance(); const result = await runDb(db, sql, params); // Ensure lastID is valid before returning if (typeof result.lastID !== 'number' || result.lastID <= 0) { throw new Error('创建代理后未能获取有效的 lastID'); } return result.lastID; } catch (err: any) { console.error('Repository: 创建代理时出错:', err.message); // Handle potential UNIQUE constraint errors if needed (e.g., on name) throw new Error(`创建代理时出错: ${err.message}`); } }; /** * 获取所有代理 */ export const findAllProxies = async (): Promise => { const sql = `SELECT * FROM proxies ORDER BY name ASC`; try { const db = await getDbInstance(); const rows = await allDb(db, sql); return rows; } catch (err: any) { console.error('Repository: 查询代理列表时出错:', err.message); throw new Error('获取代理列表失败'); } }; /** * 根据 ID 获取单个代理 */ export const findProxyById = async (id: number): Promise => { const sql = `SELECT * FROM proxies WHERE id = ?`; try { const db = await getDbInstance(); const row = await getDbRow(db, sql, [id]); return row || null; } catch (err: any) { console.error(`Repository: 查询代理 ${id} 时出错:`, err.message); throw new Error('获取代理信息失败'); } }; /** * 更新代理信息 */ export const updateProxy = async (id: number, data: Partial>): Promise => { const fieldsToUpdate: { [key: string]: any } = { ...data }; const params: any[] = []; // Remove fields that should not be updated directly delete fieldsToUpdate.id; delete fieldsToUpdate.created_at; // updated_at will be set explicitly fieldsToUpdate.updated_at = Math.floor(Date.now() / 1000); const setClauses = Object.keys(fieldsToUpdate).map(key => `${key} = ?`).join(', '); Object.values(fieldsToUpdate).forEach(value => params.push(value ?? null)); if (!setClauses) { console.warn(`[Repository] updateProxy called for ID ${id} with no fields to update.`); return false; // Nothing to update } params.push(id); // Add the ID for the WHERE clause const sql = `UPDATE proxies SET ${setClauses} WHERE id = ?`; try { const db = await getDbInstance(); const result = await runDb(db, sql, params); return result.changes > 0; } catch (err: any) { console.error(`Repository: 更新代理 ${id} 时出错:`, err.message); // Handle potential UNIQUE constraint errors if needed throw new Error('更新代理记录失败'); } }; /** * 删除代理 */ export const deleteProxy = async (id: number): Promise => { // Note: connections table proxy_id foreign key has ON DELETE SET NULL. const sql = `DELETE FROM proxies WHERE id = ?`; try { const db = await getDbInstance(); const result = await runDb(db, sql, [id]); return result.changes > 0; } catch (err: any) { console.error(`Repository: 删除代理 ${id} 时出错:`, err.message); throw new Error('删除代理记录失败'); } };