@hypequery/clickhouse 1.4.0-beta.2 → 1.5.0

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.
Files changed (127) hide show
  1. package/README.md +65 -2
  2. package/dist/cli/bin.js +65 -23
  3. package/dist/cli/generate-types.js +42 -4
  4. package/dist/core/cache/cache-manager.d.ts +4 -0
  5. package/dist/core/cache/cache-manager.d.ts.map +1 -0
  6. package/dist/core/cache/cache-manager.js +176 -0
  7. package/dist/core/cache/controller.d.ts +15 -0
  8. package/dist/core/cache/controller.d.ts.map +1 -0
  9. package/dist/core/cache/controller.js +58 -0
  10. package/dist/core/cache/key.d.ts +11 -0
  11. package/dist/core/cache/key.d.ts.map +1 -0
  12. package/dist/core/cache/key.js +26 -0
  13. package/dist/core/cache/providers/memory-lru.d.ts +31 -0
  14. package/dist/core/cache/providers/memory-lru.d.ts.map +1 -0
  15. package/dist/core/cache/providers/memory-lru.js +156 -0
  16. package/dist/core/cache/providers/noop.d.ts +7 -0
  17. package/dist/core/cache/providers/noop.d.ts.map +1 -0
  18. package/dist/core/cache/providers/noop.js +11 -0
  19. package/dist/core/cache/runtime-context.d.ts +30 -0
  20. package/dist/core/cache/runtime-context.d.ts.map +1 -0
  21. package/dist/core/cache/runtime-context.js +58 -0
  22. package/dist/core/cache/serialization.d.ts +6 -0
  23. package/dist/core/cache/serialization.d.ts.map +1 -0
  24. package/dist/core/cache/serialization.js +166 -0
  25. package/dist/core/cache/types.d.ts +52 -0
  26. package/dist/core/cache/types.d.ts.map +1 -0
  27. package/dist/core/cache/types.js +1 -0
  28. package/dist/core/cache/utils.d.ts +9 -0
  29. package/dist/core/cache/utils.d.ts.map +1 -0
  30. package/dist/core/cache/utils.js +30 -0
  31. package/dist/core/connection.d.ts.map +1 -1
  32. package/dist/core/connection.js +4 -3
  33. package/dist/core/cross-filter.d.ts +12 -9
  34. package/dist/core/cross-filter.d.ts.map +1 -1
  35. package/dist/core/cross-filter.js +9 -6
  36. package/dist/core/env/auto-client.browser.d.ts +3 -0
  37. package/dist/core/env/auto-client.browser.d.ts.map +1 -0
  38. package/dist/core/env/auto-client.browser.js +3 -0
  39. package/dist/core/env/auto-client.d.ts +9 -0
  40. package/dist/core/env/auto-client.d.ts.map +1 -0
  41. package/dist/core/env/auto-client.js +21 -0
  42. package/dist/core/features/aggregations.d.ts +18 -22
  43. package/dist/core/features/aggregations.d.ts.map +1 -1
  44. package/dist/core/features/aggregations.js +6 -6
  45. package/dist/core/features/analytics.d.ts +15 -19
  46. package/dist/core/features/analytics.d.ts.map +1 -1
  47. package/dist/core/features/analytics.js +2 -2
  48. package/dist/core/features/cross-filtering.d.ts +4 -24
  49. package/dist/core/features/cross-filtering.d.ts.map +1 -1
  50. package/dist/core/features/cross-filtering.js +0 -34
  51. package/dist/core/features/executor.d.ts +11 -9
  52. package/dist/core/features/executor.d.ts.map +1 -1
  53. package/dist/core/features/executor.js +14 -5
  54. package/dist/core/features/filtering.d.ts +32 -28
  55. package/dist/core/features/filtering.d.ts.map +1 -1
  56. package/dist/core/features/filtering.js +27 -26
  57. package/dist/core/features/joins.d.ts +7 -10
  58. package/dist/core/features/joins.d.ts.map +1 -1
  59. package/dist/core/features/query-modifiers.d.ts +18 -21
  60. package/dist/core/features/query-modifiers.d.ts.map +1 -1
  61. package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
  62. package/dist/core/formatters/sql-formatter.js +6 -0
  63. package/dist/core/join-relationships.d.ts +2 -1
  64. package/dist/core/join-relationships.d.ts.map +1 -1
  65. package/dist/core/query-builder.d.ts +67 -84
  66. package/dist/core/query-builder.d.ts.map +1 -1
  67. package/dist/core/query-builder.js +165 -135
  68. package/dist/core/tests/integration/setup.d.ts +9 -1
  69. package/dist/core/tests/integration/setup.d.ts.map +1 -1
  70. package/dist/core/tests/integration/setup.js +56 -22
  71. package/dist/core/tests/integration/test-config.d.ts +2 -2
  72. package/dist/core/tests/integration/test-config.d.ts.map +1 -1
  73. package/dist/core/tests/integration/test-config.js +3 -4
  74. package/dist/core/tests/integration/test-data.json +190 -0
  75. package/dist/core/tests/test-utils.d.ts +18 -3
  76. package/dist/core/tests/test-utils.d.ts.map +1 -1
  77. package/dist/core/tests/test-utils.js +37 -10
  78. package/dist/core/types/builder-state.d.ts +25 -0
  79. package/dist/core/types/builder-state.d.ts.map +1 -0
  80. package/dist/core/types/builder-state.js +1 -0
  81. package/dist/core/types/select-types.d.ts +32 -0
  82. package/dist/core/types/select-types.d.ts.map +1 -0
  83. package/dist/core/types/select-types.js +1 -0
  84. package/dist/core/types/type-helpers.d.ts +5 -0
  85. package/dist/core/types/type-helpers.d.ts.map +1 -0
  86. package/dist/core/types/type-helpers.js +1 -0
  87. package/dist/core/utils/logger.d.ts +6 -0
  88. package/dist/core/utils/logger.d.ts.map +1 -1
  89. package/dist/core/utils/logger.js +7 -2
  90. package/dist/core/utils/predicate-builder.d.ts +29 -0
  91. package/dist/core/utils/predicate-builder.d.ts.map +1 -0
  92. package/dist/core/utils/predicate-builder.js +92 -0
  93. package/dist/core/utils/sql-expressions.d.ts +24 -10
  94. package/dist/core/utils/sql-expressions.d.ts.map +1 -1
  95. package/dist/core/utils/sql-expressions.js +7 -30
  96. package/dist/core/utils/streaming-helpers.d.ts +2 -0
  97. package/dist/core/utils/streaming-helpers.d.ts.map +1 -0
  98. package/dist/core/utils/streaming-helpers.js +137 -0
  99. package/dist/core/validators/filter-validator.d.ts +2 -1
  100. package/dist/core/validators/filter-validator.d.ts.map +1 -1
  101. package/dist/core/validators/value-validator.d.ts +2 -1
  102. package/dist/core/validators/value-validator.d.ts.map +1 -1
  103. package/dist/index.d.ts +11 -4
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +4 -0
  106. package/dist/types/base.d.ts +10 -37
  107. package/dist/types/base.d.ts.map +1 -1
  108. package/dist/types/clickhouse-types.d.ts +9 -4
  109. package/dist/types/clickhouse-types.d.ts.map +1 -1
  110. package/dist/types/filters.d.ts +1 -1
  111. package/dist/types/filters.d.ts.map +1 -1
  112. package/dist/types/index.d.ts +2 -0
  113. package/dist/types/index.d.ts.map +1 -1
  114. package/dist/types/index.js +2 -0
  115. package/dist/types/schema.d.ts +19 -0
  116. package/dist/types/schema.d.ts.map +1 -0
  117. package/dist/types/schema.js +1 -0
  118. package/package.json +21 -23
  119. package/dist/core/features/pagination.d.ts +0 -23
  120. package/dist/core/features/pagination.d.ts.map +0 -1
  121. package/dist/core/features/pagination.js +0 -192
  122. package/dist/core/tests/integration/pagination-test-tbc.d.ts +0 -2
  123. package/dist/core/tests/integration/pagination-test-tbc.d.ts.map +0 -1
  124. package/dist/core/tests/integration/pagination-test-tbc.js +0 -189
  125. package/dist/core/tests/integration/test-initializer.d.ts +0 -7
  126. package/dist/core/tests/integration/test-initializer.d.ts.map +0 -1
  127. package/dist/core/tests/integration/test-initializer.js +0 -32
