import { createClient } from '@clickhouse/client'; import type { EventsQueryParams } from './types'; // ClickHouse 客户端配置 const clickhouse = createClient({ url: process.env.CLICKHOUSE_URL, username: process.env.CLICKHOUSE_USER , password: process.env.CLICKHOUSE_PASSWORD , database: process.env.CLICKHOUSE_DATABASE }); // 构建日期过滤条件 function buildDateFilter(startTime?: string, endTime?: string): string { const filters = []; if (startTime) { filters.push(`event_time >= parseDateTimeBestEffort('${startTime}')`); } if (endTime) { filters.push(`event_time <= parseDateTimeBestEffort('${endTime}')`); } return filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : ''; } // 构建通用过滤条件 export function buildFilter(params: Partial): string { const filters = []; // 时间范围过滤 if (params.startTime || params.endTime) { const dateFilter = buildDateFilter(params.startTime, params.endTime).replace('WHERE ', ''); if (dateFilter) { filters.push(dateFilter); } } // 事件类型过滤 if (params.eventType) { filters.push(`event_type = '${params.eventType}'`); } // 链接ID过滤 if (params.linkId) { filters.push(`link_id = '${params.linkId}'`); } // 链接短码过滤 if (params.linkSlug) { filters.push(`link_slug = '${params.linkSlug}'`); } // 用户ID过滤 if (params.userId) { filters.push(`user_id = '${params.userId}'`); } // 团队ID过滤 if (params.teamId) { filters.push(`team_id = '${params.teamId}'`); } // 项目ID过滤 if (params.projectId) { filters.push(`project_id = '${params.projectId}'`); } return filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : ''; } // 构建分页 export function buildPagination(page?: number, pageSize?: number): string { const limit = pageSize || 20; const offset = ((page || 1) - 1) * limit; return `LIMIT ${limit} OFFSET ${offset}`; } // 构建排序 export function buildOrderBy(sortBy?: string, sortOrder?: 'asc' | 'desc'): string { if (!sortBy) { return 'ORDER BY event_time DESC'; } return `ORDER BY ${sortBy} ${sortOrder || 'desc'}`; } // 执行查询并处理错误 export async function executeQuery(query: string): Promise { try { const resultSet = await clickhouse.query({ query, format: 'JSONEachRow' }); const rows = await resultSet.json(); return Array.isArray(rows) ? rows : [rows]; } catch (error) { console.error('ClickHouse query error:', error); throw error; } } // 执行查询并返回单个结果 export async function executeQuerySingle(query: string): Promise { const results = await executeQuery(query); return results.length > 0 ? results[0] : null; } export default clickhouse;