1- import { Readable } from 'node:stream' ;
21import type { ClickHouseSettings , ResponseJSON } from '@clickhouse/client' ;
32import { ClickHouseLogLevel , createClient } from '@clickhouse/client' ;
4- import sqlstring from 'sqlstring' ;
5-
63import type { NodeClickHouseClientConfigOptions } from '@clickhouse/client/dist/config' ;
74import { createLogger } from '@openpanel/logger' ;
85import type { IInterval } from '@openpanel/validation' ;
6+ import sqlstring from 'sqlstring' ;
97
108export { createClient } ;
119
@@ -68,8 +66,11 @@ export const TABLE_NAMES = {
6866 * Non-clustered mode = self-hosted environments
6967 */
7068export function isClickhouseClustered ( ) : boolean {
71- if ( process . env . CLICKHOUSE_CLUSTER === 'true' || process . env . CLICKHOUSE_CLUSTER === '1' ) {
72- return true
69+ if (
70+ process . env . CLICKHOUSE_CLUSTER === 'true' ||
71+ process . env . CLICKHOUSE_CLUSTER === '1'
72+ ) {
73+ return true ;
7374 }
7475
7576 return ! (
@@ -97,21 +98,21 @@ function getClickhouseSettings(): ClickHouseSettings {
9798 return {
9899 distributed_product_mode : 'allow' ,
99100 date_time_input_format : 'best_effort' ,
100- ...( ! process . env . CLICKHOUSE_SETTINGS_REMOVE_CONVERT_ANY_JOIN
101- ? {
101+ ...( process . env . CLICKHOUSE_SETTINGS_REMOVE_CONVERT_ANY_JOIN
102+ ? { }
103+ : {
102104 query_plan_convert_any_join_to_semi_or_anti_join : 0 ,
103- }
104- : { } ) ,
105+ } ) ,
105106 ...additionalSettings ,
106107 } ;
107108}
108109
109110export const CLICKHOUSE_OPTIONS : NodeClickHouseClientConfigOptions = {
110111 max_open_connections : 30 ,
111- request_timeout : 300000 ,
112+ request_timeout : 300_000 ,
112113 keep_alive : {
113114 enabled : true ,
114- idle_socket_ttl : 60000 ,
115+ idle_socket_ttl : 60_000 ,
115116 } ,
116117 compression : {
117118 request : true ,
@@ -138,7 +139,7 @@ const cleanQuery = (query?: string) =>
138139export async function withRetry < T > (
139140 operation : ( ) => Promise < T > ,
140141 maxRetries = 3 ,
141- baseDelay = 500 ,
142+ baseDelay = 500
142143) : Promise < T > {
143144 let lastError : Error | undefined ;
144145
@@ -162,7 +163,7 @@ export async function withRetry<T>(
162163 `Attempt ${ attempt + 1 } /${ maxRetries } failed, retrying in ${ delay } ms` ,
163164 {
164165 error : error . message ,
165- } ,
166+ }
166167 ) ;
167168 await new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
168169 continue ;
@@ -213,7 +214,7 @@ export const ch = new Proxy(originalCh, {
213214
214215export async function chQueryWithMeta < T extends Record < string , any > > (
215216 query : string ,
216- clickhouseSettings ?: ClickHouseSettings ,
217+ clickhouseSettings ?: ClickHouseSettings
217218) : Promise < ResponseJSON < T > > {
218219 const start = Date . now ( ) ;
219220 const res = await ch . query ( {
@@ -249,44 +250,16 @@ export async function chQueryWithMeta<T extends Record<string, any>>(
249250 return response ;
250251}
251252
252- export async function chInsertCSV ( tableName : string , rows : string [ ] ) {
253- try {
254- const now = performance . now ( ) ;
255- // Create a readable stream in binary mode for CSV (similar to EventBuffer)
256- const csvStream = Readable . from ( rows . join ( '\n' ) , {
257- objectMode : false ,
258- } ) ;
259-
260- await ch . insert ( {
261- table : tableName ,
262- values : csvStream ,
263- format : 'CSV' ,
264- clickhouse_settings : {
265- format_csv_allow_double_quotes : 1 ,
266- format_csv_allow_single_quotes : 0 ,
267- } ,
268- } ) ;
269-
270- logger . info ( 'CSV Insert successful' , {
271- elapsed : performance . now ( ) - now ,
272- rows : rows . length ,
273- } ) ;
274- } catch ( error ) {
275- logger . error ( 'CSV Insert failed:' , error ) ;
276- throw error ;
277- }
278- }
279-
280253export async function chQuery < T extends Record < string , any > > (
281254 query : string ,
282- clickhouseSettings ?: ClickHouseSettings ,
255+ clickhouseSettings ?: ClickHouseSettings
283256) : Promise < T [ ] > {
284257 return ( await chQueryWithMeta < T > ( query , clickhouseSettings ) ) . data ;
285258}
286259
287260export function formatClickhouseDate (
288261 date : Date | string ,
289- skipTime = false ,
262+ skipTime = false
290263) : string {
291264 if ( skipTime ) {
292265 return new Date ( date ) . toISOString ( ) . split ( 'T' ) [ 0 ] ! ;
0 commit comments