package/package.json CHANGED
@@ -1,14 +1,23 @@
1
1
  {
2
2
  "name": "@hypequery/clickhouse",
3
- "version": "1.4.0-beta.2",
3
+ "version": "1.5.0",
4
4
  "description": "ClickHouse typescript query builder",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
+ "browser": {
9
+ "./dist/core/env/auto-client.js": "./dist/core/env/auto-client.browser.js"
10
+ },
8
11
  "exports": {
9
12
  ".": {
10
13
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./cli": {
18
+ "types": "./dist/cli/index.d.ts",
19
+ "import": "./dist/cli/index.js",
20
+ "require": "./dist/cli/index.js"
12
21
  }
13
22
  },
14
23
  "license": "Apache-2.0",
@@ -20,15 +29,14 @@
20
29
  "verify-build": "node scripts/verify-build.js",
21
30
  "diagnose-ci": "node scripts/diagnose-ci.js",
22
31
  "dev": "tsc --watch",
23
- "test": "npm run test:unit",
24
- "test:unit": "jest --testPathIgnorePatterns='integration' --config=jest.config.cjs",
32
+ "test": "npm run test:types && npm run test:unit",
33
+ "test:unit": "vitest run --config vitest.config.ts",
34
+ "test:types": "tsc --project tsconfig.type-tests.json",
25
35
  "test:integration": "node scripts/run-integration-tests.js",
26
- "test:watch": "jest --testPathIgnorePatterns='integration' --watch --config=jest.config.cjs",
27
- "test:coverage": "jest --coverage --config=jest.config.cjs",
36
+ "test:watch": "vitest watch --config vitest.config.ts",
37
+ "test:coverage": "vitest run --coverage --config vitest.config.ts",
28
38
  "test:cli": "node scripts/test-cli-integration.js",
29
- "lint": "eslint src/**/*.ts",
30
- "semantic-release": "npx semantic-release",
31
- "release": "npx semantic-release --extends ./.releaserc.cjs --no-ci",
39
+ "lint": "eslint --ext .ts \"src/**/*.ts\"",
32
40
  "docs:api": "typedoc --options typedoc.json",
33
41
  "docs:mdx": "npm run docs:api && node scripts/process-typedoc-markdown.js"
34
42
  },
