UNPKG

effect-sql-kysely

Version:

A full-featured integration between `@effect/sql` and `Kysely` that provides type-safe database operations with Effect's powerful error handling and resource management.

103 lines (102 loc) 4.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeSqlClient = makeSqlClient; const Sql = __importStar(require("@effect/sql")); const effect_1 = require("effect"); const kysely_1 = require("kysely"); const beginConnection_js_1 = require("./beginConnection.js"); const createQueryId_js_1 = require("./createQueryId.js"); function makeSqlClient({ database, compiler, spanAttributes = [], chunkSize = 16, }) { const transformRows = Sql.Statement.defaultTransforms((s) => s, false).array; // A Connection is a wrapper around a Kysely database connection, or Transaction, that provides // the ability to run queries within Effects and captures any errors that may occur. class ConnectionImpl { db; constructor(db) { this.db = db; } executeUnprepared(sql, params) { return effect_1.Effect.tryPromise({ try: () => this.db .executeQuery(compileSqlQuery(sql, params)) .then((r) => transformRows(r.rows)), catch: (cause) => new Sql.SqlError.SqlError({ cause }), }); } execute(sql, params) { return effect_1.Effect.tryPromise({ try: () => this.db .executeQuery(compileSqlQuery(sql, params)) .then((r) => transformRows(r.rows)), catch: (cause) => new Sql.SqlError.SqlError({ cause }), }); } executeWithoutTransform(sql, params) { return effect_1.Effect.tryPromise({ try: () => this.db .executeQuery(compileSqlQuery(sql, params)) .then((r) => r.rows), catch: (cause) => new Sql.SqlError.SqlError({ cause }), }); } executeValues(sql, params) { return effect_1.Effect.map(this.executeRaw(sql, params), (results) => results.map((x) => Object.values(x))); } executeRaw(sql, params) { return effect_1.Effect.tryPromise({ try: () => this.db .executeQuery(compileSqlQuery(sql, params)) .then((r) => transformRows(r.rows)), catch: (cause) => new Sql.SqlError.SqlError({ cause }), }); } executeStream(sql, params) { const query = compileSqlQuery(sql, params); return effect_1.Stream.suspend(() => effect_1.Stream.mapChunks(effect_1.Stream.fromAsyncIterable(this.db .getExecutor() .stream(query, chunkSize, { queryId: (0, createQueryId_js_1.createQueryId)() }), (cause) => new Sql.SqlError.SqlError({ cause })), effect_1.Chunk.flatMap((result) => effect_1.Chunk.unsafeFromArray(result.rows)))); } } const acquirer = effect_1.Effect.succeed(new ConnectionImpl(database)); return Sql.SqlClient.make({ // Our default connection is managed by Kysely acquirer, // Our SQL statement compiler compiler, // We don't utilize db.transaction() because Sql.client.make will handle the actual transaction // But we do ensure that all queries are run within a single connection transactionAcquirer: effect_1.Effect.map(effect_1.Effect.acquireRelease(effect_1.Effect.promise(() => (0, beginConnection_js_1.beginConnection)(database)), (conn, exit) => effect_1.Effect.promise(() => effect_1.Exit.match(exit, { // If the scope fails we rollback the transaction onFailure: () => conn.fail(), // If the scope succeeds we commit the transaction onSuccess: () => conn.success(), }))), ({ conn }) => new ConnectionImpl(conn)), spanAttributes, }); } function compileSqlQuery(sql, params) { return kysely_1.CompiledQuery.raw(sql, params); }