@hypequery/clickhouse 0.2.1 → 0.2.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/dist/cli/bin.js +128 -36
- package/dist/cli/generate-types.js +101 -12
- package/dist/core/connection.d.ts +145 -0
- package/dist/core/connection.d.ts.map +1 -1
- package/dist/core/connection.js +75 -0
- package/dist/core/cross-filter.d.ts +85 -0
- package/dist/core/features/aggregations.d.ts +102 -0
- package/dist/core/features/analytics.d.ts +66 -0
- package/dist/core/features/executor.d.ts +19 -0
- package/dist/core/features/filtering.d.ts +29 -0
- package/dist/core/features/joins.d.ts +29 -0
- package/dist/core/features/pagination.d.ts +23 -0
- package/dist/core/features/query-modifiers.d.ts +119 -0
- package/dist/core/formatters/sql-formatter.d.ts +9 -0
- package/dist/core/join-relationships.d.ts +50 -0
- package/dist/core/query-builder.d.ts +197 -0
- package/dist/core/tests/index.d.ts +2 -0
- package/dist/core/tests/integration/setup.d.ts +40 -0
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/integration/setup.js +279 -237
- package/dist/core/tests/integration/test-initializer.d.ts +7 -0
- package/dist/core/tests/integration/test-initializer.d.ts.map +1 -0
- package/dist/core/tests/integration/test-initializer.js +32 -0
- package/dist/core/tests/test-utils.d.ts +30 -0
- package/dist/core/utils/logger.d.ts +37 -0
- package/dist/core/utils/sql-expressions.d.ts +59 -0
- package/dist/core/utils.d.ts +3 -0
- package/dist/core/validators/filter-validator.d.ts +8 -0
- package/dist/core/validators/value-validator.d.ts +6 -0
- package/dist/formatters/index.d.ts +1 -0
- package/dist/index.d.ts +10 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -2
- package/dist/types/base.d.ts +76 -0
- package/dist/types/clickhouse-types.d.ts +13 -0
- package/dist/types/filters.d.ts +37 -0
- package/dist/types/index.d.ts +3 -0
- package/package.json +15 -8
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { CrossFilter } from './cross-filter';
|
|
2
|
+
import { ColumnType, FilterOperator, OrderDirection, TableColumn, AggregationType, QueryConfig, OperatorValueMap, InferColumnType, PaginationOptions, PaginatedResult } from '../types';
|
|
3
|
+
import { ClickHouseSettings } from '@clickhouse/client-web';
|
|
4
|
+
import { SQLFormatter } from './formatters/sql-formatter';
|
|
5
|
+
import { JoinRelationships, JoinPathOptions } from './join-relationships';
|
|
6
|
+
import { SqlExpression } from './utils/sql-expressions';
|
|
7
|
+
/**
|
|
8
|
+
* A type-safe query builder for ClickHouse databases.
|
|
9
|
+
* @template Schema - The full database schema
|
|
10
|
+
* @template T - The schema type of the current table
|
|
11
|
+
* @template HasSelect - Whether a SELECT clause has been applied
|
|
12
|
+
* @template Aggregations - The type of any aggregation functions applied
|
|
13
|
+
*/
|
|
14
|
+
export declare class QueryBuilder<Schema extends {
|
|
15
|
+
[tableName: string]: {
|
|
16
|
+
[columnName: string]: ColumnType;
|
|
17
|
+
};
|
|
18
|
+
}, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
|
|
19
|
+
private static relationships;
|
|
20
|
+
private config;
|
|
21
|
+
private tableName;
|
|
22
|
+
private schema;
|
|
23
|
+
private originalSchema;
|
|
24
|
+
private formatter;
|
|
25
|
+
private aggregations;
|
|
26
|
+
private joins;
|
|
27
|
+
private filtering;
|
|
28
|
+
private analytics;
|
|
29
|
+
private executor;
|
|
30
|
+
private modifiers;
|
|
31
|
+
private pagination;
|
|
32
|
+
constructor(tableName: string, schema: {
|
|
33
|
+
name: string;
|
|
34
|
+
columns: T;
|
|
35
|
+
}, originalSchema: Schema);
|
|
36
|
+
debug(): this;
|
|
37
|
+
private clone;
|
|
38
|
+
withCTE(alias: string, subquery: QueryBuilder<any, any> | string): this;
|
|
39
|
+
/**
|
|
40
|
+
* Groups results by a time interval using a specified ClickHouse function.
|
|
41
|
+
*
|
|
42
|
+
* @param column - The column containing the date or timestamp.
|
|
43
|
+
* @param interval - The interval value. For example, "1 day" or "15 minute".
|
|
44
|
+
* This is only used when the method is 'toStartOfInterval'.
|
|
45
|
+
* @param method - The time bucketing function to use.
|
|
46
|
+
* Defaults to 'toStartOfInterval'.
|
|
47
|
+
* Other valid values include 'toStartOfMinute', 'toStartOfHour',
|
|
48
|
+
* 'toStartOfDay', 'toStartOfWeek', 'toStartOfMonth', 'toStartOfQuarter', and 'toStartOfYear'.
|
|
49
|
+
* @returns The current QueryBuilder instance.
|
|
50
|
+
*/
|
|
51
|
+
groupByTimeInterval(column: keyof T | TableColumn<Schema>, interval: string, method?: 'toStartOfInterval' | 'toStartOfMinute' | 'toStartOfHour' | 'toStartOfDay' | 'toStartOfWeek' | 'toStartOfMonth' | 'toStartOfQuarter' | 'toStartOfYear'): this;
|
|
52
|
+
raw(sql: string): this;
|
|
53
|
+
settings(opts: ClickHouseSettings): this;
|
|
54
|
+
/**
|
|
55
|
+
* Applies a set of cross filters to the current query.
|
|
56
|
+
* All filter conditions from the provided CrossFilter are added to the query.
|
|
57
|
+
* @param crossFilter - An instance of CrossFilter containing shared filter conditions.
|
|
58
|
+
* @returns The current QueryBuilder instance.
|
|
59
|
+
*/
|
|
60
|
+
applyCrossFilters(crossFilter: CrossFilter<Schema, keyof Schema>): this;
|
|
61
|
+
/**
|
|
62
|
+
* Selects specific columns from the table.
|
|
63
|
+
* @template K - The keys/columns to select
|
|
64
|
+
* @param {K[]} columns - Array of column names to select
|
|
65
|
+
* @returns {QueryBuilder} A new QueryBuilder instance with updated types
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* builder.select(['id', 'name'])
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
select<K extends keyof T | TableColumn<Schema> | SqlExpression>(columns: K[]): QueryBuilder<Schema, {
|
|
72
|
+
[P in Extract<K, keyof T | TableColumn<Schema>> as P extends `${string}.${infer C}` ? C : P]: P extends keyof T ? (T[P] extends "String" ? string : T[P] extends "Date" ? Date : T[P] extends "Float64" | "Int32" | "Int64" ? number : never) : string;
|
|
73
|
+
}, true, Aggregations, OriginalT>;
|
|
74
|
+
sum<Column extends keyof OriginalT, Alias extends string = `${Column & string}_sum`>(column: Column, alias?: Alias): QueryBuilder<Schema, AggregationType<T, Aggregations, Column, Alias, 'sum', HasSelect>, true, {}, OriginalT>;
|
|
75
|
+
count<Column extends keyof OriginalT, Alias extends string = `${Column & string}_count`>(column: Column, alias?: Alias): QueryBuilder<Schema, AggregationType<T, Aggregations, Column, Alias, 'count', HasSelect>, true, {}, OriginalT>;
|
|
76
|
+
avg<Column extends keyof OriginalT, Alias extends string = `${Column & string}_avg`>(column: Column, alias?: Alias): QueryBuilder<Schema, AggregationType<T, Aggregations, Column, Alias, 'avg', HasSelect>, true, {}, OriginalT>;
|
|
77
|
+
min<Column extends keyof OriginalT, Alias extends string = `${Column & string}_min`>(column: Column, alias?: Alias): QueryBuilder<Schema, AggregationType<T, Aggregations, Column, Alias, 'min', HasSelect>, true, {}, OriginalT>;
|
|
78
|
+
max<Column extends keyof OriginalT, Alias extends string = `${Column & string}_max`>(column: Column, alias?: Alias): QueryBuilder<Schema, AggregationType<T, Aggregations, Column, Alias, 'max', HasSelect>, true, {}, OriginalT>;
|
|
79
|
+
getTableName(): string;
|
|
80
|
+
getFormatter(): SQLFormatter;
|
|
81
|
+
toSQL(): string;
|
|
82
|
+
toSQLWithParams(): {
|
|
83
|
+
sql: string;
|
|
84
|
+
parameters: any[];
|
|
85
|
+
};
|
|
86
|
+
execute(): Promise<T[]>;
|
|
87
|
+
stream(): Promise<ReadableStream<T[]>>;
|
|
88
|
+
/**
|
|
89
|
+
* Processes each row in a stream with the provided callback function
|
|
90
|
+
* @param callback Function to call for each row in the stream
|
|
91
|
+
*/
|
|
92
|
+
streamForEach<R = void>(callback: (row: T) => R | Promise<R>): Promise<void>;
|
|
93
|
+
private validateFilterValue;
|
|
94
|
+
/**
|
|
95
|
+
* Adds a WHERE clause to filter results.
|
|
96
|
+
* @template K - The column key type
|
|
97
|
+
* @param {K} column - The column to filter on
|
|
98
|
+
* @param {FilterOperator} operator - The comparison operator
|
|
99
|
+
* @param {any} value - The value to compare against
|
|
100
|
+
* @returns {this} The current QueryBuilder instance
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* builder.where('age', 'gt', 18)
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
where<K extends keyof OriginalT | TableColumn<Schema>, Op extends keyof OperatorValueMap<any>>(column: K, operator: Op, value: K extends keyof OriginalT ? OperatorValueMap<OriginalT[K] extends ColumnType ? InferColumnType<OriginalT[K]> : never>[Op] : any): this;
|
|
107
|
+
orWhere<K extends keyof OriginalT | TableColumn<Schema>>(column: K, operator: FilterOperator, value: any): this;
|
|
108
|
+
/**
|
|
109
|
+
* Adds a GROUP BY clause.
|
|
110
|
+
* @param {keyof T | Array<keyof T>} columns - Column(s) to group by
|
|
111
|
+
* @returns {this} The current QueryBuilder instance
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* builder.groupBy(['category', 'status'])
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
groupBy(columns: (keyof T | TableColumn<Schema>) | Array<keyof T | TableColumn<Schema>>): this;
|
|
118
|
+
limit(count: number): this;
|
|
119
|
+
offset(count: number): this;
|
|
120
|
+
/**
|
|
121
|
+
* Adds an ORDER BY clause.
|
|
122
|
+
* @param {keyof T} column - The column to order by
|
|
123
|
+
* @param {OrderDirection} [direction='ASC'] - The sort direction
|
|
124
|
+
* @returns {this} The current QueryBuilder instance
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* builder.orderBy('created_at', 'DESC')
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
orderBy<K extends keyof T | TableColumn<Schema>>(column: K, direction?: OrderDirection): this;
|
|
131
|
+
/**
|
|
132
|
+
* Adds a HAVING clause for filtering grouped results.
|
|
133
|
+
* @param {string} condition - The HAVING condition
|
|
134
|
+
* @returns {this} The current QueryBuilder instance
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* builder.having('COUNT(*) > 5')
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
having(condition: string, parameters?: any[]): this;
|
|
141
|
+
distinct(): this;
|
|
142
|
+
whereBetween<K extends keyof OriginalT>(column: K, [min, max]: [
|
|
143
|
+
OriginalT[K] extends ColumnType ? InferColumnType<OriginalT[K]> : never,
|
|
144
|
+
OriginalT[K] extends ColumnType ? InferColumnType<OriginalT[K]> : never
|
|
145
|
+
]): this;
|
|
146
|
+
innerJoin<TableName extends keyof Schema>(table: TableName, leftColumn: keyof OriginalT, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: string): QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>;
|
|
147
|
+
leftJoin<TableName extends keyof Schema>(table: TableName, leftColumn: keyof OriginalT, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: string): QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>;
|
|
148
|
+
rightJoin<TableName extends keyof Schema>(table: TableName, leftColumn: keyof OriginalT, rightColumn: `${TableName & string}.${keyof Schema[TableName] & string}`, alias?: string): QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>;
|
|
149
|
+
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>;
|
|
150
|
+
getConfig(): QueryConfig<T, Schema>;
|
|
151
|
+
/**
|
|
152
|
+
* Paginates the query results using cursor-based pagination
|
|
153
|
+
*/
|
|
154
|
+
paginate(options: PaginationOptions<T>): Promise<PaginatedResult<T>>;
|
|
155
|
+
/**
|
|
156
|
+
* Gets the first page of results
|
|
157
|
+
*/
|
|
158
|
+
firstPage(pageSize: number): Promise<PaginatedResult<T>>;
|
|
159
|
+
/**
|
|
160
|
+
* Returns an async iterator that yields all pages
|
|
161
|
+
*/
|
|
162
|
+
iteratePages(pageSize: number): AsyncGenerator<PaginatedResult<T>>;
|
|
163
|
+
static setJoinRelationships<S extends {
|
|
164
|
+
[tableName: string]: {
|
|
165
|
+
[columnName: string]: ColumnType;
|
|
166
|
+
};
|
|
167
|
+
}>(relationships: JoinRelationships<S>): void;
|
|
168
|
+
/**
|
|
169
|
+
* Apply a predefined join relationship
|
|
170
|
+
*/
|
|
171
|
+
withRelation(name: string, options?: JoinPathOptions): this;
|
|
172
|
+
}
|
|
173
|
+
export declare function createQueryBuilder<Schema extends {
|
|
174
|
+
[K in keyof Schema]: {
|
|
175
|
+
[columnName: string]: ColumnType;
|
|
176
|
+
};
|
|
177
|
+
}>(config: {
|
|
178
|
+
host: string;
|
|
179
|
+
username?: string;
|
|
180
|
+
password?: string;
|
|
181
|
+
database?: string;
|
|
182
|
+
http_headers?: Record<string, string>;
|
|
183
|
+
request_timeout?: number;
|
|
184
|
+
compression?: {
|
|
185
|
+
response?: boolean;
|
|
186
|
+
request?: boolean;
|
|
187
|
+
};
|
|
188
|
+
application?: string;
|
|
189
|
+
keep_alive?: {
|
|
190
|
+
enabled: boolean;
|
|
191
|
+
};
|
|
192
|
+
log?: any;
|
|
193
|
+
clickhouse_settings?: ClickHouseSettings;
|
|
194
|
+
}): {
|
|
195
|
+
table<TableName extends keyof Schema>(tableName: TableName): QueryBuilder<Schema, Schema[TableName], false, {}>;
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=query-builder.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const initializeTestConnection: () => Promise<{
|
|
2
|
+
table<TableName extends never>(tableName: TableName): import("../../query-builder").QueryBuilder<{}, {}[TableName], false, {}, {}[TableName]>;
|
|
3
|
+
}>;
|
|
4
|
+
export declare const ensureConnectionInitialized: () => import("@clickhouse/client-web/dist/client").WebClickHouseClient;
|
|
5
|
+
export declare const isDockerAvailable: () => Promise<boolean>;
|
|
6
|
+
export declare const isDockerComposeAvailable: () => Promise<boolean>;
|
|
7
|
+
export declare const isContainerRunning: (containerName: string) => Promise<boolean>;
|
|
8
|
+
export declare const isClickHouseReady: () => Promise<boolean>;
|
|
9
|
+
export declare const startClickHouseContainer: () => Promise<void>;
|
|
10
|
+
export declare const waitForClickHouse: (maxAttempts?: number, retryInterval?: number) => Promise<void>;
|
|
11
|
+
export declare const stopClickHouseContainer: () => Promise<void>;
|
|
12
|
+
export interface TestSchema {
|
|
13
|
+
test_table: Array<{
|
|
14
|
+
id: number;
|
|
15
|
+
name: string;
|
|
16
|
+
category: string;
|
|
17
|
+
price: number;
|
|
18
|
+
created_at: string;
|
|
19
|
+
is_active: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
users: Array<{
|
|
22
|
+
id: number;
|
|
23
|
+
user_name: string;
|
|
24
|
+
email: string;
|
|
25
|
+
status: string;
|
|
26
|
+
created_at: string;
|
|
27
|
+
}>;
|
|
28
|
+
orders: Array<{
|
|
29
|
+
id: number;
|
|
30
|
+
user_id: number;
|
|
31
|
+
product_id: number;
|
|
32
|
+
quantity: number;
|
|
33
|
+
total: number;
|
|
34
|
+
status: string;
|
|
35
|
+
created_at: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export declare const TEST_DATA: TestSchema;
|
|
39
|
+
export declare const setupTestDatabase: () => Promise<void>;
|
|
40
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/setup.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,wBAAwB;;EAyBpC,CAAC;AAGF,eAAO,MAAM,2BAA2B,wEAevC,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,OAAO,CAOzD,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,OAAO,CAahE,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,OAAO,CAO/E,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,OAAO,CAQzD,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CAwC7D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAC5B,oBAAgB,EAChB,sBAAoB,KACnB,OAAO,CAAC,IAAI,CAad,CAAC;AAGF,eAAO,MAAM,uBAAuB,QAAa,OAAO,CAAC,IAAI,CA0B5D,CAAC;AAGF,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAGD,eAAO,MAAM,SAAS,EAAE,UAoBvB,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAuFtD,CAAC"}
|