@@ -52,27 +60,17 @@
52
60
  }
53
61
  },
54
62
  "devDependencies": {
55
- "@babel/plugin-transform-modules-commonjs": "^7.26.3",
56
63
  "@clickhouse/client": "^1.11.2",
57
64
  "@clickhouse/client-common": "^1.11.2",
58
65
  "@clickhouse/client-web": "^1.11.2",
59
- "@semantic-release/changelog": "^6.0.3",
60
- "@semantic-release/commit-analyzer": "^11.1.0",
61
- "@semantic-release/git": "^10.0.1",
62
- "@semantic-release/github": "^9.2.6",
63
- "@semantic-release/npm": "^11.0.2",
64
- "@semantic-release/release-notes-generator": "^12.1.0",
65
- "@types/jest": "^29.5.11",
66
66
  "@types/node": "^18.19.80",
67
67
  "glob": "^11.0.3",
68
- "jest": "^29.7.0",
69
- "jest-esbuild": "^0.3.0",
70
- "semantic-release": "^23.0.2",
71
- "ts-jest": "^29.1.1",
72
68
  "ts-node": "^10.9.0",
73
69
  "typedoc": "^0.28.1",
74
70
  "typedoc-plugin-markdown": "^4.6.0",
75
- "typescript": "^5.7.3"
71
+ "typescript": "^5.7.3",
72
+ "@vitest/coverage-v8": "^2.1.6",
73
+ "vitest": "^2.1.6"
76
74
  },
