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 ')}` : ''; } // 字符串转义函数 function escapeString(str: string): string { return str.replace(/'/g, "\\'"); } // 构建通用过滤条件 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 = '${escapeString(params.eventType)}'`); } // 链接ID过滤 if (params.linkId) { filters.push(`link_id = '${escapeString(params.linkId)}'`); } // 链接短码过滤 if (params.linkSlug) { filters.push(`link_slug = '${escapeString(params.linkSlug)}'`); } // 用户ID过滤 if (params.userId) { filters.push(`user_id = '${escapeString(params.userId)}'`); } // 团队ID过滤 if (params.teamId) { filters.push(`team_id = '${escapeString(params.teamId)}'`); } // 项目ID过滤 if (params.projectId) { filters.push(`project_id = '${escapeString(params.projectId)}'`); } // 标签筛选 if (params.tags && params.tags.length > 0) { const tagConditions = params.tags.map(tag => `JSONHas(JSONExtractArrayRaw(link_tags), JSON_QUOTE('${escapeString(tag)}'))` ); filters.push(`(${tagConditions.join(' OR ')})`); } // Slug 模糊搜索 if (params.searchSlug) { filters.push(`positionCaseInsensitive(link_slug, '${escapeString(params.searchSlug)}') > 0`); } 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;