| 167 | * @since 4.0.0 |
| 168 | */ |
| 169 | export const make = ( |
| 170 | options: ClickhouseClientConfig |
| 171 | ): Effect.Effect<ClickhouseClient, SqlError, Scope.Scope | Reactivity.Reactivity> => |
| 172 | Effect.gen(function*() { |
| 173 | const compiler = makeCompiler(options.transformQueryNames) |
| 174 | const transformRows = options.transformResultNames |
| 175 | ? Statement.defaultTransforms(options.transformResultNames).array |
| 176 | : undefined |
| 177 | |
| 178 | const client = yield* Effect.acquireRelease( |
| 179 | Effect.sync(() => Clickhouse.createClient(options)), |
| 180 | (client) => Effect.promise(() => client.close()) |
| 181 | ) |
| 182 | |
| 183 | yield* Effect.tryPromise({ |
| 184 | try: () => client.exec({ query: "SELECT 1" }), |
| 185 | catch: (cause) => |
| 186 | new SqlError({ reason: classifyError(cause, "ClickhouseClient: Failed to connect", "connect", "connection") }) |
| 187 | }).pipe( |
| 188 | Effect.timeoutOrElse({ |
| 189 | duration: Duration.seconds(5), |
| 190 | orElse: () => |
| 191 | Effect.fail( |
| 192 | new SqlError({ |
| 193 | reason: new ConnectionError({ |
| 194 | message: "ClickhouseClient: Connection timeout", |
| 195 | cause: new Error("connection timeout"), |
| 196 | operation: "connect" |
| 197 | }) |
| 198 | }) |
| 199 | ) |
| 200 | }) |
| 201 | ) |
| 202 | |
| 203 | class ConnectionImpl implements Connection { |
| 204 | private conn: Clickhouse.ClickHouseClient |
| 205 | constructor(conn: Clickhouse.ClickHouseClient) { |
| 206 | this.conn = conn |
| 207 | } |
| 208 | |
| 209 | private runRaw(sql: string, params: ReadonlyArray<unknown>, format: Clickhouse.DataFormat = "JSON") { |
| 210 | const paramsObj: Record<string, unknown> = {} |
| 211 | for (let i = 0; i < params.length; i++) { |
| 212 | paramsObj[`p${i + 1}`] = params[i] |
| 213 | } |
| 214 | return Effect.withFiber<Clickhouse.ResultSet<"JSON"> | Clickhouse.CommandResult, SqlError>((fiber) => { |
| 215 | const method = fiber.getRef(ClientMethod) |
| 216 | return Effect.callback<Clickhouse.ResultSet<"JSON"> | Clickhouse.CommandResult, SqlError>((resume) => { |
| 217 | const queryId = fiber.getRef(QueryId) ?? Crypto.randomUUID() |
| 218 | const settings = fiber.getRef(ClickhouseSettings) |
| 219 | const controller = new AbortController() |
| 220 | if (method === "command") { |
| 221 | this.conn.command({ |
| 222 | query: sql, |
| 223 | query_params: paramsObj, |
| 224 | abort_signal: controller.signal, |
| 225 | query_id: queryId, |
| 226 | clickhouse_settings: settings |