77
75
  "ts-node": {
78
76
  "esm": true,
@@ -89,4 +87,4 @@
89
87
  "publishConfig": {
90
88
  "access": "public"
91
89
  }
92
- }
90
+ }
@@ -1,23 +0,0 @@
1
- import { QueryBuilder } from '../query-builder.js';
2
- import { ColumnType, PaginationOptions, PaginatedResult } from '../../types/index.js';
3
- export declare class PaginationFeature<Schema extends {
4
- [tableName: string]: {
5
- [columnName: string]: ColumnType;
6
- };
7
- }, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
8
- private builder;
9
- private static cursorStacks;
10
- private stackKey;
11
- constructor(builder: QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>);
12
- private get cursorStack();
13
- private set cursorStack(value);
14
- private get currentPosition();
15
- private set currentPosition(value);
16
- private encodeCursor;
17
- private decodeCursor;
18
- paginate(options: PaginationOptions<T>): Promise<PaginatedResult<T>>;
19
- private generateCursor;
20
- firstPage(pageSize: number): Promise<PaginatedResult<T>>;
21
- iteratePages(pageSize: number): AsyncGenerator<PaginatedResult<T>>;
22
- }
23
- //# sourceMappingURL=pagination.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/core/features/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAyB,MAAM,sBAAsB,CAAC;AAE7G,qBAAa,iBAAiB,CAC5B,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;IAKD,OAAO,CAAC,OAAO;IAH3B,OAAO,CAAC,MAAM,CAAC,YAAY,CAAiE;IAC5F,OAAO,CAAC,QAAQ,CAAS;gBAEL,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAQxF,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,WAAW,QAGtB;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,KAAK,eAAe,QAG1B;IAED,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAId,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IA0I1E,OAAO,CAAC,cAAc;IAmBhB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAIvD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CAkB1E"}
@@ -1,192 +0,0 @@
1
- export class PaginationFeature {
2
- builder;
3
- static cursorStacks = new Map();
4
- stackKey;
5
- constructor(builder) {
6
- this.builder = builder;
7
- // Create a unique key for this pagination instance based on the table and sort
8
- this.stackKey = builder.getTableName();
9
- if (!PaginationFeature.cursorStacks.has(this.stackKey)) {
10
- PaginationFeature.cursorStacks.set(this.stackKey, { stack: [], position: -1 });
11
- }
12
- }
13
- get cursorStack() {
14
- return PaginationFeature.cursorStacks.get(this.stackKey).stack;
15
- }
16
- set cursorStack(value) {
17
- const current = PaginationFeature.cursorStacks.get(this.stackKey);
18
- PaginationFeature.cursorStacks.set(this.stackKey, { ...current, stack: value });
19
- }
20
- get currentPosition() {
21
- return PaginationFeature.cursorStacks.get(this.stackKey).position;
22
- }
23
- set currentPosition(value) {
24
- const current = PaginationFeature.cursorStacks.get(this.stackKey);
25
- PaginationFeature.cursorStacks.set(this.stackKey, { ...current, position: value });
26
- }
27
- encodeCursor(values) {
28
- return Buffer.from(JSON.stringify(values)).toString('base64');
29
- }
30
- decodeCursor(cursor) {
31
- return JSON.parse(Buffer.from(cursor, 'base64').toString());
32
- }
33
- async paginate(options) {
34
- const { pageSize, after, before, orderBy = [] } = options;
35
- const requestSize = pageSize + 1;
36
- // Update cursor stack
37
- if (after) {
38
- // Moving forward: add new cursor and update position
39
- if (this.currentPosition < this.cursorStack.length - 1) {
40
- // If we're not at the end, truncate the stack
41
- this.cursorStack = this.cursorStack.slice(0, this.currentPosition + 1);
42
- }
43
- this.cursorStack = [...this.cursorStack, after];
44
- this.currentPosition = this.cursorStack.length - 1;
45
- }
46
- else if (before) {
47
- // Moving backward: find the cursor in the stack
48
- const cursorIndex = this.cursorStack.indexOf(before);
49
- if (cursorIndex === -1) {
50
- // If cursor not found in stack, add it
51
- if (this.currentPosition === this.cursorStack.length - 1) {
52
- this.cursorStack = [...this.cursorStack, before];
53
- }
54
- // Move back one position
55
- this.currentPosition = Math.max(-1, this.currentPosition - 1);
56
- }
57
- else {
58
- // Move to the previous cursor position
59
- this.currentPosition = Math.max(-1, cursorIndex - 1);
60
- }
61
- }
62
- else {
63
- // Reset for first page only if we don't have a cursor
64
- if (!this.cursorStack.length) {
65
- this.cursorStack = [];
66
- this.currentPosition = -1;
67
- }
68
- }
69
- // Apply ordering first
70
- orderBy.forEach(({ column, direction }) => {
71
- this.builder.orderBy(column, direction);
72
- });
73
- // Handle cursor-based pagination
74
- const cursor = after || before;
75
- if (cursor && orderBy && orderBy.length > 0) {
76
- const [{ column, direction }] = orderBy;
77
- const columnName = String(column);
78
- const cursorValues = this.decodeCursor(cursor);
79
- const value = cursorValues[columnName];
80
- if (before) {
81
- // For backward pagination:
82
- // If sorting DESC, we want records > cursor
83
- // If sorting ASC, we want records < cursor
84
- const operator = direction === 'DESC' ? 'gt' : 'lt';
85
- this.builder.where(columnName, operator, value);
86
- // Reverse the order for backward pagination
87
- orderBy.forEach(({ column, direction }) => {
88
- const reversedDirection = direction === 'DESC' ? 'ASC' : 'DESC';
89
- this.builder.orderBy(column, reversedDirection);
90
- });
91
- }
92
- else {
93
- // For forward pagination:
94
- // If sorting DESC, we want records < cursor
95
- // If sorting ASC, we want records > cursor
96
- const operator = direction === 'DESC' ? 'lt' : 'gt';
97
- this.builder.where(columnName, operator, value);
98
- }
99
- }
100
- this.builder.limit(requestSize);
101
- // Execute query
102
- let results = await this.builder.execute();
103
- // For backward pagination, we need to reverse the results
104
- if (before) {
105
- results = results.reverse();
106
- }
107
- // Only take pageSize records for the actual data
108
- const data = results.slice(0, pageSize);
109
- // Generate cursors
110
- const startCursor = data.length > 0 ? this.generateCursor(data[0], orderBy) : '';
111
- const endCursor = data.length > 0 ? this.generateCursor(data[data.length - 1], orderBy) : '';
112
- // Determine if there are more pages
113
- const hasMore = results.length > pageSize;
114
- // For the first page
115
- if (!cursor) {
116
- return {
117
- data,
118
- pageInfo: {
119
- hasNextPage: hasMore,
120
- hasPreviousPage: data.length > 0 && this.currentPosition > 0, // Only true if we have results AND previous cursors
121
- startCursor,
122
- endCursor,
123
- totalCount: 0,
124
- totalPages: 0,
125
- pageSize
126
- }
127
- };
128
- }
129
- // For pages accessed via 'before' cursor
130
- if (before) {
131
- return {
132
- data,
133
- pageInfo: {
134
- hasNextPage: true, // We can always go forward when we've gone back
135
- hasPreviousPage: data.length > 0 && (this.currentPosition >= 0 || hasMore), // Need results to have previous page
136
- startCursor,
137
- endCursor,
138
- totalCount: 0,
139
- totalPages: 0,
140
- pageSize
141
- }
142
- };
143
- }
144
- // For pages accessed via 'after' cursor
145
- return {
146
- data,
147
- pageInfo: {
148
- hasNextPage: hasMore, // Can go forward if we have more results
149
- hasPreviousPage: data.length > 0, // Need results to have previous page
150
- startCursor,
151
- endCursor,
152
- totalCount: 0,
153
- totalPages: 0,
154
- pageSize
155
- }
156
- };
157
- }
158
- generateCursor(record, orderBy) {
159
- const cursorData = {};
160
- if (orderBy) {
161
- orderBy.forEach(({ column }) => {
162
- const columnName = String(column);
163
- cursorData[columnName] = record[columnName];
164
- });
165
- }
166
- else {
167
- // Use primary key or first column as default
168
- const [firstColumn] = Object.keys(record);
169
- if (firstColumn) {
170
- cursorData[firstColumn] = record[firstColumn];
171
- }
172
- }
173
- return this.encodeCursor(cursorData);
174
- }
175
- async firstPage(pageSize) {
176
- return this.paginate({ pageSize });
177
- }
178
- async *iteratePages(pageSize) {
179
- let currentCursor;
180
- while (true) {
181
- const result = await this.paginate({
182
- pageSize,
183
- after: currentCursor
184
- });
185
- yield result;
186
- if (!result.pageInfo.hasNextPage) {
187
- break;
188
- }
189
- currentCursor = result.pageInfo.endCursor;
190
- }
191
- }
192
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=pagination-test-tbc.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pagination-test-tbc.d.ts","sourceRoot":"","sources":["../../../../src/core/tests/integration/pagination-test-tbc.ts"],"names":[],"mappings":""}
@@ -1,189 +0,0 @@
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 {};
@@ -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.js';
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
- });