Skip to content

Commit 1a52979

Browse files
committed
test(schema-compiler): Replace apla-clickhouse with @clickhouse/client
1 parent 05984a2 commit 1a52979

File tree

3 files changed

+85
-75
lines changed

3 files changed

+85
-75
lines changed

packages/cubejs-schema-compiler/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"uuid": "^8.3.2"
5858
},
5959
"devDependencies": {
60-
"@cubejs-backend/apla-clickhouse": "^1.7.0",
60+
"@clickhouse/client": "^1.7.0",
6161
"@cubejs-backend/linter": "^1.0.0",
6262
"@cubejs-backend/query-orchestrator": "1.1.7",
6363
"@types/babel__code-frame": "^7.0.6",
Lines changed: 84 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
/* eslint-disable */
2-
// @ts-ignore
3-
import ClickHouse from '@cubejs-backend/apla-clickhouse';
1+
import { createClient } from '@clickhouse/client';
2+
import type { ClickHouseClient, ResponseJSON } from '@clickhouse/client';
43
import { GenericContainer } from 'testcontainers';
54
import type { StartedTestContainer } from 'testcontainers';
65
import { format as formatSql } from 'sqlstring';
76
import { v4 as uuidv4 } from 'uuid';
87
import { ClickHouseQuery } from '../../../src/adapter/ClickHouseQuery';
98
import { BaseDbRunner } from "../utils/BaseDbRunner";
109

11-
// Just a placeholder for now
12-
type ClickHouseClient = any;
13-
1410
process.env.TZ = 'GMT';
1511

1612
export class ClickHouseDbRunner extends BaseDbRunner {
@@ -35,27 +31,32 @@ export class ClickHouseDbRunner extends BaseDbRunner {
3531
// let engine = 'MergeTree PARTITION BY id ORDER BY (id) SETTINGS index_granularity = 8192'
3632
const engine = 'Memory';
3733

38-
await clickHouse.querying(`
39-
CREATE TEMPORARY TABLE visitors (id UInt64, amount UInt64, created_at DateTime, updated_at DateTime, status UInt64, source Nullable(String), latitude Float64, longitude Float64)
40-
ENGINE = ${engine}`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
34+
await clickHouse.command({ query: `
35+
CREATE TEMPORARY TABLE visitors (id UInt64, amount UInt64, created_at DateTime, updated_at DateTime, status UInt64, source Nullable(String), latitude Float64, longitude Float64)
36+
ENGINE = ${engine}
37+
` });
4138

42-
await clickHouse.querying(`
43-
CREATE TEMPORARY TABLE visitor_checkins (id UInt64, visitor_id UInt64, created_at DateTime, source Nullable(String))
44-
ENGINE = ${engine}`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
39+
await clickHouse.command({ query: `
40+
CREATE TEMPORARY TABLE visitor_checkins (id UInt64, visitor_id UInt64, created_at DateTime, source Nullable(String))
41+
ENGINE = ${engine}
42+
` });
4543

46-
await clickHouse.querying(`
47-
CREATE TEMPORARY TABLE cards (id UInt64, visitor_id UInt64, visitor_checkin_id UInt64)
48-
ENGINE = ${engine}`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
44+
await clickHouse.command({ query: `
45+
CREATE TEMPORARY TABLE cards (id UInt64, visitor_id UInt64, visitor_checkin_id UInt64)
46+
ENGINE = ${engine}
47+
` });
4948

50-
await clickHouse.querying(`
51-
CREATE TEMPORARY TABLE events (id UInt64, type String, name String, started_at DateTime64, ended_at Nullable(DateTime64))
52-
ENGINE = ${engine}`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
49+
await clickHouse.command({ query: `
50+
CREATE TEMPORARY TABLE events (id UInt64, type String, name String, started_at DateTime64, ended_at Nullable(DateTime64))
51+
ENGINE = ${engine}
52+
` });
5353

54-
await clickHouse.querying(`
55-
CREATE TEMPORARY TABLE numbers (num Int)
56-
ENGINE = ${engine}`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
54+
await clickHouse.command({ query: `
55+
CREATE TEMPORARY TABLE numbers (num Int)
56+
ENGINE = ${engine}
57+
` });
5758

58-
await clickHouse.querying(`
59+
await clickHouse.command({ query: `
5960
INSERT INTO
6061
visitors
6162
(id, amount, created_at, updated_at, status, source, latitude, longitude) VALUES
@@ -65,9 +66,9 @@ export class ClickHouseDbRunner extends BaseDbRunner {
6566
(4, 400, '2017-01-06 16:00:00', '2017-01-24 16:00:00', 2, null, 120.120, 10.60),
6667
(5, 500, '2017-01-06 16:00:00', '2017-01-24 16:00:00', 2, null, 120.120, 58.10),
6768
(6, 500, '2016-09-06 16:00:00', '2016-09-06 16:00:00', 2, null, 120.120, 58.10)
68-
`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
69+
` });
6970

70-
await clickHouse.querying(`
71+
await clickHouse.command({ query: `
7172
INSERT INTO
7273
visitor_checkins
7374
(id, visitor_id, created_at, source) VALUES
@@ -77,28 +78,28 @@ export class ClickHouseDbRunner extends BaseDbRunner {
7778
(4, 2, '2017-01-04 16:00:00', null),
7879
(5, 2, '2017-01-04 16:00:00', null),
7980
(6, 3, '2017-01-05 16:00:00', null)
80-
`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
81+
` });
8182

82-
await clickHouse.querying(`
83+
await clickHouse.command({ query: `
8384
INSERT INTO
8485
cards
8586
(id, visitor_id, visitor_checkin_id) VALUES
8687
(1, 1, 1),
8788
(2, 1, 2),
8889
(3, 3, 6)
89-
`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
90+
` });
9091

91-
await clickHouse.querying(`
92+
await clickHouse.command({ query: `
9293
INSERT INTO
9394
events
9495
(id, type, name, started_at, ended_at) VALUES
9596
(1, 'moon_missions', 'Apollo 10', '1969-05-18 16:49:00', '1969-05-26 16:52:23'),
9697
(2, 'moon_missions', 'Apollo 11', '1969-07-16 13:32:00', '1969-07-24 16:50:35'),
9798
(3, 'moon_missions', 'Artemis I', '2021-11-16 06:32:00', '2021-12-11 18:50:00'),
9899
(4, 'private_missions', 'Axiom Mission 1', '2022-04-08 15:17:12', '2022-04-25 17:06:00')
99-
`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
100+
` });
100101

101-
await clickHouse.querying(`
102+
await clickHouse.command({ query: `
102103
INSERT INTO
103104
numbers
104105
(num) VALUES
@@ -108,7 +109,7 @@ export class ClickHouseDbRunner extends BaseDbRunner {
108109
(30), (31), (32), (33), (34), (35), (36), (37), (38), (39),
109110
(40), (41), (42), (43), (44), (45), (46), (47), (48), (49),
110111
(50), (51), (52), (53), (54), (55), (56), (57), (58), (59)
111-
`, { queryOptions: { session_id: clickHouse.sessionId, join_use_nulls: '1' } });
112+
` });
112113
}
113114

114115
public override async testQueries(queries: Array<[string, Array<unknown>]>, prepareDataSet?: ((client: ClickHouseClient) => Promise<void>) | null): Promise<Array<Array<Record<string, unknown>>>> {
@@ -127,18 +128,17 @@ export class ClickHouseDbRunner extends BaseDbRunner {
127128
port = this.container.getMappedPort(8123);
128129
}
129130

130-
const clickHouse = new ClickHouse({
131-
host,
132-
port,
133-
});
131+
const clickHouse = createClient({
132+
url: `http://${host}:${port}`,
134133

135-
clickHouse.sessionId = uuidv4(); // needed for tests to use temporary tables
134+
// needed for tests to use temporary tables
135+
session_id: uuidv4(),
136+
max_open_connections: 1,
137+
});
136138

137139
prepareDataSet = prepareDataSet || this.gutterDataSet;
138140
await prepareDataSet(clickHouse);
139141

140-
const requests: Array<unknown> = [];
141-
142142
// Controls whether functions return results with extended date and time ranges.
143143
//
144144
// 0 — Functions return Date or DateTime for all arguments (default).
@@ -150,19 +150,23 @@ export class ClickHouseDbRunner extends BaseDbRunner {
150150
//
151151
// https://clickhouse.com/docs/en/operations/settings/settings#enable-extended-results-for-datetime-functions
152152
const extendedDateTimeResultsOptions = this.supportsExtendedDateTimeResults ? {
153-
enable_extended_results_for_datetime_functions: '1'
154-
} : {};
155-
156-
for (const [query, params] of queries) {
157-
requests.push(clickHouse.querying(formatSql(query, params), {
158-
dataObjects: true,
159-
queryOptions: {
160-
session_id: clickHouse.sessionId,
161-
join_use_nulls: '1',
162-
...extendedDateTimeResultsOptions
163-
}
164-
}));
165-
}
153+
enable_extended_results_for_datetime_functions: 1
154+
} as const : {};
155+
156+
const requests = queries
157+
.map(async ([query, params]) => {
158+
const resultSet = await clickHouse.query({
159+
query: formatSql(query, params),
160+
format: 'JSON',
161+
clickhouse_settings: {
162+
join_use_nulls: 1,
163+
...extendedDateTimeResultsOptions
164+
}
165+
});
166+
// Because we used JSON format we expect each row in result set to be a record of column name => value
167+
const result = await resultSet.json<Record<string, unknown>>();
168+
return result;
169+
});
166170

167171
const results = await Promise.all(requests);
168172

@@ -189,26 +193,37 @@ export class ClickHouseDbRunner extends BaseDbRunner {
189193
//
190194
// https://github.com/statsbotco/cube.js/pull/98#discussion_r279698399
191195
//
192-
protected static _normaliseResponse(res: any): Array<Record<string, unknown>> {
193-
if (process.env.DEBUG_LOG === 'true') console.log(res);
194-
if (res.data) {
195-
res.data.forEach(row => {
196-
for (const field in row) {
197-
const value = row[field];
198-
if (value !== null) {
199-
const meta = res.meta.find(m => m.name == field);
200-
if (meta.type.includes('DateTime')) {
201-
row[field] = `${value.substring(0, 10)}T${value.substring(11, 22)}.000`;
202-
} else if (meta.type.includes('Date')) {
203-
row[field] = `${value}T00:00:00.000`;
204-
} else if (meta.type.includes('Int') || meta.type.includes('Float')) {
205-
// convert all numbers into strings
206-
row[field] = `${value}`;
196+
protected static _normaliseResponse(res: ResponseJSON<Record<string, unknown>>): Array<Record<string, unknown>> {
197+
if (process.env.DEBUG_LOG === 'true') {
198+
console.log(res);
199+
}
200+
201+
const { meta, data } = res;
202+
if (meta === undefined) {
203+
throw new Error('Unexpected missing meta');
204+
}
205+
206+
data.forEach(row => {
207+
for (const [field, value] of Object.entries(row)) {
208+
if (value !== null) {
209+
const fieldMeta = meta.find(m => m.name == field);
210+
if (fieldMeta === undefined) {
211+
throw new Error(`Missing meta for field ${field}`);
212+
}
213+
if (fieldMeta.type.includes('DateTime')) {
214+
if (typeof value !== 'string') {
215+
throw new Error(`Unexpected value for ${field}`);
207216
}
217+
row[field] = `${value.substring(0, 10)}T${value.substring(11, 22)}.000`;
218+
} else if (fieldMeta.type.includes('Date')) {
219+
row[field] = `${value}T00:00:00.000`;
220+
} else if (fieldMeta.type.includes('Int') || fieldMeta.type.includes('Float')) {
221+
// convert all numbers into strings
222+
row[field] = `${value}`;
208223
}
209224
}
210-
});
211-
}
212-
return res.data;
225+
}
226+
});
227+
return data;
213228
}
214229
}

yarn.lock

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4365,11 +4365,6 @@
43654365
tiny-invariant "^1.3.3"
43664366
valid-url "^1.0.9"
43674367

4368-
"@cubejs-backend/apla-clickhouse@^1.7.0":
4369-
version "1.7.0"
4370-
resolved "https://registry.yarnpkg.com/@cubejs-backend/apla-clickhouse/-/apla-clickhouse-1.7.0.tgz#6359f46c56492d1704d18be0210c7546fdac5f5e"
4371-
integrity sha512-qwXapTC/qosA6RprElRjnl8gmlDQaxtJPtbgcdjyNvkmiyao1HI+w5QkjHWCiVm6aTzE0gjFr6/2y87TZ9fojg==
4372-
43734368
"@cubejs-backend/dotenv@^9.0.2":
43744369
version "9.0.2"
43754370
resolved "https://registry.yarnpkg.com/@cubejs-backend/dotenv/-/dotenv-9.0.2.tgz#c3679091b702f0fd38de120c5a63943fcdc0dcbf"

0 commit comments

Comments
 (0)