@hypequery/clickhouse 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -14
- package/dist/cli/generate-types.js +5 -12
- package/dist/core/adapters/clickhouse-adapter.d.ts +14 -0
- package/dist/core/adapters/clickhouse-adapter.d.ts.map +1 -0
- package/dist/core/adapters/clickhouse-adapter.js +58 -0
- package/dist/core/adapters/database-adapter.d.ts +13 -0
- package/dist/core/adapters/database-adapter.d.ts.map +1 -0
- package/dist/core/adapters/database-adapter.js +1 -0
- package/dist/core/cache/cache-manager.d.ts.map +1 -1
- package/dist/core/cache/cache-manager.js +6 -5
- package/dist/core/dialects/clickhouse-dialect.d.ts +10 -0
- package/dist/core/dialects/clickhouse-dialect.d.ts.map +1 -0
- package/dist/core/dialects/clickhouse-dialect.js +47 -0
- package/dist/core/dialects/sql-dialect.d.ts +11 -0
- package/dist/core/dialects/sql-dialect.d.ts.map +1 -0
- package/dist/core/dialects/sql-dialect.js +1 -0
- package/dist/core/features/aggregations.d.ts +5 -5
- package/dist/core/features/analytics.d.ts +804 -5
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +6 -9
- package/dist/core/features/executor.d.ts.map +1 -1
- package/dist/core/features/executor.js +26 -53
- package/dist/core/features/filtering.d.ts +5 -5
- package/dist/core/features/joins.d.ts +1 -1
- package/dist/core/features/query-modifiers.d.ts +6 -6
- package/dist/core/query-builder.d.ts +17 -6
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +25 -32
- package/dist/core/tests/integration/setup.d.ts +3 -1
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/test-utils.d.ts.map +1 -1
- package/dist/core/tests/test-utils.js +12 -2
- package/dist/core/types/select-types.d.ts +1 -1
- package/dist/core/types/select-types.d.ts.map +1 -1
- package/dist/core/utils/streaming-helpers.d.ts.map +1 -1
- package/dist/core/utils/streaming-helpers.js +8 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +3 -0
- package/dist/dataset/definition.d.ts +135 -0
- package/dist/dataset/definition.d.ts.map +1 -0
- package/dist/dataset/definition.js +265 -0
- package/dist/dataset/helpers.d.ts +136 -0
- package/dist/dataset/helpers.d.ts.map +1 -0
- package/dist/dataset/helpers.js +189 -0
- package/dist/dataset/index.d.ts +51 -0
- package/dist/dataset/index.d.ts.map +1 -0
- package/dist/dataset/index.js +59 -0
- package/dist/dataset/introspection.d.ts +133 -0
- package/dist/dataset/introspection.d.ts.map +1 -0
- package/dist/dataset/introspection.js +239 -0
- package/dist/dataset/sql-tag.d.ts +51 -0
- package/dist/dataset/sql-tag.d.ts.map +1 -0
- package/dist/dataset/sql-tag.js +86 -0
- package/dist/dataset/types.d.ts +300 -0
- package/dist/dataset/types.d.ts.map +1 -0
- package/dist/dataset/types.js +11 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -15
- package/dist/migrations/config/index.d.ts +3 -0
- package/dist/migrations/config/index.d.ts.map +1 -0
- package/dist/migrations/config/index.js +1 -0
- package/dist/migrations/config/types.d.ts +45 -0
- package/dist/migrations/config/types.d.ts.map +1 -0
- package/dist/migrations/config/types.js +28 -0
- package/dist/migrations/diff/diff.d.ts +11 -0
- package/dist/migrations/diff/diff.d.ts.map +1 -0
- package/dist/migrations/diff/diff.js +240 -0
- package/dist/migrations/diff/index.d.ts +3 -0
- package/dist/migrations/diff/index.d.ts.map +1 -0
- package/dist/migrations/diff/index.js +1 -0
- package/dist/migrations/diff/types.d.ts +74 -0
- package/dist/migrations/diff/types.d.ts.map +1 -0
- package/dist/migrations/diff/types.js +1 -0
- package/dist/migrations/schema/column.d.ts +71 -0
- package/dist/migrations/schema/column.d.ts.map +1 -0
- package/dist/migrations/schema/column.js +123 -0
- package/dist/migrations/schema/define.d.ts +24 -0
- package/dist/migrations/schema/define.d.ts.map +1 -0
- package/dist/migrations/schema/define.js +47 -0
- package/dist/migrations/schema/index.d.ts +4 -0
- package/dist/migrations/schema/index.d.ts.map +1 -0
- package/dist/migrations/schema/index.js +2 -0
- package/dist/migrations/schema/types.d.ts +74 -0
- package/dist/migrations/schema/types.d.ts.map +1 -0
- package/dist/migrations/schema/types.js +1 -0
- package/dist/migrations/snapshot/index.d.ts +3 -0
- package/dist/migrations/snapshot/index.d.ts.map +1 -0
- package/dist/migrations/snapshot/index.js +1 -0
- package/dist/migrations/snapshot/serialize.d.ts +21 -0
- package/dist/migrations/snapshot/serialize.d.ts.map +1 -0
- package/dist/migrations/snapshot/serialize.js +127 -0
- package/dist/migrations/snapshot/types.d.ts +47 -0
- package/dist/migrations/snapshot/types.d.ts.map +1 -0
- package/dist/migrations/snapshot/types.js +1 -0
- package/dist/migrations/sql/index.d.ts +4 -0
- package/dist/migrations/sql/index.d.ts.map +1 -0
- package/dist/migrations/sql/index.js +2 -0
- package/dist/migrations/sql/render.d.ts +11 -0
- package/dist/migrations/sql/render.d.ts.map +1 -0
- package/dist/migrations/sql/render.js +334 -0
- package/dist/migrations/sql/types.d.ts +48 -0
- package/dist/migrations/sql/types.d.ts.map +1 -0
- package/dist/migrations/sql/types.js +1 -0
- package/dist/migrations/sql/write.d.ts +9 -0
- package/dist/migrations/sql/write.d.ts.map +1 -0
- package/dist/migrations/sql/write.js +31 -0
- package/dist/types/base.d.ts +2 -1
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/clickhouse-types.d.ts +3 -1
- package/dist/types/clickhouse-types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@hypequery/clickhouse</h1>
|
|
3
|
-
<p>A
|
|
3
|
+
<p>A TypeScript-first query builder for ClickHouse and the foundation of the hypequery path.</p>
|
|
4
4
|
|
|
5
5
|
[](https://github.com/hypequery/hypequery/blob/main/LICENSE)
|
|
6
6
|
[](https://badge.fury.io/js/@hypequery%2Fclickhouse)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## Overview
|
|
12
12
|
|
|
13
|
-
hypequery is
|
|
13
|
+
`@hypequery/clickhouse` is the first step in the main hypequery flow. Generate types from your ClickHouse schema, build typed queries locally, then promote important queries into `query({ ... })` and `serve({ queries })` when they need to be reused across your app.
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
@@ -41,6 +41,13 @@ npm install @hypequery/clickhouse @clickhouse/client-web
|
|
|
41
41
|
|
|
42
42
|
## Quick Start
|
|
43
43
|
|
|
44
|
+
Main path:
|
|
45
|
+
|
|
46
|
+
1. Generate schema types
|
|
47
|
+
2. Create a typed `db` with `createQueryBuilder(...)`
|
|
48
|
+
3. Build and execute queries locally
|
|
49
|
+
4. Add `@hypequery/serve` later if a query needs a reusable contract or HTTP surface
|
|
50
|
+
|
|
44
51
|
### Node.js Environments
|
|
45
52
|
|
|
46
53
|
```typescript
|
|
@@ -126,18 +133,15 @@ const rows = await db
|
|
|
126
133
|
await db.cache.invalidateTags(['users']);
|
|
127
134
|
```
|
|
128
135
|
|
|
129
|
-
Use `.cache()` to attach defaults to a fluent chain, pass `execute({ cache: { ... } })` for one-off overrides, or call `db.cache.*` for manual invalidation. For a deep dive on cache modes, invalidation, advanced serialization, and bring-your-own-provider recipes (Redis/Upstash, compression, etc.), see the [Caching guide](https://hypequery.com/docs/
|
|
136
|
+
Use `.cache()` to attach defaults to a fluent chain, pass `execute({ cache: { ... } })` for one-off overrides, or call `db.cache.*` for manual invalidation. For a deep dive on cache modes, invalidation, advanced serialization, and bring-your-own-provider recipes (Redis/Upstash, compression, etc.), see the [Caching guide](https://hypequery.com/docs/caching).
|
|
130
137
|
|
|
131
138
|
## Schema Generation
|
|
132
139
|
|
|
133
|
-
|
|
140
|
+
Use the hypequery CLI to generate TypeScript types from your ClickHouse schema:
|
|
134
141
|
|
|
135
142
|
```bash
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
# Generate schema types
|
|
140
|
-
npx hypequery-generate-types --host your-clickhouse-host --database your-database
|
|
143
|
+
npm install -D @hypequery/cli
|
|
144
|
+
npx hypequery generate
|
|
141
145
|
```
|
|
142
146
|
|
|
143
147
|
This creates a `generated-schema.ts` file that you can import in your application:
|
|
@@ -278,12 +282,13 @@ hypequery follows semantic versioning and provides multiple release channels:
|
|
|
278
282
|
|
|
279
283
|
## Documentation
|
|
280
284
|
|
|
281
|
-
For detailed documentation and examples, visit
|
|
285
|
+
For detailed documentation and examples, visit the main docs flow.
|
|
282
286
|
|
|
283
|
-
- [
|
|
284
|
-
- [
|
|
285
|
-
- [
|
|
286
|
-
- [
|
|
287
|
+
- [Quick Start](https://hypequery.com/docs/quick-start)
|
|
288
|
+
- [Core Concepts](https://hypequery.com/docs/core-concepts)
|
|
289
|
+
- [Query Building](https://hypequery.com/docs/query-building/basics)
|
|
290
|
+
- [Filtering](https://hypequery.com/docs/query-building/where)
|
|
291
|
+
- [API Reference](https://hypequery.com/docs/reference/query-builder)
|
|
287
292
|
|
|
288
293
|
|
|
289
294
|
## Troubleshooting
|
|
@@ -23,7 +23,7 @@ dotenv.config();
|
|
|
23
23
|
* @param {string} type - The ClickHouse type to convert
|
|
24
24
|
* @returns {string} - The corresponding TypeScript type
|
|
25
25
|
*/
|
|
26
|
-
const clickhouseToTsType = (type) => {
|
|
26
|
+
export const clickhouseToTsType = (type) => {
|
|
27
27
|
if (type.startsWith('Array(')) {
|
|
28
28
|
const innerType = type.slice(6, -1);
|
|
29
29
|
return `Array<${clickhouseToTsType(innerType)}>`;
|
|
@@ -44,14 +44,6 @@ const clickhouseToTsType = (type) => {
|
|
|
44
44
|
const keyType = mapContent.substring(0, commaIndex).trim();
|
|
45
45
|
const valueType = mapContent.substring(commaIndex + 1).trim();
|
|
46
46
|
|
|
47
|
-
// Handle different key types
|
|
48
|
-
let keyTsType = 'string';
|
|
49
|
-
if (keyType === 'LowCardinality(String)') {
|
|
50
|
-
keyTsType = 'string';
|
|
51
|
-
} else if (keyType.includes('Int') || keyType.includes('UInt')) {
|
|
52
|
-
keyTsType = 'number';
|
|
53
|
-
}
|
|
54
|
-
|
|
55
47
|
// Handle different value types
|
|
56
48
|
let valueTsType = 'unknown';
|
|
57
49
|
if (valueType.startsWith('Array(')) {
|
|
@@ -64,7 +56,8 @@ const clickhouseToTsType = (type) => {
|
|
|
64
56
|
valueTsType = clickhouseToTsType(valueType);
|
|
65
57
|
}
|
|
66
58
|
|
|
67
|
-
|
|
59
|
+
// JSON object keys are strings even when ClickHouse map keys are numeric.
|
|
60
|
+
return `Record<string, ${valueTsType}>`;
|
|
68
61
|
}
|
|
69
62
|
return 'Record<string, unknown>';
|
|
70
63
|
}
|
|
@@ -77,11 +70,11 @@ const clickhouseToTsType = (type) => {
|
|
|
77
70
|
case 'int16':
|
|
78
71
|
case 'int32':
|
|
79
72
|
case 'uint8':
|
|
80
|
-
case 'int64':
|
|
81
73
|
case 'uint16':
|
|
82
74
|
case 'uint32':
|
|
83
|
-
case 'uint64':
|
|
84
75
|
return 'number';
|
|
76
|
+
case 'int64':
|
|
77
|
+
case 'uint64':
|
|
85
78
|
case 'uint128':
|
|
86
79
|
case 'uint256':
|
|
87
80
|
case 'int128':
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DatabaseAdapter, QueryExecutionOptions } from './database-adapter.js';
|
|
2
|
+
import type { ClickHouseConfig } from '../query-builder.js';
|
|
3
|
+
export declare class ClickHouseAdapter implements DatabaseAdapter {
|
|
4
|
+
private config;
|
|
5
|
+
readonly name = "clickhouse";
|
|
6
|
+
readonly namespace?: string;
|
|
7
|
+
private client;
|
|
8
|
+
constructor(config: ClickHouseConfig);
|
|
9
|
+
query<T>(sql: string, params?: unknown[], options?: QueryExecutionOptions): Promise<T[]>;
|
|
10
|
+
stream<T>(sql: string, params?: unknown[], options?: QueryExecutionOptions): Promise<ReadableStream<T[]>>;
|
|
11
|
+
render(sql: string, params?: unknown[]): string;
|
|
12
|
+
}
|
|
13
|
+
export declare function createClickHouseAdapter(config: ClickHouseConfig): DatabaseAdapter;
|
|
14
|
+
//# sourceMappingURL=clickhouse-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickhouse-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/clickhouse-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA2B5D,qBAAa,iBAAkB,YAAW,eAAe;IAK3C,OAAO,CAAC,MAAM;IAJ1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,MAAM,CAAmB;gBAEb,MAAM,EAAE,gBAAgB;IAKtC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAW5F,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;IAYnH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,MAAM;CAGpD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAEjF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isClientConfig } from '../query-builder.js';
|
|
2
|
+
import { substituteParameters } from '../utils.js';
|
|
3
|
+
import { createJsonEachRowStream } from '../utils/streaming-helpers.js';
|
|
4
|
+
import { getAutoClientModule } from '../env/auto-client.js';
|
|
5
|
+
function createClickHouseClient(config) {
|
|
6
|
+
if (isClientConfig(config)) {
|
|
7
|
+
return config.client;
|
|
8
|
+
}
|
|
9
|
+
const clientModule = getAutoClientModule();
|
|
10
|
+
return clientModule.createClient(config);
|
|
11
|
+
}
|
|
12
|
+
function deriveNamespace(config) {
|
|
13
|
+
if ('client' in config && config.client) {
|
|
14
|
+
return 'client';
|
|
15
|
+
}
|
|
16
|
+
const host = 'host' in config ? config.host : 'unknown-host';
|
|
17
|
+
const database = 'database' in config ? config.database : 'default';
|
|
18
|
+
const username = 'username' in config ? config.username : 'default';
|
|
19
|
+
return `${host || 'unknown-host'}|${database || 'default'}|${username || 'default'}`;
|
|
20
|
+
}
|
|
21
|
+
export class ClickHouseAdapter {
|
|
22
|
+
config;
|
|
23
|
+
name = 'clickhouse';
|
|
24
|
+
namespace;
|
|
25
|
+
client;
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.namespace = deriveNamespace(config);
|
|
29
|
+
this.client = createClickHouseClient(config);
|
|
30
|
+
}
|
|
31
|
+
async query(sql, params = [], options) {
|
|
32
|
+
const finalSQL = substituteParameters(sql, params);
|
|
33
|
+
const result = await this.client.query({
|
|
34
|
+
query: finalSQL,
|
|
35
|
+
format: 'JSONEachRow',
|
|
36
|
+
clickhouse_settings: options?.clickhouseSettings,
|
|
37
|
+
query_id: options?.queryId,
|
|
38
|
+
});
|
|
39
|
+
return result.json();
|
|
40
|
+
}
|
|
41
|
+
async stream(sql, params = [], options) {
|
|
42
|
+
const finalSQL = substituteParameters(sql, params);
|
|
43
|
+
const result = await this.client.query({
|
|
44
|
+
query: finalSQL,
|
|
45
|
+
format: 'JSONEachRow',
|
|
46
|
+
clickhouse_settings: options?.clickhouseSettings,
|
|
47
|
+
query_id: options?.queryId,
|
|
48
|
+
});
|
|
49
|
+
const stream = result.stream();
|
|
50
|
+
return createJsonEachRowStream(stream);
|
|
51
|
+
}
|
|
52
|
+
render(sql, params = []) {
|
|
53
|
+
return substituteParameters(sql, params);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function createClickHouseAdapter(config) {
|
|
57
|
+
return new ClickHouseAdapter(config);
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ClickHouseSettings } from '@clickhouse/client-common';
|
|
2
|
+
export interface QueryExecutionOptions {
|
|
3
|
+
clickhouseSettings?: ClickHouseSettings;
|
|
4
|
+
queryId?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DatabaseAdapter {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly namespace?: string;
|
|
9
|
+
query<T>(sql: string, params?: unknown[], options?: QueryExecutionOptions): Promise<T[]>;
|
|
10
|
+
stream?<T>(sql: string, params?: unknown[], options?: QueryExecutionOptions): Promise<ReadableStream<T[]>>;
|
|
11
|
+
render?(sql: string, params?: unknown[]): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=database-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/database-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACzF,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3G,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;CAClD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../../src/core/cache/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../../src/core/cache/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AA4DnF,wBAAsB,gBAAgB,CACpC,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvC,KAAK,SAAS,eAAe,EAE7B,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EACpC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CA4J5B"}
|
|
@@ -14,11 +14,10 @@ function deriveTags(builder) {
|
|
|
14
14
|
joins.forEach(join => tags.add(join.table));
|
|
15
15
|
return Array.from(tags);
|
|
16
16
|
}
|
|
17
|
-
async function logCacheHit({
|
|
18
|
-
const finalSQL = substituteParameters(sql, parameters);
|
|
17
|
+
async function logCacheHit({ renderSql, parameters, status, cacheKey, options, rowCount, ageMs, queryId }) {
|
|
19
18
|
const timestamp = Date.now();
|
|
20
19
|
logger.logQuery({
|
|
21
|
-
query:
|
|
20
|
+
query: renderSql,
|
|
22
21
|
parameters,
|
|
23
22
|
startTime: timestamp,
|
|
24
23
|
endTime: timestamp,
|
|
@@ -46,13 +45,15 @@ export async function executeWithCache(builder, options) {
|
|
|
46
45
|
}
|
|
47
46
|
const activeProvider = provider;
|
|
48
47
|
const { sql, parameters } = builder.toSQLWithParams();
|
|
48
|
+
const adapter = builder.getAdapter();
|
|
49
|
+
const renderSql = adapter.render ? adapter.render(sql, parameters) : substituteParameters(sql, parameters);
|
|
49
50
|
const tableName = builder.getTableName();
|
|
50
51
|
const namespace = mergedOptions.namespace || runtime.namespace;
|
|
51
52
|
const key = mergedOptions.key || computeCacheKey({
|
|
52
53
|
namespace,
|
|
53
54
|
sql,
|
|
54
55
|
parameters,
|
|
55
|
-
settings: builder.getConfig().settings
|
|
56
|
+
settings: builder.getConfig().settings,
|
|
56
57
|
version: runtime.versionTag,
|
|
57
58
|
tableName
|
|
58
59
|
});
|
|
@@ -82,7 +83,7 @@ export async function executeWithCache(builder, options) {
|
|
|
82
83
|
runtime.stats.staleHits += 1;
|
|
83
84
|
}
|
|
84
85
|
await logCacheHit({
|
|
85
|
-
|
|
86
|
+
renderSql,
|
|
86
87
|
parameters,
|
|
87
88
|
status,
|
|
88
89
|
cacheKey: key,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { QueryConfig } from '../../types/index.js';
|
|
2
|
+
import type { CompileQueryContext, SqlDialect } from './sql-dialect.js';
|
|
3
|
+
export declare class ClickHouseDialect implements SqlDialect {
|
|
4
|
+
readonly name = "clickhouse";
|
|
5
|
+
private formatter;
|
|
6
|
+
compileQuery(config: QueryConfig<any, any>, context: CompileQueryContext): string;
|
|
7
|
+
formatTimeInterval(column: string, interval: string, method: string): string;
|
|
8
|
+
formatSettings(settings: Record<string, unknown>): string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=clickhouse-dialect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickhouse-dialect.d.ts","sourceRoot":"","sources":["../../../src/core/dialects/clickhouse-dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAExE,qBAAa,iBAAkB,YAAW,UAAU;IAClD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,SAAS,CAAsB;IAEvC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM;IAyCjF,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ5E,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;CAK1D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { SQLFormatter } from '../formatters/sql-formatter.js';
|
|
2
|
+
export class ClickHouseDialect {
|
|
3
|
+
name = 'clickhouse';
|
|
4
|
+
formatter = new SQLFormatter();
|
|
5
|
+
compileQuery(config, context) {
|
|
6
|
+
const parts = [];
|
|
7
|
+
if (config.ctes?.length) {
|
|
8
|
+
parts.push(`WITH ${config.ctes.join(', ')}`);
|
|
9
|
+
}
|
|
10
|
+
parts.push(`SELECT ${this.formatter.formatSelect(config)}`);
|
|
11
|
+
parts.push(`FROM ${context.tableName}`);
|
|
12
|
+
if (config.joins?.length) {
|
|
13
|
+
parts.push(this.formatter.formatJoins(config));
|
|
14
|
+
}
|
|
15
|
+
if (config.where?.length) {
|
|
16
|
+
parts.push(`WHERE ${this.formatter.formatWhere(config)}`);
|
|
17
|
+
}
|
|
18
|
+
if (config.groupBy?.length) {
|
|
19
|
+
parts.push(`GROUP BY ${this.formatter.formatGroupBy(config)}`);
|
|
20
|
+
}
|
|
21
|
+
if (config.having?.length) {
|
|
22
|
+
parts.push(`HAVING ${config.having.join(' AND ')}`);
|
|
23
|
+
}
|
|
24
|
+
if (config.orderBy?.length) {
|
|
25
|
+
const orderBy = config.orderBy
|
|
26
|
+
.map(({ column, direction }) => `${String(column)} ${direction}`.trim())
|
|
27
|
+
.join(', ');
|
|
28
|
+
parts.push(`ORDER BY ${orderBy}`);
|
|
29
|
+
}
|
|
30
|
+
if (config.limit) {
|
|
31
|
+
const offsetClause = config.offset ? `OFFSET ${config.offset}` : '';
|
|
32
|
+
parts.push(`LIMIT ${config.limit} ${offsetClause}`);
|
|
33
|
+
}
|
|
34
|
+
return parts.join(' ').trim();
|
|
35
|
+
}
|
|
36
|
+
formatTimeInterval(column, interval, method) {
|
|
37
|
+
if (method === 'toStartOfInterval') {
|
|
38
|
+
return `${method}(${column}, INTERVAL ${interval})`;
|
|
39
|
+
}
|
|
40
|
+
return `${method}(${column})`;
|
|
41
|
+
}
|
|
42
|
+
formatSettings(settings) {
|
|
43
|
+
return Object.entries(settings)
|
|
44
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
45
|
+
.join(', ');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { QueryConfig } from '../../types/index.js';
|
|
2
|
+
export interface CompileQueryContext {
|
|
3
|
+
tableName: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SqlDialect {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
compileQuery(config: QueryConfig<any, any>, context: CompileQueryContext): string;
|
|
8
|
+
formatTimeInterval(column: string, interval: string, method: string): string;
|
|
9
|
+
formatSettings(settings: Record<string, unknown>): string;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sql-dialect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-dialect.d.ts","sourceRoot":"","sources":["../../../src/core/dialects/sql-dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAAC;IAClF,kBAAkB,CAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,MAAM,CAAC;IACV,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CAC3D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -20,7 +20,7 @@ export declare class AggregationFeature<Schema extends SchemaDefinition<Schema>,
|
|
|
20
20
|
parameters?: any[];
|
|
21
21
|
ctes?: string[];
|
|
22
22
|
unionQueries?: string[];
|
|
23
|
-
settings?:
|
|
23
|
+
settings?: import("@clickhouse/client-common").ClickHouseSettings;
|
|
24
24
|
};
|
|
25
25
|
count(column: string, alias: string): {
|
|
26
26
|
select: string[];
|
|
@@ -38,7 +38,7 @@ export declare class AggregationFeature<Schema extends SchemaDefinition<Schema>,
|
|
|
38
38
|
parameters?: any[];
|
|
39
39
|
ctes?: string[];
|
|
40
40
|
unionQueries?: string[];
|
|
41
|
-
settings?:
|
|
41
|
+
settings?: import("@clickhouse/client-common").ClickHouseSettings;
|
|
42
42
|
};
|
|
43
43
|
avg(column: string, alias: string): {
|
|
44
44
|
select: string[];
|
|
@@ -56,7 +56,7 @@ export declare class AggregationFeature<Schema extends SchemaDefinition<Schema>,
|
|
|
56
56
|
parameters?: any[];
|
|
57
57
|
ctes?: string[];
|
|
58
58
|
unionQueries?: string[];
|
|
59
|
-
settings?:
|
|
59
|
+
settings?: import("@clickhouse/client-common").ClickHouseSettings;
|
|
60
60
|
};
|
|
61
61
|
min(column: string, alias: string): {
|
|
62
62
|
select: string[];
|
|
@@ -74,7 +74,7 @@ export declare class AggregationFeature<Schema extends SchemaDefinition<Schema>,
|
|
|
74
74
|
parameters?: any[];
|
|
75
75
|
ctes?: string[];
|
|
76
76
|
unionQueries?: string[];
|
|
77
|
-
settings?:
|
|
77
|
+
settings?: import("@clickhouse/client-common").ClickHouseSettings;
|
|
78
78
|
};
|
|
79
79
|
max(column: string, alias: string): {
|
|
80
80
|
select: string[];
|
|
@@ -92,7 +92,7 @@ export declare class AggregationFeature<Schema extends SchemaDefinition<Schema>,
|
|
|
92
92
|
parameters?: any[];
|
|
93
93
|
ctes?: string[];
|
|
94
94
|
unionQueries?: string[];
|
|
95
|
-
settings?:
|
|
95
|
+
settings?: import("@clickhouse/client-common").ClickHouseSettings;
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
98
|
//# sourceMappingURL=aggregations.d.ts.map
|