@clickhouse/client 1.20.0 → 1.21.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.
- package/README.md +11 -11
- package/dist/client.d.ts +6 -6
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +6 -6
- package/dist/config.js +6 -5
- package/dist/config.js.map +1 -1
- package/dist/connection/compression.d.ts +4 -4
- package/dist/connection/compression.js +3 -3
- package/dist/connection/compression.js.map +1 -1
- package/dist/connection/create_connection.d.ts +6 -6
- package/dist/connection/create_connection.js +3 -3
- package/dist/connection/create_connection.js.map +1 -1
- package/dist/connection/index.d.ts +4 -4
- package/dist/connection/index.js.map +1 -1
- package/dist/connection/node_base_connection.d.ts +11 -11
- package/dist/connection/node_base_connection.js +75 -42
- package/dist/connection/node_base_connection.js.map +1 -1
- package/dist/connection/node_custom_agent_connection.d.ts +4 -4
- package/dist/connection/node_custom_agent_connection.js +2 -2
- package/dist/connection/node_custom_agent_connection.js.map +1 -1
- package/dist/connection/node_http_connection.d.ts +4 -4
- package/dist/connection/node_http_connection.js.map +1 -1
- package/dist/connection/node_https_connection.d.ts +5 -5
- package/dist/connection/node_https_connection.js +11 -11
- package/dist/connection/node_https_connection.js.map +1 -1
- package/dist/connection/socket_pool.d.ts +9 -9
- package/dist/connection/socket_pool.js +33 -32
- package/dist/connection/socket_pool.js.map +1 -1
- package/dist/connection/stream.d.ts +2 -2
- package/dist/connection/stream.js +18 -18
- package/dist/connection/stream.js.map +1 -1
- package/dist/index.d.ts +41 -8
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/result_set.d.ts +31 -20
- package/dist/result_set.js +83 -13
- package/dist/result_set.js.map +1 -1
- package/dist/utils/encoder.d.ts +2 -2
- package/dist/utils/encoder.js +3 -3
- package/dist/utils/encoder.js.map +1 -1
- package/dist/utils/index.d.ts +4 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/runtime.js.map +1 -1
- package/dist/utils/stream.d.ts +1 -1
- package/dist/utils/stream.js +8 -8
- package/dist/utils/stream.js.map +1 -1
- package/dist/utils/user_agent.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/skills/clickhouse-js-node-coding/reference/async-insert.md +12 -12
- package/skills/clickhouse-js-node-coding/reference/client-configuration.md +16 -16
- package/skills/clickhouse-js-node-coding/reference/custom-json.md +31 -31
- package/skills/clickhouse-js-node-coding/reference/data-types.md +65 -65
- package/skills/clickhouse-js-node-coding/reference/insert-columns.md +23 -23
- package/skills/clickhouse-js-node-coding/reference/insert-formats.md +30 -30
- package/skills/clickhouse-js-node-coding/reference/insert-values.md +35 -35
- package/skills/clickhouse-js-node-coding/reference/ping.md +24 -24
- package/skills/clickhouse-js-node-coding/reference/query-parameters.md +27 -27
- package/skills/clickhouse-js-node-coding/reference/select-formats.md +21 -21
- package/skills/clickhouse-js-node-coding/reference/sessions.md +27 -27
- package/skills/clickhouse-js-node-troubleshooting/reference/compression.md +2 -2
- package/skills/clickhouse-js-node-troubleshooting/reference/data-types.md +24 -24
- package/skills/clickhouse-js-node-troubleshooting/reference/logging.md +5 -5
- package/skills/clickhouse-js-node-troubleshooting/reference/proxy-pathname.md +7 -7
- package/skills/clickhouse-js-node-troubleshooting/reference/query-format-clause.md +6 -6
- package/skills/clickhouse-js-node-troubleshooting/reference/query-params.md +30 -30
- package/skills/clickhouse-js-node-troubleshooting/reference/readonly-users.md +4 -4
- package/skills/clickhouse-js-node-troubleshooting/reference/socket-hangup.md +20 -20
- package/skills/clickhouse-js-node-troubleshooting/reference/tls.md +24 -24
package/README.md
CHANGED
|
@@ -84,23 +84,23 @@ The client may work with older versions too; however, this is best-effort suppor
|
|
|
84
84
|
## Quick start
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
|
-
import { createClient } from
|
|
87
|
+
import { createClient } from "@clickhouse/client"; // or '@clickhouse/client-web'
|
|
88
88
|
|
|
89
89
|
const client = createClient({
|
|
90
|
-
url: process.env.CLICKHOUSE_URL ??
|
|
91
|
-
username: process.env.CLICKHOUSE_USER ??
|
|
92
|
-
password: process.env.CLICKHOUSE_PASSWORD ??
|
|
93
|
-
})
|
|
90
|
+
url: process.env.CLICKHOUSE_URL ?? "http://localhost:8123",
|
|
91
|
+
username: process.env.CLICKHOUSE_USER ?? "default",
|
|
92
|
+
password: process.env.CLICKHOUSE_PASSWORD ?? "",
|
|
93
|
+
});
|
|
94
94
|
|
|
95
95
|
const resultSet = await client.query({
|
|
96
|
-
query:
|
|
97
|
-
format:
|
|
98
|
-
})
|
|
96
|
+
query: "SELECT * FROM system.tables",
|
|
97
|
+
format: "JSONEachRow",
|
|
98
|
+
});
|
|
99
99
|
|
|
100
|
-
const tables = await resultSet.json()
|
|
101
|
-
console.log(tables)
|
|
100
|
+
const tables = await resultSet.json();
|
|
101
|
+
console.log(tables);
|
|
102
102
|
|
|
103
|
-
await client.close()
|
|
103
|
+
await client.close();
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
See more examples in the [examples directory](./examples).
|
package/dist/client.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { DataFormat, IsSame, QueryParamsWithFormat } from
|
|
2
|
-
import { ClickHouseClient } from
|
|
3
|
-
import type Stream from
|
|
4
|
-
import type { NodeClickHouseClientConfigOptions } from
|
|
5
|
-
import type { ResultSet } from
|
|
1
|
+
import type { DataFormat, IsSame, QueryParamsWithFormat } from "@clickhouse/client-common";
|
|
2
|
+
import { ClickHouseClient } from "@clickhouse/client-common";
|
|
3
|
+
import type Stream from "stream";
|
|
4
|
+
import type { NodeClickHouseClientConfigOptions } from "./config";
|
|
5
|
+
import type { ResultSet } from "./result_set";
|
|
6
6
|
/** If the Format is not a literal type, fall back to the default behavior of the ResultSet,
|
|
7
7
|
* allowing to call all methods with all data shapes variants,
|
|
8
8
|
* and avoiding generated types that include all possible DataFormat literal values. */
|
|
9
9
|
export type QueryResult<Format extends DataFormat> = IsSame<Format, DataFormat> extends true ? ResultSet<unknown> : ResultSet<Format>;
|
|
10
10
|
export declare class NodeClickHouseClient extends ClickHouseClient<Stream.Readable> {
|
|
11
11
|
/** See {@link ClickHouseClient.query}. */
|
|
12
|
-
query<Format extends DataFormat =
|
|
12
|
+
query<Format extends DataFormat = "JSON">(params: QueryParamsWithFormat<Format>): Promise<QueryResult<Format>>;
|
|
13
13
|
}
|
|
14
14
|
export declare function createClient(config?: NodeClickHouseClientConfigOptions): NodeClickHouseClient;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AA4BA,oCAOC;AA9BD,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AA4BA,oCAOC;AA9BD,6DAA6D;AAG7D,qCAA0C;AAW1C,MAAa,oBAAqB,SAAQ,gCAAiC;IACzE,0CAA0C;IACjC,KAAK,CACZ,MAAqC;QAErC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAA+B,CAAC;IAC3D,CAAC;CACF;AAPD,oDAOC;AAED,SAAgB,YAAY,CAC1B,MAA0C;IAE1C,OAAO,IAAI,gCAAgB,CAAkB;QAC3C,IAAI,EAAE,uBAAc;QACpB,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;KAClB,CAAyB,CAAC;AAC7B,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ImplementationDetails } from
|
|
2
|
-
import { type BaseClickHouseClientConfigOptions } from
|
|
3
|
-
import type http from
|
|
4
|
-
import type https from
|
|
5
|
-
import type Stream from
|
|
1
|
+
import type { ImplementationDetails } from "@clickhouse/client-common";
|
|
2
|
+
import { type BaseClickHouseClientConfigOptions } from "@clickhouse/client-common";
|
|
3
|
+
import type http from "http";
|
|
4
|
+
import type https from "node:https";
|
|
5
|
+
import type Stream from "stream";
|
|
6
6
|
export type NodeClickHouseClientConfigOptions = BaseClickHouseClientConfigOptions & {
|
|
7
7
|
tls?: BasicTLSOptions | MutualTLSOptions;
|
|
8
8
|
/** HTTP Keep-Alive related settings */
|
|
@@ -71,5 +71,5 @@ interface MutualTLSOptions {
|
|
|
71
71
|
cert: Buffer;
|
|
72
72
|
key: Buffer;
|
|
73
73
|
}
|
|
74
|
-
export declare const NodeConfigImpl: Required<ImplementationDetails<Stream.Readable>[
|
|
74
|
+
export declare const NodeConfigImpl: Required<ImplementationDetails<Stream.Readable>["impl"]>;
|
|
75
75
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -15,7 +15,7 @@ exports.NodeConfigImpl = {
|
|
|
15
15
|
urlSearchParamsKeys.forEach((key) => {
|
|
16
16
|
const value = url.searchParams.get(key);
|
|
17
17
|
switch (key) {
|
|
18
|
-
case
|
|
18
|
+
case "keep_alive_idle_socket_ttl":
|
|
19
19
|
if (nodeConfig.keep_alive === undefined) {
|
|
20
20
|
nodeConfig.keep_alive = {};
|
|
21
21
|
}
|
|
@@ -40,15 +40,15 @@ exports.NodeConfigImpl = {
|
|
|
40
40
|
make_connection: (nodeConfig, params) => {
|
|
41
41
|
let tls = undefined;
|
|
42
42
|
if (nodeConfig.tls !== undefined) {
|
|
43
|
-
if (
|
|
43
|
+
if ("cert" in nodeConfig.tls && "key" in nodeConfig.tls) {
|
|
44
44
|
tls = {
|
|
45
|
-
type:
|
|
45
|
+
type: "Mutual",
|
|
46
46
|
...nodeConfig.tls,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
50
|
tls = {
|
|
51
|
-
type:
|
|
51
|
+
type: "Basic",
|
|
52
52
|
...nodeConfig.tls,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
@@ -70,13 +70,14 @@ exports.NodeConfigImpl = {
|
|
|
70
70
|
});
|
|
71
71
|
},
|
|
72
72
|
values_encoder: (jsonHandling) => new utils_1.NodeValuesEncoder(jsonHandling),
|
|
73
|
-
make_result_set: ((stream, format, query_id, log_error, response_headers, jsonHandling) => result_set_1.ResultSet.instance({
|
|
73
|
+
make_result_set: ((stream, format, query_id, log_error, response_headers, jsonHandling, span) => result_set_1.ResultSet.instance({
|
|
74
74
|
stream,
|
|
75
75
|
format,
|
|
76
76
|
query_id,
|
|
77
77
|
log_error,
|
|
78
78
|
response_headers,
|
|
79
79
|
jsonHandling,
|
|
80
|
+
span,
|
|
80
81
|
})),
|
|
81
82
|
};
|
|
82
83
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { LogWriter } from
|
|
2
|
-
import { ClickHouseLogLevel } from
|
|
3
|
-
import type Http from
|
|
4
|
-
import Stream from
|
|
1
|
+
import type { LogWriter } from "@clickhouse/client-common";
|
|
2
|
+
import { ClickHouseLogLevel } from "@clickhouse/client-common";
|
|
3
|
+
import type Http from "http";
|
|
4
|
+
import Stream from "stream";
|
|
5
5
|
type DecompressResponseResult = {
|
|
6
6
|
response: Stream.Readable;
|
|
7
7
|
} | {
|
|
@@ -9,14 +9,14 @@ const client_common_1 = require("@clickhouse/client-common");
|
|
|
9
9
|
const stream_1 = __importDefault(require("stream"));
|
|
10
10
|
const zlib_1 = __importDefault(require("zlib"));
|
|
11
11
|
function decompressResponse(response, log_writer, log_level) {
|
|
12
|
-
const encoding = response.headers[
|
|
13
|
-
if (encoding ===
|
|
12
|
+
const encoding = response.headers["content-encoding"];
|
|
13
|
+
if (encoding === "gzip") {
|
|
14
14
|
return {
|
|
15
15
|
response: stream_1.default.pipeline(response, zlib_1.default.createGunzip(), function pipelineCb(err) {
|
|
16
16
|
if (err) {
|
|
17
17
|
if (log_level <= client_common_1.ClickHouseLogLevel.ERROR) {
|
|
18
18
|
log_writer.error({
|
|
19
|
-
message:
|
|
19
|
+
message: "An error occurred while decompressing the response",
|
|
20
20
|
err,
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../src/connection/compression.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../src/connection/compression.ts"],"names":[],"mappings":";;;;;AAUA,gDA+BC;AAED,oDAEC;AA5CD,6DAA+D;AAE/D,oDAA4B;AAC5B,gDAAwB;AAMxB,SAAgB,kBAAkB,CAChC,QAA8B,EAC9B,UAAqB,EACrB,SAA6B;IAE7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEtD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO;YACL,QAAQ,EAAE,gBAAM,CAAC,QAAQ,CACvB,QAAQ,EACR,cAAI,CAAC,YAAY,EAAE,EACnB,SAAS,UAAU,CAAC,GAAG;gBACrB,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,SAAS,IAAI,kCAAkB,CAAC,KAAK,EAAE,CAAC;wBAC1C,UAAU,CAAC,KAAK,CAAC;4BACf,OAAO,EAAE,oDAAoD;4BAC7D,GAAG;yBACJ,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC,CACF;SACF,CAAC;IACJ,CAAC;SAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,IAAI,KAAK,CAAC,wBAAwB,QAAQ,EAAE,CAAC;SACrD,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,SAAgB,oBAAoB,CAAC,MAAW;IAC9C,OAAO,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC;AACpC,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ConnectionParams } from
|
|
2
|
-
import type http from
|
|
3
|
-
import type https from
|
|
4
|
-
import type { NodeBaseConnection, NodeConnectionParams } from
|
|
1
|
+
import type { ConnectionParams } from "@clickhouse/client-common";
|
|
2
|
+
import type http from "http";
|
|
3
|
+
import type https from "node:https";
|
|
4
|
+
import type { NodeBaseConnection, NodeConnectionParams } from "./node_base_connection";
|
|
5
5
|
export interface CreateConnectionParams {
|
|
6
6
|
connection_params: ConnectionParams;
|
|
7
|
-
tls: NodeConnectionParams[
|
|
8
|
-
keep_alive: NodeConnectionParams[
|
|
7
|
+
tls: NodeConnectionParams["tls"];
|
|
8
|
+
keep_alive: NodeConnectionParams["keep_alive"];
|
|
9
9
|
http_agent: http.Agent | https.Agent | undefined;
|
|
10
10
|
set_basic_auth_header: boolean;
|
|
11
11
|
capture_enhanced_stack_trace: boolean;
|
|
@@ -20,7 +20,7 @@ class NodeConnectionFactory {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
switch (connection_params.url.protocol) {
|
|
23
|
-
case
|
|
23
|
+
case "http:":
|
|
24
24
|
return new node_http_connection_1.NodeHttpConnection({
|
|
25
25
|
...connection_params,
|
|
26
26
|
set_basic_auth_header,
|
|
@@ -29,7 +29,7 @@ class NodeConnectionFactory {
|
|
|
29
29
|
eagerly_destroy_stale_sockets,
|
|
30
30
|
max_response_headers_size,
|
|
31
31
|
});
|
|
32
|
-
case
|
|
32
|
+
case "https:":
|
|
33
33
|
return new node_https_connection_1.NodeHttpsConnection({
|
|
34
34
|
...connection_params,
|
|
35
35
|
set_basic_auth_header,
|
|
@@ -40,7 +40,7 @@ class NodeConnectionFactory {
|
|
|
40
40
|
max_response_headers_size,
|
|
41
41
|
});
|
|
42
42
|
default:
|
|
43
|
-
throw new Error(
|
|
43
|
+
throw new Error("Only HTTP and HTTPS protocols are supported");
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_connection.js","sourceRoot":"","sources":["../../src/connection/create_connection.ts"],"names":[],"mappings":";;;AAOA,
|
|
1
|
+
{"version":3,"file":"create_connection.js","sourceRoot":"","sources":["../../src/connection/create_connection.ts"],"names":[],"mappings":";;;AAOA,iFAA2E;AAC3E,iEAA4D;AAC5D,mEAA8D;AAa9D,uDAAuD;AACvD,kEAAkE;AAClE,MAAa,qBAAqB;IAChC,MAAM,CAAC,MAAM,CAAC,EACZ,iBAAiB,EACjB,GAAG,EACH,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,6BAA6B,GAAG,KAAK,EACrC,yBAAyB,GACF;QACvB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAI,wDAAyB,CAAC;gBACnC,GAAG,iBAAiB;gBACpB,qBAAqB;gBACrB,4BAA4B;gBAC5B,UAAU,EAAE,gDAAgD;gBAC5D,UAAU;gBACV,6BAA6B;gBAC7B,yBAAyB;aAC1B,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YACvC,KAAK,OAAO;gBACV,OAAO,IAAI,yCAAkB,CAAC;oBAC5B,GAAG,iBAAiB;oBACpB,qBAAqB;oBACrB,4BAA4B;oBAC5B,UAAU;oBACV,6BAA6B;oBAC7B,yBAAyB;iBAC1B,CAAC,CAAC;YACL,KAAK,QAAQ;gBACX,OAAO,IAAI,2CAAmB,CAAC;oBAC7B,GAAG,iBAAiB;oBACpB,qBAAqB;oBACrB,4BAA4B;oBAC5B,UAAU;oBACV,GAAG;oBACH,6BAA6B;oBAC7B,yBAAyB;iBAC1B,CAAC,CAAC;YACL;gBACE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;CACF;AA9CD,sDA8CC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./node_base_connection";
|
|
2
|
+
export * from "./node_http_connection";
|
|
3
|
+
export * from "./node_https_connection";
|
|
4
|
+
export * from "./create_connection";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,yDAAuC;AACvC,0DAAwC;AACxC,sDAAoC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ConnBaseQueryParams, ConnCommandResult, Connection, ConnectionParams, ConnExecParams, ConnExecResult, ConnInsertParams, ConnInsertResult, ConnPingResult, ConnQueryResult } from
|
|
2
|
-
import { ClickHouseLogLevel } from
|
|
3
|
-
import { type ConnPingParams } from
|
|
4
|
-
import type Http from
|
|
5
|
-
import type Https from
|
|
6
|
-
import type Stream from
|
|
7
|
-
import { type RequestParams } from
|
|
1
|
+
import type { ConnBaseQueryParams, ConnCommandResult, Connection, ConnectionParams, ConnExecParams, ConnExecResult, ConnInsertParams, ConnInsertResult, ConnPingResult, ConnQueryResult } from "@clickhouse/client-common";
|
|
2
|
+
import { ClickHouseLogLevel } from "@clickhouse/client-common";
|
|
3
|
+
import { type ConnPingParams } from "@clickhouse/client-common";
|
|
4
|
+
import type Http from "http";
|
|
5
|
+
import type Https from "node:https";
|
|
6
|
+
import type Stream from "stream";
|
|
7
|
+
import { type RequestParams } from "./socket_pool";
|
|
8
8
|
export type NodeConnectionParams = ConnectionParams & {
|
|
9
9
|
tls?: TLSParams;
|
|
10
10
|
http_agent?: Http.Agent | Https.Agent;
|
|
@@ -31,20 +31,20 @@ export type NodeConnectionParams = ConnectionParams & {
|
|
|
31
31
|
};
|
|
32
32
|
export type TLSParams = {
|
|
33
33
|
ca_cert: Buffer;
|
|
34
|
-
type:
|
|
34
|
+
type: "Basic";
|
|
35
35
|
} | {
|
|
36
36
|
ca_cert: Buffer;
|
|
37
37
|
cert: Buffer;
|
|
38
38
|
key: Buffer;
|
|
39
|
-
type:
|
|
39
|
+
type: "Mutual";
|
|
40
40
|
};
|
|
41
41
|
export declare abstract class NodeBaseConnection implements Connection<Stream.Readable> {
|
|
42
|
-
protected readonly params: NodeConnectionParams;
|
|
43
|
-
protected readonly agent: Http.Agent;
|
|
44
42
|
protected readonly defaultAuthHeader: string;
|
|
45
43
|
protected readonly defaultHeaders: Http.OutgoingHttpHeaders;
|
|
46
44
|
private readonly connectionId;
|
|
47
45
|
private readonly socketPool;
|
|
46
|
+
protected readonly params: NodeConnectionParams;
|
|
47
|
+
protected readonly agent: Http.Agent;
|
|
48
48
|
protected constructor(params: NodeConnectionParams, agent: Http.Agent);
|
|
49
49
|
ping(params: ConnPingParams): Promise<ConnPingResult>;
|
|
50
50
|
query(params: ConnBaseQueryParams): Promise<ConnQueryResult<Stream.Readable>>;
|
|
@@ -10,20 +10,20 @@ const utils_1 = require("../utils");
|
|
|
10
10
|
const stream_1 = require("./stream");
|
|
11
11
|
const socket_pool_1 = require("./socket_pool");
|
|
12
12
|
class NodeBaseConnection {
|
|
13
|
-
params;
|
|
14
|
-
agent;
|
|
15
13
|
defaultAuthHeader;
|
|
16
14
|
defaultHeaders;
|
|
17
15
|
connectionId = crypto_1.default.randomUUID();
|
|
18
16
|
socketPool;
|
|
17
|
+
params;
|
|
18
|
+
agent;
|
|
19
19
|
constructor(params, agent) {
|
|
20
20
|
this.params = params;
|
|
21
21
|
this.agent = agent;
|
|
22
22
|
this.socketPool = new socket_pool_1.SocketPool(this.connectionId, this.params, this.createClientRequest.bind(this), this.agent);
|
|
23
|
-
if (params.auth.type ===
|
|
24
|
-
this.defaultAuthHeader = `Basic ${Buffer.from(`${params.auth.username}:${params.auth.password}`).toString(
|
|
23
|
+
if (params.auth.type === "Credentials") {
|
|
24
|
+
this.defaultAuthHeader = `Basic ${Buffer.from(`${params.auth.username}:${params.auth.password}`).toString("base64")}`;
|
|
25
25
|
}
|
|
26
|
-
else if (params.auth.type ===
|
|
26
|
+
else if (params.auth.type === "JWT") {
|
|
27
27
|
this.defaultAuthHeader = `Bearer ${params.auth.access_token}`;
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
@@ -31,8 +31,8 @@ class NodeBaseConnection {
|
|
|
31
31
|
}
|
|
32
32
|
this.defaultHeaders = {
|
|
33
33
|
// Node.js HTTP agent, for some reason, does not set this on its own when KeepAlive is enabled
|
|
34
|
-
Connection: this.params.keep_alive.enabled ?
|
|
35
|
-
|
|
34
|
+
Connection: this.params.keep_alive.enabled ? "keep-alive" : "close",
|
|
35
|
+
"User-Agent": (0, utils_1.getUserAgent)(this.params.application_id),
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
async ping(params) {
|
|
@@ -49,29 +49,29 @@ class NodeBaseConnection {
|
|
|
49
49
|
});
|
|
50
50
|
result = await this.request({
|
|
51
51
|
query: PingQuery,
|
|
52
|
-
method:
|
|
52
|
+
method: "GET",
|
|
53
53
|
url: (0, client_common_1.transformUrl)({ url: this.params.url, searchParams }),
|
|
54
54
|
abort_signal: controller.signal,
|
|
55
55
|
headers: this.buildRequestHeaders(),
|
|
56
56
|
query_id,
|
|
57
57
|
log_writer,
|
|
58
58
|
log_level,
|
|
59
|
-
},
|
|
59
|
+
}, "Ping");
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
62
|
result = await this.request({
|
|
63
|
-
query:
|
|
64
|
-
method:
|
|
65
|
-
url: (0, client_common_1.transformUrl)({ url: this.params.url, pathname:
|
|
63
|
+
query: "ping",
|
|
64
|
+
method: "GET",
|
|
65
|
+
url: (0, client_common_1.transformUrl)({ url: this.params.url, pathname: "/ping" }),
|
|
66
66
|
abort_signal: controller.signal,
|
|
67
67
|
headers: this.buildRequestHeaders(),
|
|
68
68
|
query_id,
|
|
69
69
|
log_writer,
|
|
70
70
|
log_level,
|
|
71
|
-
},
|
|
71
|
+
}, "Ping");
|
|
72
72
|
}
|
|
73
73
|
await (0, stream_1.drainStreamInternal)({
|
|
74
|
-
op:
|
|
74
|
+
op: "Ping",
|
|
75
75
|
log_writer,
|
|
76
76
|
query_id,
|
|
77
77
|
log_level,
|
|
@@ -81,11 +81,11 @@ class NodeBaseConnection {
|
|
|
81
81
|
catch (error) {
|
|
82
82
|
// it is used to ensure that the outgoing request is terminated,
|
|
83
83
|
// and we don't get unhandled error propagation later
|
|
84
|
-
controller.abort(
|
|
84
|
+
controller.abort("Ping failed");
|
|
85
85
|
// not an error, as this might be semi-expected
|
|
86
86
|
if (log_level <= client_common_1.ClickHouseLogLevel.WARN) {
|
|
87
87
|
log_writer.warn({
|
|
88
|
-
message: this.httpRequestErrorMessage(
|
|
88
|
+
message: this.httpRequestErrorMessage("Ping"),
|
|
89
89
|
err: error,
|
|
90
90
|
args: {
|
|
91
91
|
connection_id: this.connectionId,
|
|
@@ -106,9 +106,31 @@ class NodeBaseConnection {
|
|
|
106
106
|
const { log_writer, log_level } = this.params;
|
|
107
107
|
const query_id = this.getQueryId(params.query_id);
|
|
108
108
|
const clickhouse_settings = (0, client_common_1.withHttpSettings)(params.clickhouse_settings, this.params.compression.decompress_response);
|
|
109
|
+
const queryParams = params.query_params;
|
|
110
|
+
const hasQueryParams = queryParams !== undefined && Object.keys(queryParams).length > 0;
|
|
111
|
+
let useMultipart = hasQueryParams &&
|
|
112
|
+
(params.use_multipart_params ?? this.params.use_multipart_params);
|
|
113
|
+
// In auto mode, serialize the params for the URL once with an early
|
|
114
|
+
// return: a null result means they exceed the URL budget and should be
|
|
115
|
+
// promoted to a multipart body; otherwise the entries are reused below.
|
|
116
|
+
let urlParamEntries;
|
|
117
|
+
if (hasQueryParams &&
|
|
118
|
+
!useMultipart &&
|
|
119
|
+
(params.use_multipart_params_auto ??
|
|
120
|
+
this.params.use_multipart_params_auto)) {
|
|
121
|
+
const entries = (0, client_common_1.serializeQueryParamsForUrl)(queryParams);
|
|
122
|
+
if (entries === null) {
|
|
123
|
+
useMultipart = true;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
urlParamEntries = entries;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
109
129
|
const searchParams = (0, client_common_1.toSearchParams)({
|
|
110
130
|
database: this.params.database,
|
|
111
|
-
query_params
|
|
131
|
+
// When using multipart, query_params are sent in the multipart body
|
|
132
|
+
query_params: useMultipart ? undefined : params.query_params,
|
|
133
|
+
param_entries: urlParamEntries,
|
|
112
134
|
session_id: params.session_id,
|
|
113
135
|
clickhouse_settings,
|
|
114
136
|
query_id,
|
|
@@ -117,19 +139,30 @@ class NodeBaseConnection {
|
|
|
117
139
|
const { controller, controllerCleanup } = this.getAbortController(params);
|
|
118
140
|
// allows enforcing the compression via the settings even if the client instance has it disabled
|
|
119
141
|
const enableResponseCompression = clickhouse_settings.enable_http_compression === 1;
|
|
142
|
+
let body = params.query;
|
|
143
|
+
const headers = this.buildRequestHeaders(params);
|
|
144
|
+
if (useMultipart && params.query_params !== undefined) {
|
|
145
|
+
const boundary = `----clickhouse-js-${crypto_1.default.randomUUID()}`;
|
|
146
|
+
const parts = { query: params.query };
|
|
147
|
+
for (const [key, value] of Object.entries(params.query_params)) {
|
|
148
|
+
parts[`param_${key}`] = (0, client_common_1.formatQueryParams)({ value });
|
|
149
|
+
}
|
|
150
|
+
body = (0, client_common_1.buildMultipartBody)(parts, boundary);
|
|
151
|
+
headers["Content-Type"] = `multipart/form-data; boundary=${boundary}`;
|
|
152
|
+
}
|
|
120
153
|
try {
|
|
121
154
|
const { response_headers, stream, http_status_code } = await this.request({
|
|
122
|
-
method:
|
|
155
|
+
method: "POST",
|
|
123
156
|
url: (0, client_common_1.transformUrl)({ url: this.params.url, searchParams }),
|
|
124
|
-
body
|
|
157
|
+
body,
|
|
125
158
|
abort_signal: controller.signal,
|
|
126
159
|
enable_response_compression: enableResponseCompression,
|
|
127
|
-
headers
|
|
160
|
+
headers,
|
|
128
161
|
query: params.query,
|
|
129
162
|
query_id,
|
|
130
163
|
log_writer,
|
|
131
164
|
log_level,
|
|
132
|
-
},
|
|
165
|
+
}, "Query");
|
|
133
166
|
return {
|
|
134
167
|
stream,
|
|
135
168
|
response_headers,
|
|
@@ -138,9 +171,9 @@ class NodeBaseConnection {
|
|
|
138
171
|
};
|
|
139
172
|
}
|
|
140
173
|
catch (err) {
|
|
141
|
-
controller.abort(
|
|
174
|
+
controller.abort("Query HTTP request failed");
|
|
142
175
|
this.logRequestError({
|
|
143
|
-
op:
|
|
176
|
+
op: "Query",
|
|
144
177
|
query_id: query_id,
|
|
145
178
|
query_params: params,
|
|
146
179
|
search_params: searchParams,
|
|
@@ -171,7 +204,7 @@ class NodeBaseConnection {
|
|
|
171
204
|
const { controller, controllerCleanup } = this.getAbortController(params);
|
|
172
205
|
try {
|
|
173
206
|
const { stream, summary, response_headers, http_status_code } = await this.request({
|
|
174
|
-
method:
|
|
207
|
+
method: "POST",
|
|
175
208
|
url: (0, client_common_1.transformUrl)({ url: this.params.url, searchParams }),
|
|
176
209
|
body: params.values,
|
|
177
210
|
abort_signal: controller.signal,
|
|
@@ -182,9 +215,9 @@ class NodeBaseConnection {
|
|
|
182
215
|
query_id,
|
|
183
216
|
log_writer,
|
|
184
217
|
log_level,
|
|
185
|
-
},
|
|
218
|
+
}, "Insert");
|
|
186
219
|
await (0, stream_1.drainStreamInternal)({
|
|
187
|
-
op:
|
|
220
|
+
op: "Insert",
|
|
188
221
|
log_writer,
|
|
189
222
|
query_id,
|
|
190
223
|
log_level,
|
|
@@ -192,9 +225,9 @@ class NodeBaseConnection {
|
|
|
192
225
|
return { query_id, summary, response_headers, http_status_code };
|
|
193
226
|
}
|
|
194
227
|
catch (err) {
|
|
195
|
-
controller.abort(
|
|
228
|
+
controller.abort("Insert HTTP request failed");
|
|
196
229
|
this.logRequestError({
|
|
197
|
-
op:
|
|
230
|
+
op: "Insert",
|
|
198
231
|
query_id: query_id,
|
|
199
232
|
query_params: params,
|
|
200
233
|
search_params: searchParams,
|
|
@@ -214,7 +247,7 @@ class NodeBaseConnection {
|
|
|
214
247
|
return this.runExec({
|
|
215
248
|
...params,
|
|
216
249
|
query_id,
|
|
217
|
-
op:
|
|
250
|
+
op: "Exec",
|
|
218
251
|
});
|
|
219
252
|
}
|
|
220
253
|
async command(params) {
|
|
@@ -223,9 +256,9 @@ class NodeBaseConnection {
|
|
|
223
256
|
const commandStartTime = Date.now();
|
|
224
257
|
if (log_level <= client_common_1.ClickHouseLogLevel.TRACE) {
|
|
225
258
|
log_writer.trace({
|
|
226
|
-
message:
|
|
259
|
+
message: "Command: operation started",
|
|
227
260
|
args: {
|
|
228
|
-
operation:
|
|
261
|
+
operation: "Command",
|
|
229
262
|
connection_id: this.connectionId,
|
|
230
263
|
query_id,
|
|
231
264
|
},
|
|
@@ -234,14 +267,14 @@ class NodeBaseConnection {
|
|
|
234
267
|
const { stream, summary, response_headers } = await this.runExec({
|
|
235
268
|
...params,
|
|
236
269
|
query_id,
|
|
237
|
-
op:
|
|
270
|
+
op: "Command",
|
|
238
271
|
});
|
|
239
272
|
const runExecDuration = Date.now() - commandStartTime;
|
|
240
273
|
if (log_level <= client_common_1.ClickHouseLogLevel.TRACE) {
|
|
241
274
|
log_writer.trace({
|
|
242
|
-
message:
|
|
275
|
+
message: "Command: runExec completed, starting stream drain",
|
|
243
276
|
args: {
|
|
244
|
-
operation:
|
|
277
|
+
operation: "Command",
|
|
245
278
|
connection_id: this.connectionId,
|
|
246
279
|
query_id,
|
|
247
280
|
runExec_duration_ms: runExecDuration,
|
|
@@ -256,7 +289,7 @@ class NodeBaseConnection {
|
|
|
256
289
|
// ignore the response stream and release the socket immediately
|
|
257
290
|
const drainStartTime = Date.now();
|
|
258
291
|
await (0, stream_1.drainStreamInternal)({
|
|
259
|
-
op:
|
|
292
|
+
op: "Command",
|
|
260
293
|
log_writer,
|
|
261
294
|
query_id,
|
|
262
295
|
log_level,
|
|
@@ -265,9 +298,9 @@ class NodeBaseConnection {
|
|
|
265
298
|
const drainDuration = Date.now() - drainStartTime;
|
|
266
299
|
const totalDuration = Date.now() - commandStartTime;
|
|
267
300
|
log_writer.trace({
|
|
268
|
-
message:
|
|
301
|
+
message: "Command: operation completed",
|
|
269
302
|
args: {
|
|
270
|
-
operation:
|
|
303
|
+
operation: "Command",
|
|
271
304
|
connection_id: this.connectionId,
|
|
272
305
|
query_id,
|
|
273
306
|
drain_duration_ms: drainDuration,
|
|
@@ -306,7 +339,7 @@ class NodeBaseConnection {
|
|
|
306
339
|
if ((0, client_common_1.isCredentialsAuth)(params?.auth)) {
|
|
307
340
|
return {
|
|
308
341
|
...headers,
|
|
309
|
-
Authorization: `Basic ${Buffer.from(`${params.auth.username}:${params.auth.password}`).toString(
|
|
342
|
+
Authorization: `Basic ${Buffer.from(`${params.auth.username}:${params.auth.password}`).toString("base64")}`,
|
|
310
343
|
};
|
|
311
344
|
}
|
|
312
345
|
else {
|
|
@@ -329,11 +362,11 @@ class NodeBaseConnection {
|
|
|
329
362
|
function onAbort() {
|
|
330
363
|
controller.abort();
|
|
331
364
|
}
|
|
332
|
-
params.abort_signal?.addEventListener(
|
|
365
|
+
params.abort_signal?.addEventListener("abort", onAbort);
|
|
333
366
|
return {
|
|
334
367
|
controller,
|
|
335
368
|
controllerCleanup: () => {
|
|
336
|
-
params.abort_signal?.removeEventListener(
|
|
369
|
+
params.abort_signal?.removeEventListener("abort", onAbort);
|
|
337
370
|
},
|
|
338
371
|
};
|
|
339
372
|
}
|
|
@@ -372,7 +405,7 @@ class NodeBaseConnection {
|
|
|
372
405
|
};
|
|
373
406
|
const searchParams = (0, client_common_1.toSearchParams)(toSearchParamsOptions);
|
|
374
407
|
const { controller, controllerCleanup } = this.getAbortController(params);
|
|
375
|
-
const tryDecompressResponseStream = params.op ===
|
|
408
|
+
const tryDecompressResponseStream = params.op === "Exec"
|
|
376
409
|
? // allows disabling stream decompression for the `Exec` operation only
|
|
377
410
|
(params.decompress_response_stream ??
|
|
378
411
|
this.params.compression.decompress_response)
|
|
@@ -382,7 +415,7 @@ class NodeBaseConnection {
|
|
|
382
415
|
const ignoreErrorResponse = params.ignore_error_response ?? false;
|
|
383
416
|
try {
|
|
384
417
|
const { stream, summary, response_headers, http_status_code } = await this.request({
|
|
385
|
-
method:
|
|
418
|
+
method: "POST",
|
|
386
419
|
url: (0, client_common_1.transformUrl)({ url: this.params.url, searchParams }),
|
|
387
420
|
body: sendQueryInParams ? params.values : params.query,
|
|
388
421
|
abort_signal: controller.signal,
|