Skip to content

Commit

Permalink
Use official clickhouse nodejs driver
Browse files Browse the repository at this point in the history
  • Loading branch information
rickbergfalk committed Mar 18, 2023
1 parent 89a176a commit 341e791
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 278 deletions.
47 changes: 20 additions & 27 deletions server/drivers/clickhouse/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// `clickhouse` package does not provide column information, and uses `request`
// May need to move to `node-clickhouse` or other library down the road
// https://clickhouse.tech/docs/en/interfaces/third-party/client-libraries/
const { ClickHouse } = require('clickhouse');
const { createClient } = require('@clickhouse/client');
const sqlLimiter = require('sql-limiter');
const { formatSchemaQueryResults } = require('../utils');

Expand Down Expand Up @@ -44,40 +41,36 @@ async function runQuery(query, connection) {

const port = connection.port || 8123;
const protocol = connection.useHTTPS ? 'https' : 'http';
const url = `${protocol}://${connection.host}`;
const host = `${protocol}://${connection.host}:${port}`;
const database = connection.database;

const username = connection.username || 'default';
const password = connection.password || '';

const clickhouse = new ClickHouse({
url,
port,
const client = createClient({
host,
database,
username,
password,
format: 'json',
config: {
database,
},
});

// clickhouse package will append ' FORMAT JSON' to certain queries,
// but does not handle CTEs WITH... SELECT.
// This is a modified approach used in package:
// https://github.com/TimonKK/clickhouse/blob/9dea3c0c3e4f3e2fe64e59dad762f1db044bf9bf/index.js#L479
// If a certain query type is detected and FORMAT JSON is not included, append it
// CTEs will be detected as following statement type (WITH cte AS (...) SELECT) will have type of "select"
// clickhouse client needs to use exec or query depending on statement type
// If the query returns some results, format needs to be set and the `query` method should be used
// Otherwise `exec` method should be used
const statementType = sqlLimiter.getStatementType(limitedQuery);
if (
['select', 'show', 'exists'].indexOf(statementType) > -1 &&
!limitedQuery
.trim()
.match(/FORMAT\s*(JSON|TabSeparatedWithNames|CSVWithNames)/im)
) {
limitedQuery += ' FORMAT JSON';

const format =
['select', 'show', 'exists'].indexOf(statementType) > -1
? `JSONEachRow`
: undefined;
const useExec = !format;

if (useExec) {
await client.exec({ query: limitedQuery });
return { rows, incomplete };
}

rows = await clickhouse.query(limitedQuery).toPromise();
const resultSet = await client.query({ query: limitedQuery, format });
rows = await resultSet.json();
if (rows.length > maxRows) {
incomplete = true;
rows = rows.slice(0, maxRows);
Expand Down
2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
"lint": "eslint \"**/*.js\" && prettier --check ."
},
"dependencies": {
"@clickhouse/client": "^0.0.13",
"@google-cloud/bigquery": "^6.0.0",
"athena-express": "^7.1.5",
"aws-sdk": "^2.1113.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.0",
"cassandra-driver": "^4.6.3",
"clickhouse": "^2.5.0",
"compression": "^1.7.4",
"connect-redis": "^6.1.3",
"connect-session-sequelize": "^7.1.3",
Expand Down

0 comments on commit 341e791

Please sign in to comment.