@hypequery/clickhouse 0.2.1 → 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.
Files changed (52) hide show
  1. package/dist/cli/bin.js +128 -36
  2. package/dist/cli/generate-types.js +101 -12
  3. package/dist/core/connection.d.ts +136 -0
  4. package/dist/core/connection.d.ts.map +1 -1
  5. package/dist/core/connection.js +58 -0
  6. package/dist/core/cross-filter.d.ts +85 -0
  7. package/dist/core/features/aggregations.d.ts +102 -0
  8. package/dist/core/features/analytics.d.ts +66 -0
  9. package/dist/core/features/cross-filtering.d.ts +31 -0
  10. package/dist/core/features/cross-filtering.d.ts.map +1 -0
  11. package/dist/core/features/cross-filtering.js +123 -0
  12. package/dist/core/features/executor.d.ts +19 -0
  13. package/dist/core/features/filtering.d.ts +95 -0
  14. package/dist/core/features/filtering.d.ts.map +1 -1
  15. package/dist/core/features/filtering.js +59 -1
  16. package/dist/core/features/joins.d.ts +29 -0
  17. package/dist/core/features/pagination.d.ts +23 -0
  18. package/dist/core/features/query-modifiers.d.ts +119 -0
  19. package/dist/core/formatters/sql-formatter.d.ts +9 -0
  20. package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
  21. package/dist/core/formatters/sql-formatter.js +24 -5
  22. package/dist/core/join-relationships.d.ts +50 -0
  23. package/dist/core/query-builder.d.ts +222 -0
  24. package/dist/core/query-builder.d.ts.map +1 -1
  25. package/dist/core/query-builder.js +38 -6
  26. package/dist/core/tests/index.d.ts +2 -0
  27. package/dist/core/tests/integration/pagination-test-tbc.d.ts +2 -0
  28. package/dist/core/tests/integration/pagination-test-tbc.d.ts.map +1 -0
  29. package/dist/core/tests/integration/pagination-test-tbc.js +189 -0
  30. package/dist/core/tests/integration/setup.d.ts +40 -0
  31. package/dist/core/tests/integration/setup.d.ts.map +1 -1
  32. package/dist/core/tests/integration/setup.js +278 -237
  33. package/dist/core/tests/integration/test-config.d.ts +15 -0
  34. package/dist/core/tests/integration/test-config.d.ts.map +1 -0
  35. package/dist/core/tests/integration/test-config.js +15 -0
  36. package/dist/core/tests/test-utils.d.ts +30 -0
  37. package/dist/core/utils/logger.d.ts +37 -0
  38. package/dist/core/utils/logger.js +2 -2
  39. package/dist/core/utils/sql-expressions.d.ts +59 -0
  40. package/dist/core/utils.d.ts +3 -0
  41. package/dist/core/validators/filter-validator.d.ts +8 -0
  42. package/dist/core/validators/value-validator.d.ts +6 -0
  43. package/dist/formatters/index.d.ts +1 -0
  44. package/dist/index.d.ts +10 -27
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +14 -2
  47. package/dist/types/base.d.ts +77 -0
  48. package/dist/types/base.d.ts.map +1 -1
  49. package/dist/types/clickhouse-types.d.ts +13 -0
  50. package/dist/types/filters.d.ts +37 -0
  51. package/dist/types/index.d.ts +3 -0
  52. package/package.json +15 -8
@@ -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 {};
@@ -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 TestSchemaType {
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: TestSchemaType;
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":"AAmBA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE;QACV,EAAE,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,EAAE,SAAS,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,QAAQ,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,KAAK,EAAE;QACL,EAAE,EAAE,OAAO,CAAC;QACZ,SAAS,EAAE,QAAQ,CAAC;QACpB,KAAK,EAAE,QAAQ,CAAC;QAChB,UAAU,EAAE,UAAU,CAAC;QACvB,MAAM,EAAE,QAAQ,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,OAAO,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,SAAS,CAAC;QACjB,MAAM,EAAE,QAAQ,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;KACxB,CAAC;IACF,QAAQ,EAAE;QACR,EAAE,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,EAAE,SAAS,CAAC;QACjB,QAAQ,EAAE,QAAQ,CAAC;QACnB,WAAW,EAAE,QAAQ,CAAC;KACvB,CAAC;CACH;AAGD,wBAAsB,wBAAwB;;GAwB7C;AAmDD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCrB,CAAC;AAGF,wBAAsB,iBAAiB,kBAuFtC;AAGD,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAGD,wBAAgB,wBAAwB,SAsDvC;AAGD,wBAAgB,uBAAuB,SAYtC"}
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"}