@hypequery/clickhouse 0.2.2 → 0.2.3
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/core/connection.d.ts +0 -9
- package/dist/core/connection.d.ts.map +1 -1
- package/dist/core/connection.js +0 -17
- package/dist/core/features/cross-filtering.d.ts +31 -0
- package/dist/core/features/cross-filtering.d.ts.map +1 -0
- package/dist/core/features/cross-filtering.js +123 -0
- package/dist/core/features/filtering.d.ts +66 -0
- package/dist/core/features/filtering.d.ts.map +1 -1
- package/dist/core/features/filtering.js +59 -1
- package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
- package/dist/core/formatters/sql-formatter.js +24 -5
- package/dist/core/query-builder.d.ts +26 -1
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +38 -6
- package/dist/core/tests/integration/pagination-test-tbc.d.ts +2 -0
- package/dist/core/tests/integration/pagination-test-tbc.d.ts.map +1 -0
- package/dist/core/tests/integration/pagination-test-tbc.js +189 -0
- package/dist/core/tests/integration/setup.d.ts +2 -2
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/integration/setup.js +0 -1
- package/dist/core/tests/integration/test-config.d.ts +15 -0
- package/dist/core/tests/integration/test-config.d.ts.map +1 -0
- package/dist/core/tests/integration/test-config.js +15 -0
- package/dist/core/utils/logger.js +2 -2
- package/dist/types/base.d.ts +1 -0
- package/dist/types/base.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/core/tests/integration/test-initializer.d.ts +0 -7
- package/dist/core/tests/integration/test-initializer.d.ts.map +0 -1
- package/dist/core/tests/integration/test-initializer.js +0 -32
|
@@ -113,15 +113,6 @@ export declare class ClickHouseConnection {
|
|
|
113
113
|
* password: 'password',
|
|
114
114
|
* database: 'my_database'
|
|
115
115
|
* });
|
|
116
|
-
*
|
|
117
|
-
* // For a ClickHouse Cloud instance
|
|
118
|
-
* ClickHouseConnection.initialize({
|
|
119
|
-
* host: 'https://your-instance.clickhouse.cloud:8443',
|
|
120
|
-
* username: 'default',
|
|
121
|
-
* password: 'your-password',
|
|
122
|
-
* database: 'my_database',
|
|
123
|
-
* secure: true
|
|
124
|
-
* });
|
|
125
116
|
* ```
|
|
126
117
|
*/
|
|
127
118
|
static initialize(config: ClickHouseConnectionOptions): typeof ClickHouseConnection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IAEF;;OAEG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV;;OAEG;IACH,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IAEF;;OAEG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV;;OAEG;IACH,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,oBAAoB;IAsBnF;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,SAAS,IAAI,UAAU,CAAC,OAAO,YAAY,CAAC;CAMpD"}
|
package/dist/core/connection.js
CHANGED
|
@@ -40,15 +40,6 @@ export class ClickHouseConnection {
|
|
|
40
40
|
* password: 'password',
|
|
41
41
|
* database: 'my_database'
|
|
42
42
|
* });
|
|
43
|
-
*
|
|
44
|
-
* // For a ClickHouse Cloud instance
|
|
45
|
-
* ClickHouseConnection.initialize({
|
|
46
|
-
* host: 'https://your-instance.clickhouse.cloud:8443',
|
|
47
|
-
* username: 'default',
|
|
48
|
-
* password: 'your-password',
|
|
49
|
-
* database: 'my_database',
|
|
50
|
-
* secure: true
|
|
51
|
-
* });
|
|
52
43
|
* ```
|
|
53
44
|
*/
|
|
54
45
|
static initialize(config) {
|
|
@@ -59,14 +50,6 @@ export class ClickHouseConnection {
|
|
|
59
50
|
password: config.password,
|
|
60
51
|
database: config.database,
|
|
61
52
|
};
|
|
62
|
-
// Automatically enable secure mode for HTTPS URLs
|
|
63
|
-
const isSecure = config.secure || config.host.startsWith('https://');
|
|
64
|
-
if (isSecure) {
|
|
65
|
-
clientConfig.tls = {
|
|
66
|
-
ca_cert: undefined, // Use system CA certificates
|
|
67
|
-
verify: true,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
53
|
// Add the extended options if provided
|
|
71
54
|
if (config.http_headers)
|
|
72
55
|
clientConfig.http_headers = config.http_headers;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { QueryBuilder } from '../query-builder';
|
|
2
|
+
import { CrossFilter } from '../cross-filter';
|
|
3
|
+
import { ColumnType } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Feature for handling cross-filter operations on queries
|
|
6
|
+
*/
|
|
7
|
+
export declare class CrossFilteringFeature<Schema extends {
|
|
8
|
+
[tableName: string]: {
|
|
9
|
+
[columnName: string]: ColumnType;
|
|
10
|
+
};
|
|
11
|
+
}, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
|
|
12
|
+
private builder;
|
|
13
|
+
constructor(builder: QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>);
|
|
14
|
+
/**
|
|
15
|
+
* Applies a set of cross filters to the query
|
|
16
|
+
* @param crossFilter - An instance of CrossFilter containing shared filter conditions
|
|
17
|
+
* @returns Updated query config
|
|
18
|
+
*/
|
|
19
|
+
applyCrossFilters(crossFilter: CrossFilter<Schema, keyof Schema>): import("../../types").QueryConfig<T, Schema>;
|
|
20
|
+
/**
|
|
21
|
+
* Apply AND conditions - each condition is applied with WHERE
|
|
22
|
+
*/
|
|
23
|
+
private applyAndConditions;
|
|
24
|
+
/**
|
|
25
|
+
* Apply direct OR conditions without adding extra conjunctions
|
|
26
|
+
* @param conditions The conditions to apply
|
|
27
|
+
* @param builder The builder to apply conditions to, defaults to this.builder
|
|
28
|
+
*/
|
|
29
|
+
private applyOrConditions;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=cross-filtering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-filtering.d.ts","sourceRoot":"","sources":["../../../src/core/features/cross-filtering.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAe,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAwB,UAAU,EAAe,MAAM,aAAa,CAAC;AAgB5E;;GAEG;AACH,qBAAa,qBAAqB,CAChC,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF;;;;OAIG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;IAsBhE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAqD1B"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
//@ts-
|
|
2
|
+
/**
|
|
3
|
+
* Type guard to check if an object is a FilterConditionInput
|
|
4
|
+
*/
|
|
5
|
+
function isFilterCondition(obj) {
|
|
6
|
+
return obj && 'column' in obj && 'operator' in obj && 'value' in obj;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Type guard to check if an object is a FilterGroup
|
|
10
|
+
*/
|
|
11
|
+
function isFilterGroup(obj) {
|
|
12
|
+
return obj && 'conditions' in obj && 'operator' in obj;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Feature for handling cross-filter operations on queries
|
|
16
|
+
*/
|
|
17
|
+
export class CrossFilteringFeature {
|
|
18
|
+
constructor(builder) {
|
|
19
|
+
this.builder = builder;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Applies a set of cross filters to the query
|
|
23
|
+
* @param crossFilter - An instance of CrossFilter containing shared filter conditions
|
|
24
|
+
* @returns Updated query config
|
|
25
|
+
*/
|
|
26
|
+
applyCrossFilters(crossFilter) {
|
|
27
|
+
const filterGroup = crossFilter.getConditions();
|
|
28
|
+
if (filterGroup.conditions.length === 0) {
|
|
29
|
+
return this.builder.getConfig();
|
|
30
|
+
}
|
|
31
|
+
// Apply conditions based on filter group operator
|
|
32
|
+
if (filterGroup.operator === 'AND') {
|
|
33
|
+
// For AND groups, apply each condition directly
|
|
34
|
+
this.applyAndConditions(filterGroup.conditions);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// For OR groups, special handling to ensure proper parentheses
|
|
38
|
+
// We use whereGroup instead of orWhereGroup here since this is a top-level group
|
|
39
|
+
this.builder.whereGroup(builder => {
|
|
40
|
+
this.applyOrConditions(filterGroup.conditions, builder);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return this.builder.getConfig();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Apply AND conditions - each condition is applied with WHERE
|
|
47
|
+
*/
|
|
48
|
+
applyAndConditions(conditions) {
|
|
49
|
+
conditions.forEach(condition => {
|
|
50
|
+
if (isFilterCondition(condition)) {
|
|
51
|
+
// Simple condition - apply with WHERE
|
|
52
|
+
this.builder.where(condition.column, condition.operator, condition.value);
|
|
53
|
+
}
|
|
54
|
+
else if (isFilterGroup(condition)) {
|
|
55
|
+
// Nested group
|
|
56
|
+
if (condition.operator === 'AND') {
|
|
57
|
+
// AND subgroup - apply all conditions
|
|
58
|
+
this.builder.whereGroup(builder => {
|
|
59
|
+
const feature = new CrossFilteringFeature(builder);
|
|
60
|
+
feature.applyAndConditions(condition.conditions);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// OR subgroup within AND - needs special parentheses handling
|
|
65
|
+
this.builder.whereGroup(builder => {
|
|
66
|
+
const feature = new CrossFilteringFeature(builder);
|
|
67
|
+
feature.applyOrConditions(condition.conditions, builder);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply direct OR conditions without adding extra conjunctions
|
|
75
|
+
* @param conditions The conditions to apply
|
|
76
|
+
* @param builder The builder to apply conditions to, defaults to this.builder
|
|
77
|
+
*/
|
|
78
|
+
applyOrConditions(conditions, builder = this.builder) {
|
|
79
|
+
if (conditions.length === 0)
|
|
80
|
+
return;
|
|
81
|
+
// Handle first condition
|
|
82
|
+
const firstCondition = conditions[0];
|
|
83
|
+
if (isFilterCondition(firstCondition)) {
|
|
84
|
+
builder.where(firstCondition.column, firstCondition.operator, firstCondition.value);
|
|
85
|
+
}
|
|
86
|
+
else if (isFilterGroup(firstCondition)) {
|
|
87
|
+
// Handle nested group
|
|
88
|
+
if (firstCondition.operator === 'AND') {
|
|
89
|
+
builder.whereGroup(innerBuilder => {
|
|
90
|
+
const feature = new CrossFilteringFeature(innerBuilder);
|
|
91
|
+
feature.applyAndConditions(firstCondition.conditions);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
builder.whereGroup(innerBuilder => {
|
|
96
|
+
const feature = new CrossFilteringFeature(innerBuilder);
|
|
97
|
+
feature.applyOrConditions(firstCondition.conditions, innerBuilder);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Handle remaining conditions
|
|
102
|
+
for (let i = 1; i < conditions.length; i++) {
|
|
103
|
+
const condition = conditions[i];
|
|
104
|
+
if (isFilterCondition(condition)) {
|
|
105
|
+
builder.orWhere(condition.column, condition.operator, condition.value);
|
|
106
|
+
}
|
|
107
|
+
else if (isFilterGroup(condition)) {
|
|
108
|
+
if (condition.operator === 'AND') {
|
|
109
|
+
builder.orWhereGroup(innerBuilder => {
|
|
110
|
+
const feature = new CrossFilteringFeature(innerBuilder);
|
|
111
|
+
feature.applyAndConditions(condition.conditions);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
builder.orWhereGroup(innerBuilder => {
|
|
116
|
+
const feature = new CrossFilteringFeature(innerBuilder);
|
|
117
|
+
feature.applyOrConditions(condition.conditions, innerBuilder);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -25,5 +25,71 @@ export declare class FilteringFeature<Schema extends {
|
|
|
25
25
|
unionQueries?: string[];
|
|
26
26
|
settings?: string;
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Adds a group-start marker to start a parenthesized group of conditions with AND conjunction
|
|
30
|
+
* @returns The updated query config
|
|
31
|
+
*/
|
|
32
|
+
startWhereGroup(): {
|
|
33
|
+
where: import("../../types").WhereCondition[];
|
|
34
|
+
select?: (string | keyof T)[] | undefined;
|
|
35
|
+
groupBy?: string[];
|
|
36
|
+
having?: string[];
|
|
37
|
+
limit?: number;
|
|
38
|
+
offset?: number;
|
|
39
|
+
distinct?: boolean;
|
|
40
|
+
orderBy?: {
|
|
41
|
+
column: TableColumn<Schema> | keyof T;
|
|
42
|
+
direction: import("../../types").OrderDirection;
|
|
43
|
+
}[] | undefined;
|
|
44
|
+
joins?: import("../../types").JoinClause[];
|
|
45
|
+
parameters?: any[];
|
|
46
|
+
ctes?: string[];
|
|
47
|
+
unionQueries?: string[];
|
|
48
|
+
settings?: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Adds a group-start marker to start a parenthesized group of conditions with OR conjunction
|
|
52
|
+
* @returns The updated query config
|
|
53
|
+
*/
|
|
54
|
+
startOrWhereGroup(): {
|
|
55
|
+
where: import("../../types").WhereCondition[];
|
|
56
|
+
select?: (string | keyof T)[] | undefined;
|
|
57
|
+
groupBy?: string[];
|
|
58
|
+
having?: string[];
|
|
59
|
+
limit?: number;
|
|
60
|
+
offset?: number;
|
|
61
|
+
distinct?: boolean;
|
|
62
|
+
orderBy?: {
|
|
63
|
+
column: TableColumn<Schema> | keyof T;
|
|
64
|
+
direction: import("../../types").OrderDirection;
|
|
65
|
+
}[] | undefined;
|
|
66
|
+
joins?: import("../../types").JoinClause[];
|
|
67
|
+
parameters?: any[];
|
|
68
|
+
ctes?: string[];
|
|
69
|
+
unionQueries?: string[];
|
|
70
|
+
settings?: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Adds a group-end marker to end a parenthesized group of conditions
|
|
74
|
+
* @returns The updated query config
|
|
75
|
+
*/
|
|
76
|
+
endWhereGroup(): {
|
|
77
|
+
where: import("../../types").WhereCondition[];
|
|
78
|
+
select?: (string | keyof T)[] | undefined;
|
|
79
|
+
groupBy?: string[];
|
|
80
|
+
having?: string[];
|
|
81
|
+
limit?: number;
|
|
82
|
+
offset?: number;
|
|
83
|
+
distinct?: boolean;
|
|
84
|
+
orderBy?: {
|
|
85
|
+
column: TableColumn<Schema> | keyof T;
|
|
86
|
+
direction: import("../../types").OrderDirection;
|
|
87
|
+
}[] | undefined;
|
|
88
|
+
joins?: import("../../types").JoinClause[];
|
|
89
|
+
parameters?: any[];
|
|
90
|
+
ctes?: string[];
|
|
91
|
+
unionQueries?: string[];
|
|
92
|
+
settings?: string;
|
|
93
|
+
};
|
|
28
94
|
}
|
|
29
95
|
//# sourceMappingURL=filtering.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../src/core/features/filtering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtE,qBAAa,gBAAgB,CAC3B,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF,YAAY,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,EAC1D,WAAW,EAAE,KAAK,GAAG,IAAI,EACzB,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,GAAG;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../../src/core/features/filtering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtE,qBAAa,gBAAgB,CAC3B,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF,YAAY,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,EAC1D,WAAW,EAAE,KAAK,GAAG,IAAI,EACzB,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,GAAG;;;;;;;;;;;;;;;;;;IA+BZ;;;OAGG;IACH,eAAe;;;;;;;;;;;;;;;;;;IAkBf;;;OAGG;IACH,iBAAiB;;;;;;;;;;;;;;;;;;IAkBjB;;;OAGG;IACH,aAAa;;;;;;;;;;;;;;;;;;CAiBd"}
|
|
@@ -10,7 +10,8 @@ export class FilteringFeature {
|
|
|
10
10
|
column: String(column),
|
|
11
11
|
operator,
|
|
12
12
|
value,
|
|
13
|
-
conjunction
|
|
13
|
+
conjunction,
|
|
14
|
+
type: 'condition'
|
|
14
15
|
});
|
|
15
16
|
if (operator === 'in' || operator === 'notIn') {
|
|
16
17
|
parameters.push(...value);
|
|
@@ -27,4 +28,61 @@ export class FilteringFeature {
|
|
|
27
28
|
parameters
|
|
28
29
|
};
|
|
29
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Adds a group-start marker to start a parenthesized group of conditions with AND conjunction
|
|
33
|
+
* @returns The updated query config
|
|
34
|
+
*/
|
|
35
|
+
startWhereGroup() {
|
|
36
|
+
const config = this.builder.getConfig();
|
|
37
|
+
const where = config.where || [];
|
|
38
|
+
where.push({
|
|
39
|
+
column: '', // Not used for group markers
|
|
40
|
+
operator: 'eq', // Not used for group markers
|
|
41
|
+
value: null, // Not used for group markers
|
|
42
|
+
conjunction: 'AND',
|
|
43
|
+
type: 'group-start'
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
...config,
|
|
47
|
+
where
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Adds a group-start marker to start a parenthesized group of conditions with OR conjunction
|
|
52
|
+
* @returns The updated query config
|
|
53
|
+
*/
|
|
54
|
+
startOrWhereGroup() {
|
|
55
|
+
const config = this.builder.getConfig();
|
|
56
|
+
const where = config.where || [];
|
|
57
|
+
where.push({
|
|
58
|
+
column: '', // Not used for group markers
|
|
59
|
+
operator: 'eq', // Not used for group markers
|
|
60
|
+
value: null, // Not used for group markers
|
|
61
|
+
conjunction: 'OR',
|
|
62
|
+
type: 'group-start'
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
...config,
|
|
66
|
+
where
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Adds a group-end marker to end a parenthesized group of conditions
|
|
71
|
+
* @returns The updated query config
|
|
72
|
+
*/
|
|
73
|
+
endWhereGroup() {
|
|
74
|
+
const config = this.builder.getConfig();
|
|
75
|
+
const where = config.where || [];
|
|
76
|
+
where.push({
|
|
77
|
+
column: '', // Not used for group markers
|
|
78
|
+
operator: 'eq', // Not used for group markers
|
|
79
|
+
value: null, // Not used for group markers
|
|
80
|
+
conjunction: 'AND', // Not relevant for end markers
|
|
81
|
+
type: 'group-end'
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
...config,
|
|
85
|
+
where
|
|
86
|
+
};
|
|
87
|
+
}
|
|
30
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-formatter.d.ts","sourceRoot":"","sources":["../../../src/core/formatters/sql-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAE1D,qBAAa,YAAY;IACvB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;IAMnD,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;IASpD,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;
|
|
1
|
+
{"version":3,"file":"sql-formatter.d.ts","sourceRoot":"","sources":["../../../src/core/formatters/sql-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAE1D,qBAAa,YAAY;IACvB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;IAMnD,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;IASpD,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;IAuDlD,OAAO,CAAC,cAAc;IActB,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;CAUnD"}
|
|
@@ -17,10 +17,25 @@ export class SQLFormatter {
|
|
|
17
17
|
formatWhere(config) {
|
|
18
18
|
if (!config.where?.length)
|
|
19
19
|
return '';
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
let afterGroupStart = false; // Track whether we're immediately after a group-start
|
|
21
|
+
// First pass - generate the SQL fragments for each condition
|
|
22
|
+
const fragments = config.where.map((condition, index) => {
|
|
23
|
+
// Handle special group markers
|
|
24
|
+
if (condition.type === 'group-start') {
|
|
25
|
+
const prefix = index === 0 ? '' : ` ${condition.conjunction} `;
|
|
26
|
+
afterGroupStart = true; // Mark that the next condition follows a group-start
|
|
27
|
+
return `${prefix}(`.trim();
|
|
28
|
+
}
|
|
29
|
+
if (condition.type === 'group-end') {
|
|
30
|
+
afterGroupStart = false; // Reset the flag after group-end
|
|
31
|
+
return ')';
|
|
32
|
+
}
|
|
33
|
+
// Normal conditions
|
|
22
34
|
const { column, operator, value, conjunction } = condition;
|
|
23
|
-
|
|
35
|
+
// Don't add conjunction if it's the first condition or right after a group-start
|
|
36
|
+
const prefix = index === 0 || afterGroupStart ? '' : ` ${conjunction} `;
|
|
37
|
+
// Reset the afterGroupStart flag
|
|
38
|
+
afterGroupStart = false;
|
|
24
39
|
if (operator === 'in' || operator === 'notIn') {
|
|
25
40
|
if (!Array.isArray(value)) {
|
|
26
41
|
throw new Error(`Expected an array for ${operator} operator, but got ${typeof value}`);
|
|
@@ -40,8 +55,12 @@ export class SQLFormatter {
|
|
|
40
55
|
else {
|
|
41
56
|
return `${prefix}${column} ${this.getSqlOperator(operator)} ?`.trim();
|
|
42
57
|
}
|
|
43
|
-
})
|
|
44
|
-
|
|
58
|
+
});
|
|
59
|
+
// Join fragments and then remove extra spaces around parentheses
|
|
60
|
+
let result = fragments.join(' ');
|
|
61
|
+
// Replace "( " with "(" and " )" with ")"
|
|
62
|
+
result = result.replace(/\(\s+/g, '(').replace(/\s+\)/g, ')');
|
|
63
|
+
return result;
|
|
45
64
|
}
|
|
46
65
|
getSqlOperator(operator) {
|
|
47
66
|
switch (operator) {
|
|
@@ -29,12 +29,13 @@ export declare class QueryBuilder<Schema extends {
|
|
|
29
29
|
private executor;
|
|
30
30
|
private modifiers;
|
|
31
31
|
private pagination;
|
|
32
|
+
private crossFiltering;
|
|
32
33
|
constructor(tableName: string, schema: {
|
|
33
34
|
name: string;
|
|
34
35
|
columns: T;
|
|
35
36
|
}, originalSchema: Schema);
|
|
36
37
|
debug(): this;
|
|
37
|
-
|
|
38
|
+
clone(): QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>;
|
|
38
39
|
withCTE(alias: string, subquery: QueryBuilder<any, any> | string): this;
|
|
39
40
|
/**
|
|
40
41
|
* Groups results by a time interval using a specified ClickHouse function.
|
|
@@ -105,6 +106,30 @@ export declare class QueryBuilder<Schema extends {
|
|
|
105
106
|
*/
|
|
106
107
|
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
108
|
orWhere<K extends keyof OriginalT | TableColumn<Schema>>(column: K, operator: FilterOperator, value: any): this;
|
|
109
|
+
/**
|
|
110
|
+
* Creates a parenthesized group of WHERE conditions joined with AND/OR operators.
|
|
111
|
+
* @param {Function} callback - Function that builds the conditions within the group
|
|
112
|
+
* @returns {this} The current QueryBuilder instance
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* builder.whereGroup(qb => {
|
|
116
|
+
* qb.where('status', 'eq', 'active').orWhere('status', 'eq', 'pending');
|
|
117
|
+
* })
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
whereGroup(callback: (builder: this) => void): this;
|
|
121
|
+
/**
|
|
122
|
+
* Creates a parenthesized group of WHERE conditions joined with OR operator.
|
|
123
|
+
* @param {Function} callback - Function that builds the conditions within the group
|
|
124
|
+
* @returns {this} The current QueryBuilder instance
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* builder.orWhereGroup(qb => {
|
|
128
|
+
* qb.where('status', 'eq', 'active').orWhere('status', 'eq', 'pending');
|
|
129
|
+
* })
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
orWhereGroup(callback: (builder: this) => void): this;
|
|
108
133
|
/**
|
|
109
134
|
* Adds a GROUP BY clause.
|
|
110
135
|
* @param {keyof T | Array<keyof T>} columns - Column(s) to group by
|
|
@@ -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,gBAAgB,CAAC;AAC7C,OAAO,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,eAAe,
|
|
1
|
+
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../src/core/query-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { ExecutorFeature } from './features/executor';
|
|
|
8
8
|
import { QueryModifiersFeature } from './features/query-modifiers';
|
|
9
9
|
import { FilterValidator } from './validators/filter-validator';
|
|
10
10
|
import { PaginationFeature } from './features/pagination';
|
|
11
|
+
import { CrossFilteringFeature } from './features/cross-filtering';
|
|
11
12
|
/**
|
|
12
13
|
* A type-safe query builder for ClickHouse databases.
|
|
13
14
|
* @template Schema - The full database schema
|
|
@@ -29,6 +30,7 @@ export class QueryBuilder {
|
|
|
29
30
|
this.executor = new ExecutorFeature(this);
|
|
30
31
|
this.modifiers = new QueryModifiersFeature(this);
|
|
31
32
|
this.pagination = new PaginationFeature(this);
|
|
33
|
+
this.crossFiltering = new CrossFilteringFeature(this);
|
|
32
34
|
}
|
|
33
35
|
debug() {
|
|
34
36
|
console.log('Current Type:', {
|
|
@@ -49,6 +51,7 @@ export class QueryBuilder {
|
|
|
49
51
|
newBuilder.executor = new ExecutorFeature(newBuilder);
|
|
50
52
|
newBuilder.modifiers = new QueryModifiersFeature(newBuilder);
|
|
51
53
|
newBuilder.pagination = new PaginationFeature(newBuilder);
|
|
54
|
+
newBuilder.crossFiltering = new CrossFilteringFeature(newBuilder);
|
|
52
55
|
return newBuilder;
|
|
53
56
|
}
|
|
54
57
|
// --- Analytics Helper: Add a CTE.
|
|
@@ -92,12 +95,7 @@ export class QueryBuilder {
|
|
|
92
95
|
* @returns The current QueryBuilder instance.
|
|
93
96
|
*/
|
|
94
97
|
applyCrossFilters(crossFilter) {
|
|
95
|
-
|
|
96
|
-
filterGroup.conditions.forEach((item) => {
|
|
97
|
-
if ('column' in item) {
|
|
98
|
-
this.where(item.column, item.operator, item.value);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
98
|
+
this.config = this.crossFiltering.applyCrossFilters(crossFilter);
|
|
101
99
|
return this;
|
|
102
100
|
}
|
|
103
101
|
/**
|
|
@@ -226,6 +224,40 @@ export class QueryBuilder {
|
|
|
226
224
|
this.config = this.filtering.addCondition('OR', column, operator, value);
|
|
227
225
|
return this;
|
|
228
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Creates a parenthesized group of WHERE conditions joined with AND/OR operators.
|
|
229
|
+
* @param {Function} callback - Function that builds the conditions within the group
|
|
230
|
+
* @returns {this} The current QueryBuilder instance
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* builder.whereGroup(qb => {
|
|
234
|
+
* qb.where('status', 'eq', 'active').orWhere('status', 'eq', 'pending');
|
|
235
|
+
* })
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
whereGroup(callback) {
|
|
239
|
+
this.config = this.filtering.startWhereGroup();
|
|
240
|
+
callback(this);
|
|
241
|
+
this.config = this.filtering.endWhereGroup();
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Creates a parenthesized group of WHERE conditions joined with OR operator.
|
|
246
|
+
* @param {Function} callback - Function that builds the conditions within the group
|
|
247
|
+
* @returns {this} The current QueryBuilder instance
|
|
248
|
+
* @example
|
|
249
|
+
* ```ts
|
|
250
|
+
* builder.orWhereGroup(qb => {
|
|
251
|
+
* qb.where('status', 'eq', 'active').orWhere('status', 'eq', 'pending');
|
|
252
|
+
* })
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
orWhereGroup(callback) {
|
|
256
|
+
this.config = this.filtering.startOrWhereGroup();
|
|
257
|
+
callback(this);
|
|
258
|
+
this.config = this.filtering.endWhereGroup();
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
229
261
|
/**
|
|
230
262
|
* Adds a GROUP BY clause.
|
|
231
263
|
* @param {keyof T | Array<keyof T>} columns - Column(s) to group by
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-test-tbc.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/pagination-test-tbc.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Skipping tests becuase this feature is not ready
|
|
2
|
+
const SKIP_INTEGRATION_TESTS = true; // process.env.SKIP_INTEGRATION_TESTS === 'true' || process.env.CI === 'true';
|
|
3
|
+
describe('Integration Tests - Pagination', () => {
|
|
4
|
+
// Only run these tests if not skipped
|
|
5
|
+
// Removing until this feature is ready
|
|
6
|
+
// (SKIP_INTEGRATION_TESTS ? describe.skip : describe)('ClickHouse Integration', () => {
|
|
7
|
+
// let db: Awaited<ReturnType<typeof initializeTestConnection>>;
|
|
8
|
+
// beforeAll(async () => {
|
|
9
|
+
// if (!SKIP_INTEGRATION_TESTS) {
|
|
10
|
+
// try {
|
|
11
|
+
// // Start ClickHouse container
|
|
12
|
+
// startClickHouseContainer();
|
|
13
|
+
// // Initialize connection
|
|
14
|
+
// db = await initializeTestConnection();
|
|
15
|
+
// // Set up test database
|
|
16
|
+
// await setupTestDatabase();
|
|
17
|
+
// } catch (error) {
|
|
18
|
+
// console.error('Failed to set up integration tests:', error);
|
|
19
|
+
// throw error;
|
|
20
|
+
// }
|
|
21
|
+
// }
|
|
22
|
+
// }, 60000); // Allow up to 60 seconds for setup
|
|
23
|
+
// afterAll(async () => {
|
|
24
|
+
// if (!SKIP_INTEGRATION_TESTS) {
|
|
25
|
+
// try {
|
|
26
|
+
// // Wait for any pending operations to complete
|
|
27
|
+
// console.log('Starting test cleanup...');
|
|
28
|
+
// await new Promise(resolve => setTimeout(resolve, 1000));
|
|
29
|
+
// // Close any active client connections to prevent lingering queries
|
|
30
|
+
// if (db) {
|
|
31
|
+
// try {
|
|
32
|
+
// const client = ClickHouseConnection.getClient();
|
|
33
|
+
// console.log('Closing ClickHouse client connection...');
|
|
34
|
+
// // Wait for any in-flight queries to complete
|
|
35
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
36
|
+
// // Ensure we're not running any more queries
|
|
37
|
+
// await client.close().catch(err => {
|
|
38
|
+
// console.error('Error closing ClickHouse client:', err);
|
|
39
|
+
// });
|
|
40
|
+
// console.log('ClickHouse client closed successfully');
|
|
41
|
+
// } catch (closeError) {
|
|
42
|
+
// console.error('Error during client close:', closeError);
|
|
43
|
+
// }
|
|
44
|
+
// }
|
|
45
|
+
// // Then stop the container
|
|
46
|
+
// console.log('Stopping ClickHouse container...');
|
|
47
|
+
// await stopClickHouseContainer();
|
|
48
|
+
// console.log('Cleanup completed');
|
|
49
|
+
// // Make sure all async operations have a chance to complete
|
|
50
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
51
|
+
// } catch (error) {
|
|
52
|
+
// console.error('Error during test cleanup:', error);
|
|
53
|
+
// }
|
|
54
|
+
// }
|
|
55
|
+
// }, 15000); // Allow up to 15 seconds for teardown
|
|
56
|
+
// test('should paginate results with cursor-based pagination', async () => {
|
|
57
|
+
// // Get first page
|
|
58
|
+
// const firstPage = await db.table('test_table')
|
|
59
|
+
// .orderBy('id', 'ASC')
|
|
60
|
+
// .paginate({
|
|
61
|
+
// pageSize: 2,
|
|
62
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
63
|
+
// });
|
|
64
|
+
// expect(firstPage.data).toHaveLength(2);
|
|
65
|
+
// expect(firstPage.pageInfo.hasNextPage).toBe(true);
|
|
66
|
+
// expect(firstPage.pageInfo.hasPreviousPage).toBe(false);
|
|
67
|
+
// expect(firstPage.pageInfo.startCursor).toBeTruthy();
|
|
68
|
+
// expect(firstPage.pageInfo.endCursor).toBeTruthy();
|
|
69
|
+
// expect(firstPage.data[0].id).toBe(1);
|
|
70
|
+
// expect(firstPage.data[1].id).toBe(2);
|
|
71
|
+
// // Get second page using the cursor
|
|
72
|
+
// const secondPage = await db.table('test_table')
|
|
73
|
+
// .orderBy('id', 'ASC')
|
|
74
|
+
// .paginate({
|
|
75
|
+
// pageSize: 2,
|
|
76
|
+
// after: firstPage.pageInfo.endCursor,
|
|
77
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
78
|
+
// });
|
|
79
|
+
// expect(secondPage.data).toHaveLength(2);
|
|
80
|
+
// expect(secondPage.pageInfo.hasNextPage).toBe(true);
|
|
81
|
+
// expect(secondPage.pageInfo.hasPreviousPage).toBe(true);
|
|
82
|
+
// expect(secondPage.data[0].id).toBe(3);
|
|
83
|
+
// expect(secondPage.data[1].id).toBe(4);
|
|
84
|
+
// // Get third page using the cursor
|
|
85
|
+
// const thirdPage = await db.table('test_table')
|
|
86
|
+
// .orderBy('id', 'ASC')
|
|
87
|
+
// .paginate({
|
|
88
|
+
// pageSize: 2,
|
|
89
|
+
// after: secondPage.pageInfo.endCursor,
|
|
90
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
91
|
+
// });
|
|
92
|
+
// expect(thirdPage.data).toHaveLength(1); // Only one record left
|
|
93
|
+
// expect(thirdPage.pageInfo.hasNextPage).toBe(false);
|
|
94
|
+
// expect(thirdPage.pageInfo.hasPreviousPage).toBe(true);
|
|
95
|
+
// expect(thirdPage.data[0].id).toBe(5);
|
|
96
|
+
// });
|
|
97
|
+
// test('should navigate backwards with cursor-based pagination', async () => {
|
|
98
|
+
// // Get first page
|
|
99
|
+
// const firstPage = await db.table('test_table')
|
|
100
|
+
// .orderBy('id', 'ASC')
|
|
101
|
+
// .paginate({
|
|
102
|
+
// pageSize: 2,
|
|
103
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
104
|
+
// });
|
|
105
|
+
// // Get second page
|
|
106
|
+
// const secondPage = await db.table('test_table')
|
|
107
|
+
// .orderBy('id', 'ASC')
|
|
108
|
+
// .paginate({
|
|
109
|
+
// pageSize: 2,
|
|
110
|
+
// after: firstPage.pageInfo.endCursor,
|
|
111
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
112
|
+
// });
|
|
113
|
+
// // Navigate back to first page
|
|
114
|
+
// const backToFirstPage = await db.table('test_table')
|
|
115
|
+
// .orderBy('id', 'ASC')
|
|
116
|
+
// .paginate({
|
|
117
|
+
// pageSize: 2,
|
|
118
|
+
// before: secondPage.pageInfo.startCursor,
|
|
119
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
120
|
+
// });
|
|
121
|
+
// expect(backToFirstPage.data).toHaveLength(2);
|
|
122
|
+
// expect(backToFirstPage.pageInfo.hasNextPage).toBe(true);
|
|
123
|
+
// expect(backToFirstPage.pageInfo.hasPreviousPage).toBe(false);
|
|
124
|
+
// expect(backToFirstPage.data[0].id).toBe(1);
|
|
125
|
+
// expect(backToFirstPage.data[1].id).toBe(2);
|
|
126
|
+
// });
|
|
127
|
+
// test('should handle empty results', async () => {
|
|
128
|
+
// const result = await db.table('test_table')
|
|
129
|
+
// .where('id', 'gt', 100) // No records with id > 100
|
|
130
|
+
// .paginate({
|
|
131
|
+
// pageSize: 10,
|
|
132
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
133
|
+
// });
|
|
134
|
+
// expect(result.data).toHaveLength(0);
|
|
135
|
+
// expect(result.pageInfo.hasNextPage).toBe(false);
|
|
136
|
+
// expect(result.pageInfo.hasPreviousPage).toBe(false);
|
|
137
|
+
// expect(result.pageInfo.startCursor).toBe('');
|
|
138
|
+
// expect(result.pageInfo.endCursor).toBe('');
|
|
139
|
+
// });
|
|
140
|
+
// test('should handle exactly pageSize results', async () => {
|
|
141
|
+
// const result = await db.table('test_table')
|
|
142
|
+
// .where('id', 'lte', 2) // Only 2 records
|
|
143
|
+
// .paginate({
|
|
144
|
+
// pageSize: 2,
|
|
145
|
+
// orderBy: [{ column: 'id', direction: 'ASC' }]
|
|
146
|
+
// });
|
|
147
|
+
// console.log('CHECK!!!!: ', result.pageInfo)
|
|
148
|
+
// expect(result.data).toHaveLength(2);
|
|
149
|
+
// expect(result.pageInfo.hasNextPage).toBe(false);
|
|
150
|
+
// expect(result.pageInfo.hasPreviousPage).toBe(false);
|
|
151
|
+
// });
|
|
152
|
+
// test('should iterate through all pages', async () => {
|
|
153
|
+
// const allResults: any[] = [];
|
|
154
|
+
// for await (const page of db.table('test_table')
|
|
155
|
+
// .orderBy('id', 'ASC')
|
|
156
|
+
// .iteratePages(2)) {
|
|
157
|
+
// allResults.push(...page.data);
|
|
158
|
+
// }
|
|
159
|
+
// expect(allResults).toHaveLength(TEST_DATA.test_table.length);
|
|
160
|
+
// // Check that all records were retrieved in the correct order
|
|
161
|
+
// for (let i = 0; i < allResults.length; i++) {
|
|
162
|
+
// expect(allResults[i].id).toBe(i + 1);
|
|
163
|
+
// }
|
|
164
|
+
// });
|
|
165
|
+
// test('should paginate with complex ordering', async () => {
|
|
166
|
+
// // First page ordered by price descending
|
|
167
|
+
// const firstPage = await db.table('test_table')
|
|
168
|
+
// .paginate({
|
|
169
|
+
// pageSize: 2,
|
|
170
|
+
// orderBy: [{ column: 'price', direction: 'DESC' }]
|
|
171
|
+
// });
|
|
172
|
+
// expect(firstPage.data).toHaveLength(2);
|
|
173
|
+
// // Verify ordering
|
|
174
|
+
// expect(Number(firstPage.data[0].price)).toBeGreaterThanOrEqual(Number(firstPage.data[1].price));
|
|
175
|
+
// // Get second page
|
|
176
|
+
// const secondPage = await db.table('test_table')
|
|
177
|
+
// .paginate({
|
|
178
|
+
// pageSize: 2,
|
|
179
|
+
// after: firstPage.pageInfo.endCursor,
|
|
180
|
+
// orderBy: [{ column: 'price', direction: 'DESC' }]
|
|
181
|
+
// });
|
|
182
|
+
// expect(secondPage.data).toHaveLength(2);
|
|
183
|
+
// // Verify ordering continues correctly
|
|
184
|
+
// expect(Number(firstPage.data[1].price)).toBeGreaterThanOrEqual(Number(secondPage.data[0].price));
|
|
185
|
+
// expect(Number(secondPage.data[0].price)).toBeGreaterThanOrEqual(Number(secondPage.data[1].price));
|
|
186
|
+
// });
|
|
187
|
+
// });
|
|
188
|
+
});
|
|
189
|
+
export {};
|
|
@@ -9,7 +9,7 @@ export declare const isClickHouseReady: () => Promise<boolean>;
|
|
|
9
9
|
export declare const startClickHouseContainer: () => Promise<void>;
|
|
10
10
|
export declare const waitForClickHouse: (maxAttempts?: number, retryInterval?: number) => Promise<void>;
|
|
11
11
|
export declare const stopClickHouseContainer: () => Promise<void>;
|
|
12
|
-
export interface
|
|
12
|
+
export interface TestSchemaType {
|
|
13
13
|
test_table: Array<{
|
|
14
14
|
id: number;
|
|
15
15
|
name: string;
|
|
@@ -35,6 +35,6 @@ export interface TestSchema {
|
|
|
35
35
|
created_at: string;
|
|
36
36
|
}>;
|
|
37
37
|
}
|
|
38
|
-
export declare const TEST_DATA:
|
|
38
|
+
export declare const TEST_DATA: TestSchemaType;
|
|
39
39
|
export declare const setupTestDatabase: () => Promise<void>;
|
|
40
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":"AA6CA,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,cAAc;IAC7B,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,cAoBvB,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAuFtD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized configuration for integration tests
|
|
3
|
+
* Import this in all integration test files to ensure consistent behavior
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether to skip integration tests:
|
|
7
|
+
* - Skip if SKIP_INTEGRATION_TESTS is explicitly set to 'true'
|
|
8
|
+
* - In CI environments, skip unless ENABLE_CI_INTEGRATION_TESTS is set to 'true'
|
|
9
|
+
*/
|
|
10
|
+
export declare const SKIP_INTEGRATION_TESTS: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Default timeout for test setup (in milliseconds)
|
|
13
|
+
*/
|
|
14
|
+
export declare const SETUP_TIMEOUT = 30000;
|
|
15
|
+
//# sourceMappingURL=test-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-config.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/test-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,SAEgD,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,aAAa,QAAQ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized configuration for integration tests
|
|
3
|
+
* Import this in all integration test files to ensure consistent behavior
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether to skip integration tests:
|
|
7
|
+
* - Skip if SKIP_INTEGRATION_TESTS is explicitly set to 'true'
|
|
8
|
+
* - In CI environments, skip unless ENABLE_CI_INTEGRATION_TESTS is set to 'true'
|
|
9
|
+
*/
|
|
10
|
+
export const SKIP_INTEGRATION_TESTS = process.env.SKIP_INTEGRATION_TESTS === 'true' ||
|
|
11
|
+
(process.env.CI === 'true' && process.env.ENABLE_CI_INTEGRATION_TESTS !== 'true');
|
|
12
|
+
/**
|
|
13
|
+
* Default timeout for test setup (in milliseconds)
|
|
14
|
+
*/
|
|
15
|
+
export const SETUP_TIMEOUT = 30000;
|
|
@@ -63,6 +63,8 @@ class Logger {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
logQuery(log) {
|
|
66
|
+
if (!this.enabled)
|
|
67
|
+
return;
|
|
66
68
|
if (this.onQueryLog) {
|
|
67
69
|
this.onQueryLog(log);
|
|
68
70
|
}
|
|
@@ -72,8 +74,6 @@ class Logger {
|
|
|
72
74
|
subscribers.forEach(callback => callback(log));
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
|
-
if (!this.enabled)
|
|
76
|
-
return;
|
|
77
77
|
const { query, parameters, duration, status, error, rowCount } = log;
|
|
78
78
|
const message = `Query ${status}: ${query}`;
|
|
79
79
|
const details = {
|
package/dist/types/base.d.ts
CHANGED
package/dist/types/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,MAAM;IACpC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACtC,SAAS,EAAE,cAAc,CAAC;KAC3B,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AACxE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AACrC,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;CACxE,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AAGxC,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,UAAU,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,GAAG,CAAC;IACX,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Common initialization for all integration tests
|
|
3
|
-
* Import this at the beginning of each test file to ensure consistent setup
|
|
4
|
-
*/
|
|
5
|
-
export declare const skipIntegrationTests: () => boolean;
|
|
6
|
-
export declare const initializeForTest: () => Promise<void>;
|
|
7
|
-
//# sourceMappingURL=test-initializer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-initializer.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/test-initializer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,eAAO,MAAM,oBAAoB,eAEhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAqBtD,CAAC"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Common initialization for all integration tests
|
|
3
|
-
* Import this at the beginning of each test file to ensure consistent setup
|
|
4
|
-
*/
|
|
5
|
-
import { startClickHouseContainer, waitForClickHouse, ensureConnectionInitialized, setupTestDatabase } from './setup';
|
|
6
|
-
export const skipIntegrationTests = () => {
|
|
7
|
-
return process.env.SKIP_INTEGRATION_TESTS === 'true' || process.env.CI === 'true';
|
|
8
|
-
};
|
|
9
|
-
export const initializeForTest = async () => {
|
|
10
|
-
if (skipIntegrationTests()) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
try {
|
|
14
|
-
// Initialize the connection
|
|
15
|
-
ensureConnectionInitialized();
|
|
16
|
-
// Make sure container is running
|
|
17
|
-
await startClickHouseContainer();
|
|
18
|
-
// Wait for ClickHouse to be ready
|
|
19
|
-
await waitForClickHouse();
|
|
20
|
-
// Set up the test database
|
|
21
|
-
await setupTestDatabase();
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
console.error('Failed to initialize test environment:', error);
|
|
25
|
-
throw error;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
// Automatically initialize when this module is imported
|
|
29
|
-
initializeForTest().catch(error => {
|
|
30
|
-
console.error('Test initialization failed:', error);
|
|
31
|
-
process.exit(1);
|
|
32
|
-
});
|