@effect/sql-clickhouse 0.45.0 → 4.0.0-beta.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/dist/{dts/ClickhouseClient.d.ts → ClickhouseClient.d.ts} +16 -18
- package/dist/ClickhouseClient.d.ts.map +1 -0
- package/dist/{esm/ClickhouseClient.js → ClickhouseClient.js} +50 -42
- package/dist/ClickhouseClient.js.map +1 -0
- package/dist/{dts/ClickhouseMigrator.d.ts → ClickhouseMigrator.d.ts} +4 -8
- package/dist/ClickhouseMigrator.d.ts.map +1 -0
- package/dist/{esm/ClickhouseMigrator.js → ClickhouseMigrator.js} +2 -9
- package/dist/ClickhouseMigrator.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/{esm/index.js → index.js} +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -51
- package/src/ClickhouseClient.ts +85 -82
- package/src/ClickhouseMigrator.ts +4 -9
- package/src/index.ts +8 -2
- package/ClickhouseClient/package.json +0 -6
- package/ClickhouseMigrator/package.json +0 -6
- package/dist/cjs/ClickhouseClient.js +0 -278
- package/dist/cjs/ClickhouseClient.js.map +0 -1
- package/dist/cjs/ClickhouseMigrator.js +0 -60
- package/dist/cjs/ClickhouseMigrator.js.map +0 -1
- package/dist/cjs/index.js +0 -12
- package/dist/cjs/index.js.map +0 -1
- package/dist/dts/ClickhouseClient.d.ts.map +0 -1
- package/dist/dts/ClickhouseMigrator.d.ts.map +0 -1
- package/dist/dts/index.d.ts +0 -9
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/esm/ClickhouseClient.js.map +0 -1
- package/dist/esm/ClickhouseMigrator.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/package.json +0 -4
- package/index/package.json +0 -6
package/src/ClickhouseClient.ts
CHANGED
|
@@ -2,24 +2,21 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Clickhouse from "@clickhouse/client"
|
|
5
|
-
import * as Reactivity from "@effect/experimental/Reactivity"
|
|
6
5
|
import * as NodeStream from "@effect/platform-node/NodeStream"
|
|
7
|
-
import * as Client from "@effect/sql/SqlClient"
|
|
8
|
-
import type { Connection } from "@effect/sql/SqlConnection"
|
|
9
|
-
import { SqlError } from "@effect/sql/SqlError"
|
|
10
|
-
import * as Statement from "@effect/sql/Statement"
|
|
11
|
-
import * as Chunk from "effect/Chunk"
|
|
12
6
|
import * as Config from "effect/Config"
|
|
13
|
-
import type { ConfigError } from "effect/ConfigError"
|
|
14
|
-
import * as Context from "effect/Context"
|
|
15
7
|
import * as Duration from "effect/Duration"
|
|
16
8
|
import * as Effect from "effect/Effect"
|
|
17
|
-
import * as
|
|
9
|
+
import * as Fiber from "effect/Fiber"
|
|
18
10
|
import { dual } from "effect/Function"
|
|
19
|
-
import { globalValue } from "effect/GlobalValue"
|
|
20
11
|
import * as Layer from "effect/Layer"
|
|
21
12
|
import type * as Scope from "effect/Scope"
|
|
13
|
+
import * as ServiceMap from "effect/ServiceMap"
|
|
22
14
|
import * as Stream from "effect/Stream"
|
|
15
|
+
import * as Reactivity from "effect/unstable/reactivity/Reactivity"
|
|
16
|
+
import * as Client from "effect/unstable/sql/SqlClient"
|
|
17
|
+
import type { Connection } from "effect/unstable/sql/SqlConnection"
|
|
18
|
+
import { SqlError } from "effect/unstable/sql/SqlError"
|
|
19
|
+
import * as Statement from "effect/unstable/sql/Statement"
|
|
23
20
|
import * as Crypto from "node:crypto"
|
|
24
21
|
import type { Readable } from "node:stream"
|
|
25
22
|
|
|
@@ -30,13 +27,13 @@ const ATTR_DB_NAMESPACE = "db.namespace"
|
|
|
30
27
|
* @category type ids
|
|
31
28
|
* @since 1.0.0
|
|
32
29
|
*/
|
|
33
|
-
export const TypeId:
|
|
30
|
+
export const TypeId: TypeId = "~@effect/sql-clickhouse/ClickhouseClient"
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
33
|
* @category type ids
|
|
37
34
|
* @since 1.0.0
|
|
38
35
|
*/
|
|
39
|
-
export type TypeId =
|
|
36
|
+
export type TypeId = "~@effect/sql-clickhouse/ClickhouseClient"
|
|
40
37
|
|
|
41
38
|
/**
|
|
42
39
|
* @category models
|
|
@@ -71,7 +68,7 @@ export interface ClickhouseClient extends Client.SqlClient {
|
|
|
71
68
|
* @category tags
|
|
72
69
|
* @since 1.0.0
|
|
73
70
|
*/
|
|
74
|
-
export const ClickhouseClient =
|
|
71
|
+
export const ClickhouseClient = ServiceMap.Service<ClickhouseClient>("@effect/sql-clickhouse/ClickhouseClient")
|
|
75
72
|
|
|
76
73
|
/**
|
|
77
74
|
* @category constructors
|
|
@@ -105,29 +102,34 @@ export const make = (
|
|
|
105
102
|
}),
|
|
106
103
|
() => Effect.promise(() => client.close())
|
|
107
104
|
).pipe(
|
|
108
|
-
Effect.
|
|
105
|
+
Effect.timeoutOrElse({
|
|
109
106
|
duration: Duration.seconds(5),
|
|
110
107
|
onTimeout: () =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
Effect.fail(
|
|
109
|
+
new SqlError({
|
|
110
|
+
message: "ClickhouseClient: Connection timeout",
|
|
111
|
+
cause: new Error("connection timeout")
|
|
112
|
+
})
|
|
113
|
+
)
|
|
115
114
|
})
|
|
116
115
|
)
|
|
117
116
|
|
|
118
117
|
class ConnectionImpl implements Connection {
|
|
119
|
-
|
|
118
|
+
private conn: Clickhouse.ClickHouseClient
|
|
119
|
+
constructor(conn: Clickhouse.ClickHouseClient) {
|
|
120
|
+
this.conn = conn
|
|
121
|
+
}
|
|
120
122
|
|
|
121
123
|
private runRaw(sql: string, params: ReadonlyArray<unknown>, format: Clickhouse.DataFormat = "JSON") {
|
|
122
124
|
const paramsObj: Record<string, unknown> = {}
|
|
123
125
|
for (let i = 0; i < params.length; i++) {
|
|
124
126
|
paramsObj[`p${i + 1}`] = params[i]
|
|
125
127
|
}
|
|
126
|
-
return Effect.
|
|
127
|
-
const method = fiber.
|
|
128
|
-
return Effect.
|
|
129
|
-
const queryId = fiber.
|
|
130
|
-
const settings = fiber.
|
|
128
|
+
return Effect.withFiber<Clickhouse.ResultSet<"JSON"> | Clickhouse.CommandResult, SqlError>((fiber) => {
|
|
129
|
+
const method = fiber.getRef(ClientMethod)
|
|
130
|
+
return Effect.callback<Clickhouse.ResultSet<"JSON"> | Clickhouse.CommandResult, SqlError>((resume) => {
|
|
131
|
+
const queryId = fiber.getRef(QueryId) ?? Crypto.randomUUID()
|
|
132
|
+
const settings = fiber.getRef(ClickhouseSettings)
|
|
131
133
|
const controller = new AbortController()
|
|
132
134
|
if (method === "command") {
|
|
133
135
|
this.conn.command({
|
|
@@ -205,10 +207,10 @@ export const make = (
|
|
|
205
207
|
if (!("stream" in result)) {
|
|
206
208
|
return Stream.empty
|
|
207
209
|
}
|
|
208
|
-
return NodeStream.fromReadable<
|
|
209
|
-
() => result.stream() as any,
|
|
210
|
-
(cause) => new SqlError({ cause, message: "Failed to execute stream" })
|
|
211
|
-
)
|
|
210
|
+
return NodeStream.fromReadable<ReadonlyArray<Clickhouse.Row<any, "JSONEachRow">>, SqlError>({
|
|
211
|
+
evaluate: () => result.stream() as any,
|
|
212
|
+
onError: (cause) => new SqlError({ cause, message: "Failed to execute stream" })
|
|
213
|
+
})
|
|
212
214
|
}),
|
|
213
215
|
Stream.unwrap,
|
|
214
216
|
Stream.chunks,
|
|
@@ -220,12 +222,11 @@ export const make = (
|
|
|
220
222
|
}
|
|
221
223
|
}
|
|
222
224
|
return Effect.tryPromise({
|
|
223
|
-
try: () =>
|
|
224
|
-
Promise.all(promises).then((rows) => Chunk.unsafeFromArray(transformRows ? transformRows(rows) : rows)),
|
|
225
|
+
try: () => Promise.all(promises).then((rows) => transformRows ? transformRows(rows) : rows),
|
|
225
226
|
catch: (cause) => new SqlError({ cause, message: "Failed to parse row" })
|
|
226
227
|
})
|
|
227
228
|
}),
|
|
228
|
-
Stream.
|
|
229
|
+
Stream.flattenIterable
|
|
229
230
|
)
|
|
230
231
|
}
|
|
231
232
|
}
|
|
@@ -248,94 +249,96 @@ export const make = (
|
|
|
248
249
|
[TypeId]: TypeId as TypeId,
|
|
249
250
|
config: options,
|
|
250
251
|
param(dataType: string, value: unknown) {
|
|
251
|
-
return clickhouseParam(dataType, value)
|
|
252
|
+
return Statement.fragment([clickhouseParam(dataType, value)])
|
|
252
253
|
},
|
|
253
254
|
asCommand<A, E, R>(effect: Effect.Effect<A, E, R>) {
|
|
254
|
-
return Effect.
|
|
255
|
+
return Effect.provideService(effect, ClientMethod, "command")
|
|
255
256
|
},
|
|
256
257
|
insertQuery<T = unknown>(options: {
|
|
257
258
|
readonly table: string
|
|
258
259
|
readonly values: Clickhouse.InsertValues<Readable, T>
|
|
259
260
|
readonly format?: Clickhouse.DataFormat
|
|
260
261
|
}) {
|
|
261
|
-
return Effect.
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
})
|
|
262
|
+
return Effect.callback<Clickhouse.InsertResult, SqlError>((resume) => {
|
|
263
|
+
const fiber = Fiber.getCurrent()!
|
|
264
|
+
const queryId = fiber.getRef(QueryId) ?? Crypto.randomUUID()
|
|
265
|
+
const settings = fiber.getRef(ClickhouseSettings)
|
|
266
|
+
const controller = new AbortController()
|
|
267
|
+
client.insert({
|
|
268
|
+
format: "JSONEachRow",
|
|
269
|
+
...options,
|
|
270
|
+
abort_signal: controller.signal,
|
|
271
|
+
query_id: queryId,
|
|
272
|
+
clickhouse_settings: settings
|
|
273
|
+
}).then(
|
|
274
|
+
(result) => resume(Effect.succeed(result)),
|
|
275
|
+
(cause) => resume(Effect.fail(new SqlError({ cause, message: "Failed to insert data" })))
|
|
276
|
+
)
|
|
277
|
+
return Effect.suspend(() => {
|
|
278
|
+
controller.abort()
|
|
279
|
+
return Effect.promise(() => client.command({ query: `KILL QUERY WHERE query_id = '${queryId}'` }))
|
|
280
280
|
})
|
|
281
|
-
)
|
|
281
|
+
})
|
|
282
282
|
},
|
|
283
283
|
withQueryId: dual(2, <A, E, R>(effect: Effect.Effect<A, E, R>, queryId: string) =>
|
|
284
|
-
Effect.
|
|
284
|
+
Effect.provideService(effect, QueryId, queryId)),
|
|
285
285
|
withClickhouseSettings: dual(
|
|
286
286
|
2,
|
|
287
287
|
<A, E, R>(
|
|
288
288
|
effect: Effect.Effect<A, E, R>,
|
|
289
289
|
settings: NonNullable<Clickhouse.BaseQueryParams["clickhouse_settings"]>
|
|
290
290
|
) =>
|
|
291
|
-
Effect.
|
|
291
|
+
Effect.provideService(effect, ClickhouseSettings, settings)
|
|
292
292
|
)
|
|
293
293
|
}
|
|
294
294
|
)
|
|
295
295
|
})
|
|
296
296
|
|
|
297
297
|
/**
|
|
298
|
-
* @category
|
|
298
|
+
* @category References
|
|
299
299
|
* @since 1.0.0
|
|
300
300
|
*/
|
|
301
|
-
export const
|
|
302
|
-
"@effect/sql-clickhouse/ClickhouseClient/
|
|
303
|
-
|
|
301
|
+
export const ClientMethod = ServiceMap.Reference<"query" | "command" | "insert">(
|
|
302
|
+
"@effect/sql-clickhouse/ClickhouseClient/ClientMethod",
|
|
303
|
+
{
|
|
304
|
+
defaultValue: () => "query"
|
|
305
|
+
}
|
|
304
306
|
)
|
|
305
307
|
|
|
306
308
|
/**
|
|
307
|
-
* @category
|
|
309
|
+
* @category References
|
|
308
310
|
* @since 1.0.0
|
|
309
311
|
*/
|
|
310
|
-
export const
|
|
311
|
-
"@effect/sql-clickhouse/ClickhouseClient/
|
|
312
|
-
() =>
|
|
312
|
+
export const QueryId = ServiceMap.Reference<string | undefined>(
|
|
313
|
+
"@effect/sql-clickhouse/ClickhouseClient/QueryId",
|
|
314
|
+
{ defaultValue: () => undefined }
|
|
313
315
|
)
|
|
314
316
|
|
|
315
317
|
/**
|
|
316
|
-
* @category
|
|
318
|
+
* @category References
|
|
317
319
|
* @since 1.0.0
|
|
318
320
|
*/
|
|
319
|
-
export const
|
|
321
|
+
export const ClickhouseSettings: ServiceMap.Reference<
|
|
320
322
|
NonNullable<Clickhouse.BaseQueryParams["clickhouse_settings"]>
|
|
321
|
-
> =
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
)
|
|
323
|
+
> = ServiceMap.Reference("@effect/sql-clickhouse/ClickhouseClient/ClickhouseSettings", {
|
|
324
|
+
defaultValue: () => ({})
|
|
325
|
+
})
|
|
325
326
|
|
|
326
327
|
/**
|
|
327
328
|
* @category layers
|
|
328
329
|
* @since 1.0.0
|
|
329
330
|
*/
|
|
330
|
-
export const layerConfig
|
|
331
|
-
config: Config.
|
|
332
|
-
)
|
|
333
|
-
|
|
334
|
-
|
|
331
|
+
export const layerConfig: (
|
|
332
|
+
config: Config.Wrap<ClickhouseClientConfig>
|
|
333
|
+
) => Layer.Layer<ClickhouseClient | Client.SqlClient, Config.ConfigError | SqlError> = (
|
|
334
|
+
config: Config.Wrap<ClickhouseClientConfig>
|
|
335
|
+
): Layer.Layer<ClickhouseClient | Client.SqlClient, Config.ConfigError | SqlError> =>
|
|
336
|
+
Layer.effectServices(
|
|
337
|
+
Config.unwrap(config).asEffect().pipe(
|
|
335
338
|
Effect.flatMap(make),
|
|
336
339
|
Effect.map((client) =>
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
ServiceMap.make(ClickhouseClient, client).pipe(
|
|
341
|
+
ServiceMap.add(Client.SqlClient, client)
|
|
339
342
|
)
|
|
340
343
|
)
|
|
341
344
|
)
|
|
@@ -347,11 +350,11 @@ export const layerConfig = (
|
|
|
347
350
|
*/
|
|
348
351
|
export const layer = (
|
|
349
352
|
config: ClickhouseClientConfig
|
|
350
|
-
): Layer.Layer<ClickhouseClient | Client.SqlClient, ConfigError | SqlError> =>
|
|
351
|
-
Layer.
|
|
353
|
+
): Layer.Layer<ClickhouseClient | Client.SqlClient, Config.ConfigError | SqlError> =>
|
|
354
|
+
Layer.effectServices(
|
|
352
355
|
Effect.map(make(config), (client) =>
|
|
353
|
-
|
|
354
|
-
|
|
356
|
+
ServiceMap.make(ClickhouseClient, client).pipe(
|
|
357
|
+
ServiceMap.add(Client.SqlClient, client)
|
|
355
358
|
))
|
|
356
359
|
).pipe(Layer.provide(Reactivity.layer))
|
|
357
360
|
|
|
@@ -359,7 +362,7 @@ const typeFromUnknown = (value: unknown): string => {
|
|
|
359
362
|
if (Statement.isFragment(value)) {
|
|
360
363
|
return typeFromUnknown(value.segments[0])
|
|
361
364
|
} else if (isClickhouseParam(value)) {
|
|
362
|
-
return value.
|
|
365
|
+
return value.paramA
|
|
363
366
|
} else if (Array.isArray(value)) {
|
|
364
367
|
return `Array(${typeFromUnknown(value[0])})`
|
|
365
368
|
}
|
|
@@ -399,7 +402,7 @@ export const makeCompiler = (transform?: (_: string) => string) =>
|
|
|
399
402
|
return ["", []]
|
|
400
403
|
},
|
|
401
404
|
onCustom(type, placeholder) {
|
|
402
|
-
return [placeholder(type), [type.
|
|
405
|
+
return [placeholder(type), [type.paramB]]
|
|
403
406
|
}
|
|
404
407
|
})
|
|
405
408
|
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import * as Migrator from "@effect/sql/Migrator"
|
|
5
|
-
import type * as Client from "@effect/sql/SqlClient"
|
|
6
|
-
import type { SqlError } from "@effect/sql/SqlError"
|
|
7
4
|
import type * as Effect from "effect/Effect"
|
|
8
5
|
import * as Layer from "effect/Layer"
|
|
6
|
+
import * as Migrator from "effect/unstable/sql/Migrator"
|
|
7
|
+
import type * as Client from "effect/unstable/sql/SqlClient"
|
|
8
|
+
import type { SqlError } from "effect/unstable/sql/SqlError"
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @since 1.0.0
|
|
12
12
|
*/
|
|
13
|
-
export * from "
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @since 1.0.0
|
|
17
|
-
*/
|
|
18
|
-
export * from "@effect/sql/Migrator/FileSystem"
|
|
13
|
+
export * from "effect/unstable/sql/Migrator"
|
|
19
14
|
|
|
20
15
|
/**
|
|
21
16
|
* @category constructor
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// @barrel: Auto-generated exports. Do not edit manually.
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @since 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
export * as ClickhouseClient from "./ClickhouseClient.ts"
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* @since 1.0.0
|
|
8
14
|
*/
|
|
9
|
-
export * as ClickhouseMigrator from "./ClickhouseMigrator.
|
|
15
|
+
export * as ClickhouseMigrator from "./ClickhouseMigrator.ts"
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.makeCompiler = exports.make = exports.layerConfig = exports.layer = exports.currentQueryId = exports.currentClientMethod = exports.currentClickhouseSettings = exports.TypeId = exports.ClickhouseClient = void 0;
|
|
7
|
-
var Clickhouse = _interopRequireWildcard(require("@clickhouse/client"));
|
|
8
|
-
var Reactivity = _interopRequireWildcard(require("@effect/experimental/Reactivity"));
|
|
9
|
-
var NodeStream = _interopRequireWildcard(require("@effect/platform-node/NodeStream"));
|
|
10
|
-
var Client = _interopRequireWildcard(require("@effect/sql/SqlClient"));
|
|
11
|
-
var _SqlError = require("@effect/sql/SqlError");
|
|
12
|
-
var Statement = _interopRequireWildcard(require("@effect/sql/Statement"));
|
|
13
|
-
var Chunk = _interopRequireWildcard(require("effect/Chunk"));
|
|
14
|
-
var Config = _interopRequireWildcard(require("effect/Config"));
|
|
15
|
-
var Context = _interopRequireWildcard(require("effect/Context"));
|
|
16
|
-
var Duration = _interopRequireWildcard(require("effect/Duration"));
|
|
17
|
-
var Effect = _interopRequireWildcard(require("effect/Effect"));
|
|
18
|
-
var FiberRef = _interopRequireWildcard(require("effect/FiberRef"));
|
|
19
|
-
var _Function = require("effect/Function");
|
|
20
|
-
var _GlobalValue = require("effect/GlobalValue");
|
|
21
|
-
var Layer = _interopRequireWildcard(require("effect/Layer"));
|
|
22
|
-
var Stream = _interopRequireWildcard(require("effect/Stream"));
|
|
23
|
-
var Crypto = _interopRequireWildcard(require("node:crypto"));
|
|
24
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
25
|
-
/**
|
|
26
|
-
* @since 1.0.0
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
const ATTR_DB_SYSTEM_NAME = "db.system.name";
|
|
30
|
-
const ATTR_DB_NAMESPACE = "db.namespace";
|
|
31
|
-
/**
|
|
32
|
-
* @category type ids
|
|
33
|
-
* @since 1.0.0
|
|
34
|
-
*/
|
|
35
|
-
const TypeId = exports.TypeId = /*#__PURE__*/Symbol.for("@effect/sql-clickhouse/ClickhouseClient");
|
|
36
|
-
/**
|
|
37
|
-
* @category tags
|
|
38
|
-
* @since 1.0.0
|
|
39
|
-
*/
|
|
40
|
-
const ClickhouseClient = exports.ClickhouseClient = /*#__PURE__*/Context.GenericTag("@effect/sql-clickhouse/ClickhouseClient");
|
|
41
|
-
/**
|
|
42
|
-
* @category constructors
|
|
43
|
-
* @since 1.0.0
|
|
44
|
-
*/
|
|
45
|
-
const make = options => Effect.gen(function* () {
|
|
46
|
-
const compiler = makeCompiler(options.transformQueryNames);
|
|
47
|
-
const transformRows = options.transformResultNames ? Statement.defaultTransforms(options.transformResultNames).array : undefined;
|
|
48
|
-
const client = Clickhouse.createClient(options);
|
|
49
|
-
yield* Effect.acquireRelease(Effect.tryPromise({
|
|
50
|
-
try: () => client.exec({
|
|
51
|
-
query: "SELECT 1"
|
|
52
|
-
}),
|
|
53
|
-
catch: cause => new _SqlError.SqlError({
|
|
54
|
-
cause,
|
|
55
|
-
message: "ClickhouseClient: Failed to connect"
|
|
56
|
-
})
|
|
57
|
-
}), () => Effect.promise(() => client.close())).pipe(Effect.timeoutFail({
|
|
58
|
-
duration: Duration.seconds(5),
|
|
59
|
-
onTimeout: () => new _SqlError.SqlError({
|
|
60
|
-
message: "ClickhouseClient: Connection timeout",
|
|
61
|
-
cause: new Error("connection timeout")
|
|
62
|
-
})
|
|
63
|
-
}));
|
|
64
|
-
class ConnectionImpl {
|
|
65
|
-
conn;
|
|
66
|
-
constructor(conn) {
|
|
67
|
-
this.conn = conn;
|
|
68
|
-
}
|
|
69
|
-
runRaw(sql, params, format = "JSON") {
|
|
70
|
-
const paramsObj = {};
|
|
71
|
-
for (let i = 0; i < params.length; i++) {
|
|
72
|
-
paramsObj[`p${i + 1}`] = params[i];
|
|
73
|
-
}
|
|
74
|
-
return Effect.withFiberRuntime(fiber => {
|
|
75
|
-
const method = fiber.getFiberRef(currentClientMethod);
|
|
76
|
-
return Effect.async(resume => {
|
|
77
|
-
const queryId = fiber.getFiberRef(currentQueryId) ?? Crypto.randomUUID();
|
|
78
|
-
const settings = fiber.getFiberRef(currentClickhouseSettings) ?? {};
|
|
79
|
-
const controller = new AbortController();
|
|
80
|
-
if (method === "command") {
|
|
81
|
-
this.conn.command({
|
|
82
|
-
query: sql,
|
|
83
|
-
query_params: paramsObj,
|
|
84
|
-
abort_signal: controller.signal,
|
|
85
|
-
query_id: queryId,
|
|
86
|
-
clickhouse_settings: settings
|
|
87
|
-
}).then(result => resume(Effect.succeed(result)), cause => resume(Effect.fail(new _SqlError.SqlError({
|
|
88
|
-
cause,
|
|
89
|
-
message: "Failed to execute statement"
|
|
90
|
-
}))));
|
|
91
|
-
} else {
|
|
92
|
-
this.conn.query({
|
|
93
|
-
query: sql,
|
|
94
|
-
query_params: paramsObj,
|
|
95
|
-
abort_signal: controller.signal,
|
|
96
|
-
query_id: queryId,
|
|
97
|
-
clickhouse_settings: settings,
|
|
98
|
-
format
|
|
99
|
-
}).then(result => resume(Effect.succeed(result)), cause => resume(Effect.fail(new _SqlError.SqlError({
|
|
100
|
-
cause,
|
|
101
|
-
message: "Failed to execute statement"
|
|
102
|
-
}))));
|
|
103
|
-
}
|
|
104
|
-
return Effect.suspend(() => {
|
|
105
|
-
controller.abort();
|
|
106
|
-
return Effect.promise(() => this.conn.command({
|
|
107
|
-
query: `KILL QUERY WHERE query_id = '${queryId}'`
|
|
108
|
-
}));
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
run(sql, params, format) {
|
|
114
|
-
return this.runRaw(sql, params, format).pipe(Effect.flatMap(result => {
|
|
115
|
-
if ("json" in result) {
|
|
116
|
-
return Effect.promise(() => result.json().then(result => "data" in result ? result.data : result, () => []));
|
|
117
|
-
}
|
|
118
|
-
return Effect.succeed([]);
|
|
119
|
-
}));
|
|
120
|
-
}
|
|
121
|
-
execute(sql, params, transformRows) {
|
|
122
|
-
return transformRows ? Effect.map(this.run(sql, params), transformRows) : this.run(sql, params);
|
|
123
|
-
}
|
|
124
|
-
executeRaw(sql, params) {
|
|
125
|
-
return this.runRaw(sql, params);
|
|
126
|
-
}
|
|
127
|
-
executeValues(sql, params) {
|
|
128
|
-
return this.run(sql, params, "JSONCompact");
|
|
129
|
-
}
|
|
130
|
-
executeUnprepared(sql, params, transformRows) {
|
|
131
|
-
return this.execute(sql, params, transformRows);
|
|
132
|
-
}
|
|
133
|
-
executeStream(sql, params, transformRows) {
|
|
134
|
-
return this.runRaw(sql, params, "JSONEachRow").pipe(Effect.map(result => {
|
|
135
|
-
if (!("stream" in result)) {
|
|
136
|
-
return Stream.empty;
|
|
137
|
-
}
|
|
138
|
-
return NodeStream.fromReadable(() => result.stream(), cause => new _SqlError.SqlError({
|
|
139
|
-
cause,
|
|
140
|
-
message: "Failed to execute stream"
|
|
141
|
-
}));
|
|
142
|
-
}), Stream.unwrap, Stream.chunks, Stream.mapEffect(chunk => {
|
|
143
|
-
const promises = [];
|
|
144
|
-
for (const rows of chunk) {
|
|
145
|
-
for (const row of rows) {
|
|
146
|
-
promises.push(row.json());
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return Effect.tryPromise({
|
|
150
|
-
try: () => Promise.all(promises).then(rows => Chunk.unsafeFromArray(transformRows ? transformRows(rows) : rows)),
|
|
151
|
-
catch: cause => new _SqlError.SqlError({
|
|
152
|
-
cause,
|
|
153
|
-
message: "Failed to parse row"
|
|
154
|
-
})
|
|
155
|
-
});
|
|
156
|
-
}), Stream.flattenChunks);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const connection = new ConnectionImpl(client);
|
|
160
|
-
return Object.assign(yield* Client.make({
|
|
161
|
-
acquirer: Effect.succeed(connection),
|
|
162
|
-
compiler,
|
|
163
|
-
spanAttributes: [...(options.spanAttributes ? Object.entries(options.spanAttributes) : []), [ATTR_DB_SYSTEM_NAME, "clickhouse"], [ATTR_DB_NAMESPACE, options.database ?? "default"]],
|
|
164
|
-
beginTransaction: "BEGIN TRANSACTION",
|
|
165
|
-
transformRows
|
|
166
|
-
}), {
|
|
167
|
-
[TypeId]: TypeId,
|
|
168
|
-
config: options,
|
|
169
|
-
param(dataType, value) {
|
|
170
|
-
return clickhouseParam(dataType, value);
|
|
171
|
-
},
|
|
172
|
-
asCommand(effect) {
|
|
173
|
-
return Effect.locally(effect, currentClientMethod, "command");
|
|
174
|
-
},
|
|
175
|
-
insertQuery(options) {
|
|
176
|
-
return Effect.withFiberRuntime(fiber => Effect.async(resume => {
|
|
177
|
-
const queryId = fiber.getFiberRef(currentQueryId) ?? Crypto.randomUUID();
|
|
178
|
-
const settings = fiber.getFiberRef(currentClickhouseSettings);
|
|
179
|
-
const controller = new AbortController();
|
|
180
|
-
client.insert({
|
|
181
|
-
format: "JSONEachRow",
|
|
182
|
-
...options,
|
|
183
|
-
abort_signal: controller.signal,
|
|
184
|
-
query_id: queryId,
|
|
185
|
-
clickhouse_settings: settings
|
|
186
|
-
}).then(result => resume(Effect.succeed(result)), cause => resume(Effect.fail(new _SqlError.SqlError({
|
|
187
|
-
cause,
|
|
188
|
-
message: "Failed to insert data"
|
|
189
|
-
}))));
|
|
190
|
-
return Effect.suspend(() => {
|
|
191
|
-
controller.abort();
|
|
192
|
-
return Effect.promise(() => client.command({
|
|
193
|
-
query: `KILL QUERY WHERE query_id = '${queryId}'`
|
|
194
|
-
}));
|
|
195
|
-
});
|
|
196
|
-
}));
|
|
197
|
-
},
|
|
198
|
-
withQueryId: (0, _Function.dual)(2, (effect, queryId) => Effect.locally(effect, currentQueryId, queryId)),
|
|
199
|
-
withClickhouseSettings: (0, _Function.dual)(2, (effect, settings) => Effect.locally(effect, currentClickhouseSettings, settings))
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
/**
|
|
203
|
-
* @category fiber refs
|
|
204
|
-
* @since 1.0.0
|
|
205
|
-
*/
|
|
206
|
-
exports.make = make;
|
|
207
|
-
const currentClientMethod = exports.currentClientMethod = /*#__PURE__*/(0, _GlobalValue.globalValue)("@effect/sql-clickhouse/ClickhouseClient/currentClientMethod", () => FiberRef.unsafeMake("query"));
|
|
208
|
-
/**
|
|
209
|
-
* @category fiber refs
|
|
210
|
-
* @since 1.0.0
|
|
211
|
-
*/
|
|
212
|
-
const currentQueryId = exports.currentQueryId = /*#__PURE__*/(0, _GlobalValue.globalValue)("@effect/sql-clickhouse/ClickhouseClient/currentQueryId", () => FiberRef.unsafeMake(undefined));
|
|
213
|
-
/**
|
|
214
|
-
* @category fiber refs
|
|
215
|
-
* @since 1.0.0
|
|
216
|
-
*/
|
|
217
|
-
const currentClickhouseSettings = exports.currentClickhouseSettings = /*#__PURE__*/(0, _GlobalValue.globalValue)("@effect/sql-clickhouse/ClickhouseClient/currentClickhouseSettings", () => FiberRef.unsafeMake({}));
|
|
218
|
-
/**
|
|
219
|
-
* @category layers
|
|
220
|
-
* @since 1.0.0
|
|
221
|
-
*/
|
|
222
|
-
const layerConfig = config => Layer.scopedContext(Config.unwrap(config).pipe(Effect.flatMap(make), Effect.map(client => Context.make(ClickhouseClient, client).pipe(Context.add(Client.SqlClient, client))))).pipe(Layer.provide(Reactivity.layer));
|
|
223
|
-
/**
|
|
224
|
-
* @category layers
|
|
225
|
-
* @since 1.0.0
|
|
226
|
-
*/
|
|
227
|
-
exports.layerConfig = layerConfig;
|
|
228
|
-
const layer = config => Layer.scopedContext(Effect.map(make(config), client => Context.make(ClickhouseClient, client).pipe(Context.add(Client.SqlClient, client)))).pipe(Layer.provide(Reactivity.layer));
|
|
229
|
-
exports.layer = layer;
|
|
230
|
-
const typeFromUnknown = value => {
|
|
231
|
-
if (Statement.isFragment(value)) {
|
|
232
|
-
return typeFromUnknown(value.segments[0]);
|
|
233
|
-
} else if (isClickhouseParam(value)) {
|
|
234
|
-
return value.i0;
|
|
235
|
-
} else if (Array.isArray(value)) {
|
|
236
|
-
return `Array(${typeFromUnknown(value[0])})`;
|
|
237
|
-
}
|
|
238
|
-
switch (typeof value) {
|
|
239
|
-
case "number":
|
|
240
|
-
return "Decimal";
|
|
241
|
-
case "bigint":
|
|
242
|
-
return "Int64";
|
|
243
|
-
case "boolean":
|
|
244
|
-
return "Bool";
|
|
245
|
-
case "object":
|
|
246
|
-
if (value instanceof Date) {
|
|
247
|
-
return "DateTime()";
|
|
248
|
-
}
|
|
249
|
-
return "String";
|
|
250
|
-
default:
|
|
251
|
-
return "String";
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
/**
|
|
255
|
-
* @category compiler
|
|
256
|
-
* @since 1.0.0
|
|
257
|
-
*/
|
|
258
|
-
const makeCompiler = transform => Statement.makeCompiler({
|
|
259
|
-
dialect: "sqlite",
|
|
260
|
-
placeholder(i, u) {
|
|
261
|
-
return `{p${i}: ${typeFromUnknown(u)}}`;
|
|
262
|
-
},
|
|
263
|
-
onIdentifier: transform ? function (value, withoutTransform) {
|
|
264
|
-
return withoutTransform ? escape(value) : escape(transform(value));
|
|
265
|
-
} : escape,
|
|
266
|
-
onRecordUpdate() {
|
|
267
|
-
return ["", []];
|
|
268
|
-
},
|
|
269
|
-
onCustom(type, placeholder) {
|
|
270
|
-
return [placeholder(type), [type.i1]];
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
// compiler helpers
|
|
274
|
-
exports.makeCompiler = makeCompiler;
|
|
275
|
-
const escape = /*#__PURE__*/Statement.defaultEscape("\"");
|
|
276
|
-
const clickhouseParam = /*#__PURE__*/Statement.custom("ClickhouseParam");
|
|
277
|
-
const isClickhouseParam = /*#__PURE__*/Statement.isCustom("ClickhouseParam");
|
|
278
|
-
//# sourceMappingURL=ClickhouseClient.js.map
|