@hypequery/clickhouse 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/core/features/aggregations.d.ts +13 -17
- package/dist/core/features/aggregations.d.ts.map +1 -1
- package/dist/core/features/aggregations.js +6 -6
- package/dist/core/features/analytics.d.ts +12 -16
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +2 -2
- package/dist/core/features/cross-filtering.d.ts +4 -19
- package/dist/core/features/cross-filtering.d.ts.map +1 -1
- package/dist/core/features/cross-filtering.js +0 -33
- package/dist/core/features/executor.d.ts +5 -9
- package/dist/core/features/executor.d.ts.map +1 -1
- package/dist/core/features/filtering.d.ts +14 -30
- package/dist/core/features/filtering.d.ts.map +1 -1
- package/dist/core/features/filtering.js +10 -26
- package/dist/core/features/joins.d.ts +6 -10
- package/dist/core/features/joins.d.ts.map +1 -1
- package/dist/core/features/pagination.d.ts +7 -10
- package/dist/core/features/pagination.d.ts.map +1 -1
- package/dist/core/features/pagination.js +13 -41
- package/dist/core/features/query-modifiers.d.ts +17 -21
- package/dist/core/features/query-modifiers.d.ts.map +1 -1
- package/dist/core/query-builder.d.ts +46 -75
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +74 -95
- package/dist/core/tests/integration/setup.d.ts +1 -1
- package/dist/core/tests/test-utils.d.ts +4 -3
- package/dist/core/tests/test-utils.d.ts.map +1 -1
- package/dist/core/tests/test-utils.js +18 -8
- package/dist/core/types/builder-state.d.ts +25 -0
- package/dist/core/types/builder-state.d.ts.map +1 -0
- package/dist/core/types/builder-state.js +1 -0
- package/dist/core/types/select-types.d.ts +25 -0
- package/dist/core/types/select-types.d.ts.map +1 -0
- package/dist/core/types/select-types.js +1 -0
- package/dist/core/types/type-helpers.d.ts +5 -0
- package/dist/core/types/type-helpers.d.ts.map +1 -0
- package/dist/core/types/type-helpers.js +1 -0
- package/dist/core/utils/predicate-builder.d.ts +12 -10
- package/dist/core/utils/predicate-builder.d.ts.map +1 -1
- package/dist/core/utils/predicate-builder.js +2 -1
- package/dist/core/utils/sql-expressions.d.ts +11 -10
- package/dist/core/utils/sql-expressions.d.ts.map +1 -1
- package/dist/core/utils/sql-expressions.js +4 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types/schema.d.ts +1 -1
- package/dist/types/schema.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { CrossFilter } from './cross-filter.js';
|
|
2
|
-
import {
|
|
3
|
-
import { ColumnType, InferColumnType, TableColumn } from '../types/schema.js';
|
|
2
|
+
import { FilterOperator, OperatorValueMap, OrderDirection, PaginatedResult, PaginationOptions, QueryConfig } from '../types/index.js';
|
|
4
3
|
import { SQLFormatter } from './formatters/sql-formatter.js';
|
|
5
4
|
import { JoinRelationships, JoinPathOptions } from './join-relationships.js';
|
|
6
|
-
import { SqlExpression } from './utils/sql-expressions.js';
|
|
7
5
|
import { PredicateBuilder, PredicateExpression } from './utils/predicate-builder.js';
|
|
8
6
|
import type { ClickHouseSettings, BaseClickHouseClientConfigOptions } from '@clickhouse/client-common';
|
|
9
7
|
import type { ClickHouseClient as NodeClickHouseClient } from '@clickhouse/client';
|
|
10
8
|
import type { ClickHouseClient as WebClickHouseClient } from '@clickhouse/client-web';
|
|
9
|
+
import type { BuilderState, AnyBuilderState, SchemaDefinition, InitialState, UpdateOutput, WidenTables, AppendToOutput, BaseRow, AddAlias } from './types/builder-state.js';
|
|
10
|
+
import { SelectableItem, SelectableColumn, SelectionResult, ColumnSelectionValue } from './types/select-types.js';
|
|
11
|
+
type WhereColumn<State extends AnyBuilderState> = SelectableColumn<State>;
|
|
12
|
+
type ColumnOperatorValue<Schema extends SchemaDefinition<Schema>, State extends BuilderState<Schema, string, any, keyof Schema, Partial<Record<string, keyof Schema>>>, Column extends WhereColumn<State>, Op extends keyof OperatorValueMap<any, Schema>> = OperatorValueMap<ColumnSelectionValue<State, Column>, Schema>[Op];
|
|
11
13
|
type ClickHouseClient = NodeClickHouseClient | WebClickHouseClient;
|
|
12
14
|
/**
|
|
13
15
|
* Configuration for client-based connections.
|
|
@@ -27,21 +29,13 @@ export type ClickHouseConfig = BaseClickHouseClientConfigOptions | ClickHouseCli
|
|
|
27
29
|
export declare function isClientConfig(config: ClickHouseConfig): config is ClickHouseClientConfig;
|
|
28
30
|
/**
|
|
29
31
|
* A type-safe query builder for ClickHouse databases.
|
|
30
|
-
*
|
|
31
|
-
* @template T - The schema type of the current table
|
|
32
|
-
* @template HasSelect - Whether a SELECT clause has been applied
|
|
33
|
-
* @template Aggregations - The type of any aggregation functions applied
|
|
32
|
+
* The builder carries a single state object that encodes scope, output, and schema metadata.
|
|
34
33
|
*/
|
|
35
|
-
export declare class QueryBuilder<Schema extends {
|
|
36
|
-
[K in keyof Schema]: {
|
|
37
|
-
[columnName: string]: ColumnType;
|
|
38
|
-
};
|
|
39
|
-
}, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
|
|
34
|
+
export declare class QueryBuilder<Schema extends SchemaDefinition<Schema>, State extends BuilderState<Schema, string, any, keyof Schema, Partial<Record<string, keyof Schema>>>> {
|
|
40
35
|
private static relationships;
|
|
41
36
|
private config;
|
|
42
37
|
private tableName;
|
|
43
|
-
private
|
|
44
|
-
private originalSchema;
|
|
38
|
+
private state;
|
|
45
39
|
private formatter;
|
|
46
40
|
private aggregations;
|
|
47
41
|
private joins;
|
|
@@ -51,13 +45,10 @@ export declare class QueryBuilder<Schema extends {
|
|
|
51
45
|
private modifiers;
|
|
52
46
|
private pagination;
|
|
53
47
|
private crossFiltering;
|
|
54
|
-
constructor(tableName: string,
|
|
55
|
-
|
|
56
|
-
columns: T;
|
|
57
|
-
}, originalSchema: Schema);
|
|
48
|
+
constructor(tableName: string, state: State);
|
|
49
|
+
private fork;
|
|
58
50
|
debug(): this;
|
|
59
|
-
|
|
60
|
-
withCTE(alias: string, subquery: QueryBuilder<any, any> | string): this;
|
|
51
|
+
withCTE(alias: string, subquery: QueryBuilder<any, AnyBuilderState> | string): this;
|
|
61
52
|
/**
|
|
62
53
|
* Groups results by a time interval using a specified ClickHouse function.
|
|
63
54
|
*
|
|
@@ -70,7 +61,7 @@ export declare class QueryBuilder<Schema extends {
|
|
|
70
61
|
* 'toStartOfDay', 'toStartOfWeek', 'toStartOfMonth', 'toStartOfQuarter', and 'toStartOfYear'.
|
|
71
62
|
* @returns The current QueryBuilder instance.
|
|
72
63
|
*/
|
|
73
|
-
groupByTimeInterval(column:
|
|
64
|
+
groupByTimeInterval(column: SelectableColumn<State>, interval: string, method?: 'toStartOfInterval' | 'toStartOfMinute' | 'toStartOfHour' | 'toStartOfDay' | 'toStartOfWeek' | 'toStartOfMonth' | 'toStartOfQuarter' | 'toStartOfYear'): this;
|
|
74
65
|
raw(sql: string): this;
|
|
75
66
|
settings(opts: ClickHouseSettings): this;
|
|
76
67
|
/**
|
|
@@ -91,14 +82,15 @@ export declare class QueryBuilder<Schema extends {
|
|
|
91
82
|
* builder.select('*')
|
|
92
83
|
* ```
|
|
93
84
|
*/
|
|
94
|
-
select
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
sum<Column extends keyof
|
|
98
|
-
count<Column extends keyof
|
|
99
|
-
avg<Column extends keyof
|
|
100
|
-
min<Column extends keyof
|
|
101
|
-
max<Column extends keyof
|
|
85
|
+
select(columnsOrAsterisk: '*'): QueryBuilder<Schema, UpdateOutput<State, BaseRow<State>>>;
|
|
86
|
+
select<Selections extends ReadonlyArray<SelectableItem<State>>>(columnsOrAsterisk: Selections): QueryBuilder<Schema, UpdateOutput<State, SelectionResult<State, Selections[number]>>>;
|
|
87
|
+
selectConst<Selections extends ReadonlyArray<SelectableItem<State>>>(...columns: Selections): QueryBuilder<Schema, UpdateOutput<State, SelectionResult<State, Selections[number]>>>;
|
|
88
|
+
sum<Column extends keyof BaseRow<State>, Alias extends string = `${Column & string}_sum`>(column: Column, alias?: Alias): QueryBuilder<Schema, AppendToOutput<State, Record<Alias, string>>>;
|
|
89
|
+
count<Column extends keyof BaseRow<State>, Alias extends string = `${Column & string}_count`>(column: Column, alias?: Alias): QueryBuilder<Schema, AppendToOutput<State, Record<Alias, string>>>;
|
|
90
|
+
avg<Column extends keyof BaseRow<State>, Alias extends string = `${Column & string}_avg`>(column: Column, alias?: Alias): QueryBuilder<Schema, AppendToOutput<State, Record<Alias, string>>>;
|
|
91
|
+
min<Column extends keyof BaseRow<State>, Alias extends string = `${Column & string}_min`>(column: Column, alias?: Alias): QueryBuilder<Schema, AppendToOutput<State, Record<Alias, string>>>;
|
|
92
|
+
max<Column extends keyof BaseRow<State>, Alias extends string = `${Column & string}_max`>(column: Column, alias?: Alias): QueryBuilder<Schema, AppendToOutput<State, Record<Alias, string>>>;
|
|
93
|
+
private applyAggregation;
|
|
102
94
|
getTableName(): string;
|
|
103
95
|
getFormatter(): SQLFormatter;
|
|
104
96
|
toSQL(): string;
|
|
@@ -106,13 +98,13 @@ export declare class QueryBuilder<Schema extends {
|
|
|
106
98
|
sql: string;
|
|
107
99
|
parameters: any[];
|
|
108
100
|
};
|
|
109
|
-
execute(): Promise<
|
|
110
|
-
stream(): Promise<ReadableStream<
|
|
101
|
+
execute(): Promise<State['output'][]>;
|
|
102
|
+
stream(): Promise<ReadableStream<State['output'][]>>;
|
|
111
103
|
/**
|
|
112
104
|
* Processes each row in a stream with the provided callback function
|
|
113
105
|
* @param callback Function to call for each row in the stream
|
|
114
106
|
*/
|
|
115
|
-
streamForEach<R = void>(callback: (row:
|
|
107
|
+
streamForEach<R = void>(callback: (row: State['output']) => R | Promise<R>): Promise<void>;
|
|
116
108
|
private validateFilterValue;
|
|
117
109
|
/**
|
|
118
110
|
* Adds a WHERE clause to filter results.
|
|
@@ -126,8 +118,8 @@ export declare class QueryBuilder<Schema extends {
|
|
|
126
118
|
* builder.where('age', 'gt', 18)
|
|
127
119
|
* ```
|
|
128
120
|
*/
|
|
129
|
-
where(expressionBuilder: (expr: PredicateBuilder<
|
|
130
|
-
where<
|
|
121
|
+
where(expressionBuilder: (expr: PredicateBuilder<State>) => PredicateExpression): this;
|
|
122
|
+
where<Column extends WhereColumn<State>, Op extends keyof OperatorValueMap<any, Schema>>(columnOrColumns: Column | Column[], operator: Op, value: ColumnOperatorValue<Schema, State, Column, Op>): this;
|
|
131
123
|
/**
|
|
132
124
|
* Adds a WHERE clause for tuple IN operations.
|
|
133
125
|
* @template K - The column keys type
|
|
@@ -140,22 +132,10 @@ export declare class QueryBuilder<Schema extends {
|
|
|
140
132
|
* builder.where(['counter_id', 'user_id'], 'inTuple', [[34, 123], [101500, 456]])
|
|
141
133
|
* ```
|
|
142
134
|
*/
|
|
143
|
-
where<
|
|
144
|
-
orWhere(expressionBuilder: (expr: PredicateBuilder<
|
|
145
|
-
orWhere<
|
|
146
|
-
|
|
147
|
-
* Adds an OR WHERE clause for tuple IN operations.
|
|
148
|
-
* @template K - The column keys type
|
|
149
|
-
* @param {K[]} columns - The columns to filter on (for tuple operations)
|
|
150
|
-
* @param {'inTuple' | 'globalInTuple'} operator - The tuple IN operator
|
|
151
|
-
* @param {any} value - The array of tuples to compare against
|
|
152
|
-
* @returns {this} The current QueryBuilder instance
|
|
153
|
-
* @example
|
|
154
|
-
* ```ts
|
|
155
|
-
* builder.orWhere(['counter_id', 'user_id'], 'inTuple', [[34, 123], [101500, 456]])
|
|
156
|
-
* ```
|
|
157
|
-
*/
|
|
158
|
-
orWhere<K extends keyof OriginalT | TableColumn<Schema>>(columns: K[], operator: 'inTuple' | 'globalInTuple', value: any): this;
|
|
135
|
+
where<Column extends WhereColumn<State>>(columns: Column[], operator: 'inTuple' | 'globalInTuple', value: any): this;
|
|
136
|
+
orWhere(expressionBuilder: (expr: PredicateBuilder<State>) => PredicateExpression): this;
|
|
137
|
+
orWhere<Column extends WhereColumn<State>>(column: Column, operator: FilterOperator, value: any): this;
|
|
138
|
+
orWhere<Column extends WhereColumn<State>>(columns: Column[], operator: 'inTuple' | 'globalInTuple', value: any): this;
|
|
159
139
|
/**
|
|
160
140
|
* Creates a parenthesized group of WHERE conditions joined with AND/OR operators.
|
|
161
141
|
* @param {Function} callback - Function that builds the conditions within the group
|
|
@@ -189,7 +169,7 @@ export declare class QueryBuilder<Schema extends {
|
|
|
189
169
|
* builder.groupBy(['category', 'status'])
|
|
190
170
|
* ```
|
|
191
171
|
*/
|
|
192
|
-
groupBy(columns:
|
|
172
|
+
groupBy(columns: SelectableColumn<State> | Array<SelectableColumn<State>>): this;
|
|
193
173
|
limit(count: number): this;
|
|
194
174
|
offset(count: number): this;
|
|
195
175
|
/**
|
|
@@ -202,7 +182,7 @@ export declare class QueryBuilder<Schema extends {
|
|
|
202
182
|
* builder.orderBy('created_at', 'DESC')
|
|
203
183
|
* ```
|
|
204
184
|
*/
|
|
205
|
-
orderBy
|
|
185
|
+
orderBy(column: SelectableColumn<State>, direction?: OrderDirection): this;
|
|
206
186
|
/**
|
|
207
187
|
* Adds a HAVING clause for filtering grouped results.
|
|
208
188
|
* @param {string} condition - The HAVING condition
|
|
@@ -214,43 +194,34 @@ export declare class QueryBuilder<Schema extends {
|
|
|
214
194
|
*/
|
|
215
195
|
having(condition: string, parameters?: any[]): this;
|
|
216
196
|
distinct(): this;
|
|
217
|
-
whereBetween<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
]):
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
fullJoin<TableName extends keyof Schema>(table: TableName, leftColumn: keyof OriginalT, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: string): QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>;
|
|
225
|
-
getConfig(): QueryConfig<T, Schema>;
|
|
197
|
+
whereBetween<Column extends keyof BaseRow<State>>(column: Column, [min, max]: [BaseRow<State>[Column], BaseRow<State>[Column]]): this;
|
|
198
|
+
innerJoin<TableName extends Extract<keyof Schema, string>, Alias extends string | undefined = undefined>(table: TableName, leftColumn: keyof BaseRow<State>, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: Alias): QueryBuilder<Schema, Alias extends string ? AddAlias<WidenTables<State, TableName>, Alias, TableName> : WidenTables<State, TableName>>;
|
|
199
|
+
leftJoin<TableName extends Extract<keyof Schema, string>, Alias extends string | undefined = undefined>(table: TableName, leftColumn: keyof BaseRow<State>, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: Alias): QueryBuilder<Schema, Alias extends string ? AddAlias<WidenTables<State, TableName>, Alias, TableName> : WidenTables<State, TableName>>;
|
|
200
|
+
rightJoin<TableName extends Extract<keyof Schema, string>, Alias extends string | undefined = undefined>(table: TableName, leftColumn: keyof BaseRow<State>, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: Alias): QueryBuilder<Schema, Alias extends string ? AddAlias<WidenTables<State, TableName>, Alias, TableName> : WidenTables<State, TableName>>;
|
|
201
|
+
fullJoin<TableName extends Extract<keyof Schema, string>, Alias extends string | undefined = undefined>(table: TableName, leftColumn: keyof BaseRow<State>, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: Alias): QueryBuilder<Schema, Alias extends string ? AddAlias<WidenTables<State, TableName>, Alias, TableName> : WidenTables<State, TableName>>;
|
|
202
|
+
private applyJoin;
|
|
203
|
+
getConfig(): QueryConfig<State["output"], Schema>;
|
|
226
204
|
/**
|
|
227
205
|
* Paginates the query results using cursor-based pagination
|
|
228
206
|
*/
|
|
229
|
-
paginate(options: PaginationOptions<
|
|
207
|
+
paginate(options: PaginationOptions<State['output']>): Promise<PaginatedResult<State['output']>>;
|
|
230
208
|
/**
|
|
231
209
|
* Gets the first page of results
|
|
232
210
|
*/
|
|
233
|
-
firstPage(pageSize: number): Promise<PaginatedResult<
|
|
211
|
+
firstPage(pageSize: number): Promise<PaginatedResult<State['output']>>;
|
|
234
212
|
/**
|
|
235
213
|
* Returns an async iterator that yields all pages
|
|
236
214
|
*/
|
|
237
|
-
iteratePages(pageSize: number): AsyncGenerator<PaginatedResult<
|
|
238
|
-
static setJoinRelationships<S extends
|
|
239
|
-
[K in keyof S]: {
|
|
240
|
-
[columnName: string]: ColumnType;
|
|
241
|
-
};
|
|
242
|
-
}>(relationships: JoinRelationships<S>): void;
|
|
215
|
+
iteratePages(pageSize: number): AsyncGenerator<PaginatedResult<State['output']>>;
|
|
216
|
+
static setJoinRelationships<S extends SchemaDefinition<S>>(relationships: JoinRelationships<S>): void;
|
|
243
217
|
/**
|
|
244
218
|
* Apply a predefined join relationship
|
|
245
219
|
*/
|
|
246
220
|
withRelation(name: string, options?: JoinPathOptions): this;
|
|
247
221
|
}
|
|
248
|
-
export
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
};
|
|
252
|
-
}>(config: ClickHouseConfig): {
|
|
253
|
-
table<TableName extends keyof Schema>(tableName: TableName): QueryBuilder<Schema, Schema[TableName], false, {}>;
|
|
222
|
+
export type SelectQB<Schema extends SchemaDefinition<Schema>, Tables extends string, Output, BaseTable extends keyof Schema> = QueryBuilder<Schema, BuilderState<Schema, Tables, Output, BaseTable, {}>>;
|
|
223
|
+
export declare function createQueryBuilder<Schema extends SchemaDefinition<Schema>>(config: ClickHouseConfig): {
|
|
224
|
+
table<TableName extends Extract<keyof Schema, string>>(tableName: TableName): SelectQB<Schema, TableName, InitialState<Schema, TableName>["output"], TableName>;
|
|
254
225
|
};
|
|
255
226
|
export {};
|
|
256
227
|
//# sourceMappingURL=query-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../src/core/query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../src/core/query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,WAAW,EAEZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAS7D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE7E,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AACvG,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,OAAO,EACP,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,WAAW,CAAC,KAAK,SAAS,eAAe,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAE1E,KAAK,mBAAmB,CACtB,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC,CAAC,CAAC,EACpG,MAAM,SAAS,WAAW,CAAC,KAAK,CAAC,EACjC,EAAE,SAAS,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,IAC5C,gBAAgB,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;AAGtE,KAAK,gBAAgB,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iCAAiC;IAC/E,iDAAiD;IACjD,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,iCAAiC,GAAG,sBAAsB,CAAC;AAE1F;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,IAAI,sBAAsB,CAEzF;AAED;;;GAGG;AACH,qBAAa,YAAY,CACvB,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvC,KAAK,SAAS,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC,CAAC,CAAC;IAEpG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAyB;IAErD,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,cAAc,CAAuC;gBAG3D,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,KAAK;IAcd,OAAO,CAAC,IAAI;IAiBZ,KAAK;IASL,OAAO,CACL,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,GAAG,MAAM,GACpD,IAAI;IAKP;;;;;;;;;;;KAWC;IACD,mBAAmB,CACjB,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAmB,GAAG,iBAAiB,GAAG,eAAe,GAAG,cAAc,GAAG,eAAe,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,eAAqC,GACnL,IAAI;IAMP,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAStB,QAAQ,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAKxC;;;;;OAKG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI;IAMxF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,iBAAiB,EAAE,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACzF,MAAM,CAAC,UAAU,SAAS,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAC5D,iBAAiB,EAAE,UAAU,GAC5B,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAgDxF,WAAW,CAAC,UAAU,SAAS,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EACjE,GAAG,OAAO,EAAE,UAAU,GACrB,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAIxF,GAAG,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,MAAM,EACtF,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAMrE,KAAK,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,QAAQ,EAC1F,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAMrE,GAAG,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,MAAM,EACtF,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAMrE,GAAG,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,MAAM,EACtF,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAMrE,GAAG,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,MAAM,EACtF,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAMrE,OAAO,CAAC,gBAAgB;IAoBxB,YAAY;IAIZ,YAAY;IAKZ,KAAK,IAAI,MAAM;IAIf,eAAe,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,GAAG,EAAE,CAAA;KAAE;IAIrD,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;IAI/B,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAI1D;;;OAGG;IACG,aAAa,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhG,OAAO,CAAC,mBAAmB;IAgC3B;;;;;;;;;;;OAWG;IACH,KAAK,CACH,iBAAiB,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,mBAAmB,GACxE,IAAI;IACP,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,EACrF,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,EAClC,QAAQ,EAAE,EAAE,EACZ,KAAK,EAAE,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,GACpD,IAAI;IACP;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,MAAM,SAAS,WAAW,CAAC,KAAK,CAAC,EACrC,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,SAAS,GAAG,eAAe,EACrC,KAAK,EAAE,GAAG,GACT,IAAI;IA8BP,OAAO,CACL,iBAAiB,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,mBAAmB,GACxE,IAAI;IACP,OAAO,CAAC,MAAM,SAAS,WAAW,CAAC,KAAK,CAAC,EACvC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,GAAG,GACT,IAAI;IACP,OAAO,CAAC,MAAM,SAAS,WAAW,CAAC,KAAK,CAAC,EACvC,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,SAAS,GAAG,eAAe,EACrC,KAAK,EAAE,GAAG,GACT,IAAI;IA6BP;;;;;;;;;;OAUG;IACH,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAOnD;;;;;;;;;;OAUG;IACH,YAAY,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAOrD;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI;IAMhF,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B;;;;;;;;;OASG;IACH,OAAO,CACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC/B,SAAS,GAAE,cAAsB,GAChC,IAAI;IAKP;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAKnD,QAAQ,IAAI,IAAI;IAKhB,YAAY,CAAC,MAAM,SAAS,MAAM,OAAO,CAAC,KAAK,CAAC,EAC9C,MAAM,EAAE,MAAM,EACd,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAC3D,IAAI;IAOP,SAAS,CAAC,SAAS,SAAS,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,EACrG,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAChC,WAAW,EAAE,GAAG,SAAS,GAAG,MAAM,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EACxE,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CACb,MAAM,EACN,KAAK,SAAS,MAAM,GAClB,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GACzD,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAChC;IAID,QAAQ,CAAC,SAAS,SAAS,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,EACpG,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAChC,WAAW,EAAE,GAAG,SAAS,GAAG,MAAM,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EACxE,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CACb,MAAM,EACN,KAAK,SAAS,MAAM,GAClB,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GACzD,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAChC;IAID,SAAS,CAAC,SAAS,SAAS,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,EACrG,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAChC,WAAW,EAAE,GAAG,SAAS,GAAG,MAAM,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EACxE,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CACb,MAAM,EACN,KAAK,SAAS,MAAM,GAClB,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GACzD,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAChC;IAID,QAAQ,CAAC,SAAS,SAAS,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,EACpG,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAChC,WAAW,EAAE,GAAG,SAAS,GAAG,MAAM,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,EACxE,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY,CACb,MAAM,EACN,KAAK,SAAS,MAAM,GAClB,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GACzD,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAChC;IAID,OAAO,CAAC,SAAS;IAyBjB,SAAS;IAIT;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAItG;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAI5E;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAIhF,MAAM,CAAC,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,CAAC,CAAC,CAAC,EACvD,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAClC,IAAI;IAIP;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;CA8B5D;AAED,MAAM,MAAM,QAAQ,CAClB,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvC,MAAM,SAAS,MAAM,EACrB,MAAM,EACN,SAAS,SAAS,MAAM,MAAM,IAC5B,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;AAE9E,wBAAgB,kBAAkB,CAAC,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACxE,MAAM,EAAE,gBAAgB;UAKhB,SAAS,SAAS,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,aAAa,SAAS,GAAG,QAAQ,CACpF,MAAM,EACN,SAAS,EACT,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,EACzC,SAAS,CACV;EAaJ"}
|
|
@@ -18,17 +18,13 @@ export function isClientConfig(config) {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* A type-safe query builder for ClickHouse databases.
|
|
21
|
-
*
|
|
22
|
-
* @template T - The schema type of the current table
|
|
23
|
-
* @template HasSelect - Whether a SELECT clause has been applied
|
|
24
|
-
* @template Aggregations - The type of any aggregation functions applied
|
|
21
|
+
* The builder carries a single state object that encodes scope, output, and schema metadata.
|
|
25
22
|
*/
|
|
26
23
|
export class QueryBuilder {
|
|
27
24
|
static relationships;
|
|
28
25
|
config = {};
|
|
29
26
|
tableName;
|
|
30
|
-
|
|
31
|
-
originalSchema;
|
|
27
|
+
state;
|
|
32
28
|
formatter = new SQLFormatter();
|
|
33
29
|
aggregations;
|
|
34
30
|
joins;
|
|
@@ -38,10 +34,9 @@ export class QueryBuilder {
|
|
|
38
34
|
modifiers;
|
|
39
35
|
pagination;
|
|
40
36
|
crossFiltering;
|
|
41
|
-
constructor(tableName,
|
|
37
|
+
constructor(tableName, state) {
|
|
42
38
|
this.tableName = tableName;
|
|
43
|
-
this.
|
|
44
|
-
this.originalSchema = originalSchema;
|
|
39
|
+
this.state = state;
|
|
45
40
|
this.aggregations = new AggregationFeature(this);
|
|
46
41
|
this.joins = new JoinFeature(this);
|
|
47
42
|
this.filtering = new FilteringFeature(this);
|
|
@@ -51,28 +46,18 @@ export class QueryBuilder {
|
|
|
51
46
|
this.pagination = new PaginationFeature(this);
|
|
52
47
|
this.crossFiltering = new CrossFilteringFeature(this);
|
|
53
48
|
}
|
|
49
|
+
fork(state, config) {
|
|
50
|
+
const builder = new QueryBuilder(this.tableName, state);
|
|
51
|
+
builder.config = { ...config };
|
|
52
|
+
return builder;
|
|
53
|
+
}
|
|
54
54
|
debug() {
|
|
55
55
|
console.log('Current Type:', {
|
|
56
|
-
|
|
57
|
-
originalSchema: this.originalSchema,
|
|
56
|
+
state: this.state,
|
|
58
57
|
config: this.config
|
|
59
58
|
});
|
|
60
59
|
return this;
|
|
61
60
|
}
|
|
62
|
-
clone() {
|
|
63
|
-
const newBuilder = new QueryBuilder(this.tableName, this.schema, this.originalSchema);
|
|
64
|
-
newBuilder.config = { ...this.config };
|
|
65
|
-
// Initialize features with the new builder
|
|
66
|
-
newBuilder.aggregations = new AggregationFeature(newBuilder);
|
|
67
|
-
newBuilder.joins = new JoinFeature(newBuilder);
|
|
68
|
-
newBuilder.filtering = new FilteringFeature(newBuilder);
|
|
69
|
-
newBuilder.analytics = new AnalyticsFeature(newBuilder);
|
|
70
|
-
newBuilder.executor = new ExecutorFeature(newBuilder);
|
|
71
|
-
newBuilder.modifiers = new QueryModifiersFeature(newBuilder);
|
|
72
|
-
newBuilder.pagination = new PaginationFeature(newBuilder);
|
|
73
|
-
newBuilder.crossFiltering = new CrossFilteringFeature(newBuilder);
|
|
74
|
-
return newBuilder;
|
|
75
|
-
}
|
|
76
61
|
// --- Analytics Helper: Add a CTE.
|
|
77
62
|
withCTE(alias, subquery) {
|
|
78
63
|
this.config = this.analytics.addCTE(alias, subquery);
|
|
@@ -91,7 +76,7 @@ export class QueryBuilder {
|
|
|
91
76
|
* @returns The current QueryBuilder instance.
|
|
92
77
|
*/
|
|
93
78
|
groupByTimeInterval(column, interval, method = 'toStartOfInterval') {
|
|
94
|
-
this.config = this.analytics.addTimeInterval(column, interval, method);
|
|
79
|
+
this.config = this.analytics.addTimeInterval(String(column), interval, method);
|
|
95
80
|
return this;
|
|
96
81
|
}
|
|
97
82
|
// --- Analytics Helper: Add a raw SQL fragment.
|
|
@@ -117,22 +102,13 @@ export class QueryBuilder {
|
|
|
117
102
|
this.config = this.crossFiltering.applyCrossFilters(crossFilter);
|
|
118
103
|
return this;
|
|
119
104
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Selects specific columns from the table.
|
|
122
|
-
* @template K - The keys/columns to select
|
|
123
|
-
* @param {K[] | '*'} columnsOrAsterisk - Array of column names to select or '*' for all columns
|
|
124
|
-
* @returns {QueryBuilder} A new QueryBuilder instance with updated types
|
|
125
|
-
* @example
|
|
126
|
-
* ```ts
|
|
127
|
-
* builder.select(['id', 'name'])
|
|
128
|
-
* builder.select('*')
|
|
129
|
-
* ```
|
|
130
|
-
*/
|
|
131
105
|
select(columnsOrAsterisk) {
|
|
132
|
-
// Handle '*' case - return all columns with original type
|
|
133
106
|
if (columnsOrAsterisk === '*') {
|
|
134
|
-
const
|
|
135
|
-
|
|
107
|
+
const nextState = {
|
|
108
|
+
...this.state,
|
|
109
|
+
output: {}
|
|
110
|
+
};
|
|
111
|
+
const nextConfig = {
|
|
136
112
|
...this.config,
|
|
137
113
|
select: ['*'],
|
|
138
114
|
orderBy: this.config.orderBy?.map(({ column, direction }) => ({
|
|
@@ -140,23 +116,20 @@ export class QueryBuilder {
|
|
|
140
116
|
direction
|
|
141
117
|
}))
|
|
142
118
|
};
|
|
143
|
-
return
|
|
119
|
+
return this.fork(nextState, nextConfig);
|
|
144
120
|
}
|
|
145
|
-
// Handle array case - select specific columns
|
|
146
121
|
const columns = columnsOrAsterisk;
|
|
147
|
-
// Create a new builder with the appropriate type parameters
|
|
148
|
-
const newBuilder = new QueryBuilder(this.tableName, {
|
|
149
|
-
name: this.schema.name,
|
|
150
|
-
columns: {}
|
|
151
|
-
}, this.originalSchema);
|
|
152
|
-
// Process columns array to handle SqlExpressions and convert to strings
|
|
153
122
|
const processedColumns = columns.map(col => {
|
|
154
123
|
if (typeof col === 'object' && col !== null && '__type' in col) {
|
|
155
124
|
return col.toSql();
|
|
156
125
|
}
|
|
157
126
|
return String(col);
|
|
158
127
|
});
|
|
159
|
-
|
|
128
|
+
const nextState = {
|
|
129
|
+
...this.state,
|
|
130
|
+
output: {}
|
|
131
|
+
};
|
|
132
|
+
const nextConfig = {
|
|
160
133
|
...this.config,
|
|
161
134
|
select: processedColumns,
|
|
162
135
|
orderBy: this.config.orderBy?.map(({ column, direction }) => ({
|
|
@@ -164,32 +137,35 @@ export class QueryBuilder {
|
|
|
164
137
|
direction
|
|
165
138
|
}))
|
|
166
139
|
};
|
|
167
|
-
return
|
|
140
|
+
return this.fork(nextState, nextConfig);
|
|
141
|
+
}
|
|
142
|
+
selectConst(...columns) {
|
|
143
|
+
return this.select(columns);
|
|
168
144
|
}
|
|
169
145
|
sum(column, alias) {
|
|
170
|
-
|
|
171
|
-
newBuilder.config = this.aggregations.sum(column, alias);
|
|
172
|
-
return newBuilder;
|
|
146
|
+
return this.applyAggregation(column, alias, 'sum', (col, finalAlias) => this.aggregations.sum(col, finalAlias));
|
|
173
147
|
}
|
|
174
148
|
count(column, alias) {
|
|
175
|
-
|
|
176
|
-
newBuilder.config = this.aggregations.count(column, alias);
|
|
177
|
-
return newBuilder;
|
|
149
|
+
return this.applyAggregation(column, alias, 'count', (col, finalAlias) => this.aggregations.count(col, finalAlias));
|
|
178
150
|
}
|
|
179
151
|
avg(column, alias) {
|
|
180
|
-
|
|
181
|
-
newBuilder.config = this.aggregations.avg(column, alias);
|
|
182
|
-
return newBuilder;
|
|
152
|
+
return this.applyAggregation(column, alias, 'avg', (col, finalAlias) => this.aggregations.avg(col, finalAlias));
|
|
183
153
|
}
|
|
184
154
|
min(column, alias) {
|
|
185
|
-
|
|
186
|
-
newBuilder.config = this.aggregations.min(column, alias);
|
|
187
|
-
return newBuilder;
|
|
155
|
+
return this.applyAggregation(column, alias, 'min', (col, finalAlias) => this.aggregations.min(col, finalAlias));
|
|
188
156
|
}
|
|
189
157
|
max(column, alias) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
158
|
+
return this.applyAggregation(column, alias, 'max', (col, finalAlias) => this.aggregations.max(col, finalAlias));
|
|
159
|
+
}
|
|
160
|
+
applyAggregation(column, alias, suffix, updater) {
|
|
161
|
+
const columnName = String(column);
|
|
162
|
+
const finalAlias = (alias || `${columnName}_${suffix}`);
|
|
163
|
+
const nextState = {
|
|
164
|
+
...this.state,
|
|
165
|
+
output: {}
|
|
166
|
+
};
|
|
167
|
+
const nextConfig = updater(columnName, finalAlias);
|
|
168
|
+
return this.fork(nextState, nextConfig);
|
|
193
169
|
}
|
|
194
170
|
// Make needed properties accessible to features
|
|
195
171
|
getTableName() {
|
|
@@ -247,10 +223,12 @@ export class QueryBuilder {
|
|
|
247
223
|
if (advancedInOperators.includes(operator)) {
|
|
248
224
|
return;
|
|
249
225
|
}
|
|
250
|
-
|
|
226
|
+
const columnName = String(column);
|
|
227
|
+
if (FilterValidator.validateJoinedColumn(columnName))
|
|
251
228
|
return;
|
|
252
|
-
const
|
|
253
|
-
|
|
229
|
+
const baseColumns = this.state.base;
|
|
230
|
+
const columnType = baseColumns[columnName];
|
|
231
|
+
FilterValidator.validateFilterCondition({ column: columnName, operator, value }, columnType);
|
|
254
232
|
}
|
|
255
233
|
where(columnOrColumns, operator, value) {
|
|
256
234
|
if (typeof columnOrColumns === 'function') {
|
|
@@ -263,16 +241,14 @@ export class QueryBuilder {
|
|
|
263
241
|
}
|
|
264
242
|
// Handle tuple operations
|
|
265
243
|
if (Array.isArray(columnOrColumns) && (operator === 'inTuple' || operator === 'globalInTuple')) {
|
|
266
|
-
// For tuple operations, we need to handle the column array specially
|
|
267
244
|
const columns = columnOrColumns;
|
|
268
245
|
this.validateFilterValue(columns, operator, value);
|
|
269
|
-
this.config = this.filtering.addCondition('AND', columns, operator, value);
|
|
246
|
+
this.config = this.filtering.addCondition('AND', columns.map(String), operator, value);
|
|
270
247
|
return this;
|
|
271
248
|
}
|
|
272
|
-
// Handle regular operations
|
|
273
249
|
const column = columnOrColumns;
|
|
274
250
|
this.validateFilterValue(column, operator, value);
|
|
275
|
-
this.config = this.filtering.addCondition('AND', column, operator, value);
|
|
251
|
+
this.config = this.filtering.addCondition('AND', String(column), operator, value);
|
|
276
252
|
return this;
|
|
277
253
|
}
|
|
278
254
|
orWhere(columnOrColumns, operator, value) {
|
|
@@ -284,18 +260,15 @@ export class QueryBuilder {
|
|
|
284
260
|
if (operator === undefined) {
|
|
285
261
|
throw new Error('Operator is required when specifying a column for orWhere()');
|
|
286
262
|
}
|
|
287
|
-
// Handle tuple operations
|
|
288
263
|
if (Array.isArray(columnOrColumns) && (operator === 'inTuple' || operator === 'globalInTuple')) {
|
|
289
|
-
// For tuple operations, we need to handle the column array specially
|
|
290
264
|
const columns = columnOrColumns;
|
|
291
265
|
this.validateFilterValue(columns, operator, value);
|
|
292
|
-
this.config = this.filtering.addCondition('OR', columns, operator, value);
|
|
266
|
+
this.config = this.filtering.addCondition('OR', columns.map(String), operator, value);
|
|
293
267
|
return this;
|
|
294
268
|
}
|
|
295
|
-
// Handle regular operations
|
|
296
269
|
const column = columnOrColumns;
|
|
297
270
|
this.validateFilterValue(column, operator, value);
|
|
298
|
-
this.config = this.filtering.addCondition('OR', column, operator, value);
|
|
271
|
+
this.config = this.filtering.addCondition('OR', String(column), operator, value);
|
|
299
272
|
return this;
|
|
300
273
|
}
|
|
301
274
|
/**
|
|
@@ -342,7 +315,8 @@ export class QueryBuilder {
|
|
|
342
315
|
* ```
|
|
343
316
|
*/
|
|
344
317
|
groupBy(columns) {
|
|
345
|
-
|
|
318
|
+
const normalized = Array.isArray(columns) ? columns.map(String) : String(columns);
|
|
319
|
+
this.config = this.modifiers.addGroupBy(normalized);
|
|
346
320
|
return this;
|
|
347
321
|
}
|
|
348
322
|
limit(count) {
|
|
@@ -364,7 +338,7 @@ export class QueryBuilder {
|
|
|
364
338
|
* ```
|
|
365
339
|
*/
|
|
366
340
|
orderBy(column, direction = 'ASC') {
|
|
367
|
-
this.config = this.modifiers.addOrderBy(column, direction);
|
|
341
|
+
this.config = this.modifiers.addOrderBy(String(column), direction);
|
|
368
342
|
return this;
|
|
369
343
|
}
|
|
370
344
|
/**
|
|
@@ -391,24 +365,24 @@ export class QueryBuilder {
|
|
|
391
365
|
return this.where(column, 'between', [min, max]);
|
|
392
366
|
}
|
|
393
367
|
innerJoin(table, leftColumn, rightColumn, alias) {
|
|
394
|
-
|
|
395
|
-
newBuilder.config = this.joins.addJoin('INNER', table, leftColumn, rightColumn, alias);
|
|
396
|
-
return newBuilder;
|
|
368
|
+
return this.applyJoin('INNER', table, leftColumn, rightColumn, alias);
|
|
397
369
|
}
|
|
398
370
|
leftJoin(table, leftColumn, rightColumn, alias) {
|
|
399
|
-
|
|
400
|
-
newBuilder.config = this.joins.addJoin('LEFT', table, leftColumn, rightColumn, alias);
|
|
401
|
-
return newBuilder;
|
|
371
|
+
return this.applyJoin('LEFT', table, leftColumn, rightColumn, alias);
|
|
402
372
|
}
|
|
403
373
|
rightJoin(table, leftColumn, rightColumn, alias) {
|
|
404
|
-
|
|
405
|
-
newBuilder.config = this.joins.addJoin('RIGHT', table, leftColumn, rightColumn, alias);
|
|
406
|
-
return newBuilder;
|
|
374
|
+
return this.applyJoin('RIGHT', table, leftColumn, rightColumn, alias);
|
|
407
375
|
}
|
|
408
376
|
fullJoin(table, leftColumn, rightColumn, alias) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
377
|
+
return this.applyJoin('FULL', table, leftColumn, rightColumn, alias);
|
|
378
|
+
}
|
|
379
|
+
applyJoin(type, table, leftColumn, rightColumn, alias) {
|
|
380
|
+
const nextState = {
|
|
381
|
+
...this.state,
|
|
382
|
+
aliases: alias ? { ...this.state.aliases, [alias]: table } : this.state.aliases
|
|
383
|
+
};
|
|
384
|
+
const nextConfig = this.joins.addJoin(type, table, String(leftColumn), rightColumn, alias);
|
|
385
|
+
return this.fork(nextState, nextConfig);
|
|
412
386
|
}
|
|
413
387
|
// Make config accessible to features
|
|
414
388
|
getConfig() {
|
|
@@ -471,10 +445,15 @@ export function createQueryBuilder(config) {
|
|
|
471
445
|
ClickHouseConnection.initialize(config);
|
|
472
446
|
return {
|
|
473
447
|
table(tableName) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
448
|
+
const state = {
|
|
449
|
+
schema: {},
|
|
450
|
+
tables: tableName,
|
|
451
|
+
output: {},
|
|
452
|
+
baseTable: tableName,
|
|
453
|
+
base: {},
|
|
454
|
+
aliases: {}
|
|
455
|
+
};
|
|
456
|
+
return new QueryBuilder(tableName, state);
|
|
478
457
|
}
|
|
479
458
|
};
|
|
480
459
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const initializeTestConnection: () => Promise<{
|
|
2
|
-
table<TableName extends never>(tableName: TableName): import("../../query-builder.js").
|
|
2
|
+
table<TableName extends never>(tableName: TableName): import("../../query-builder.js").SelectQB<import("../../types/builder-state.js").SchemaDefinition<unknown>, TableName, import("../../../index.js").TableRecord<import("../../types/builder-state.js").SchemaDefinition<unknown>[TableName]>, TableName>;
|
|
3
3
|
}>;
|
|
4
4
|
export declare const ensureConnectionInitialized: () => import("@clickhouse/client").ClickHouseClient | import("@clickhouse/client-web").ClickHouseClient;
|
|
5
5
|
export declare const isDockerAvailable: () => Promise<boolean>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SelectQB } from '../query-builder.js';
|
|
2
|
+
import type { TableRecord } from '../../types/schema.js';
|
|
2
3
|
export type TestTableSchema = {
|
|
3
4
|
id: 'Int32';
|
|
4
5
|
name: 'String';
|
|
@@ -38,6 +39,6 @@ export interface TestSchema {
|
|
|
38
39
|
users: UsersSchema;
|
|
39
40
|
}
|
|
40
41
|
export declare const TEST_SCHEMAS: TestSchema;
|
|
41
|
-
export declare function setupUsersBuilder():
|
|
42
|
-
export declare function setupTestBuilder():
|
|
42
|
+
export declare function setupUsersBuilder(): SelectQB<TestSchema, 'users', TableRecord<TestSchema['users']>, 'users'>;
|
|
43
|
+
export declare function setupTestBuilder(): SelectQB<TestSchema, 'test_table', TableRecord<TestSchema['test_table']>, 'test_table'>;
|
|
43
44
|
//# sourceMappingURL=test-utils.d.ts.map
|