| 1 | import { MysqlClient } from "@effect/sql-mysql2" |
| 2 | import { assert, describe, it } from "@effect/vitest" |
| 3 | import { Effect, Stream } from "effect" |
| 4 | import * as Mysql from "mysql2" |
| 5 | import { vi } from "vitest" |
| 6 | |
| 7 | import { MysqlContainer } from "./utils.ts" |
| 8 | |
| 9 | vi.mock("mysql2", { spy: true }) |
| 10 | |
| 11 | describe("MysqlClient", () => { |
| 12 | it.effect("stream returns same rows as direct execution", () => |
| 13 | Effect.gen(function*() { |
| 14 | const sql = yield* MysqlClient.MysqlClient |
| 15 | |
| 16 | yield* sql`DROP TABLE IF EXISTS stream_regression_test` |
| 17 | yield* sql`CREATE TABLE stream_regression_test (id INT PRIMARY KEY AUTO_INCREMENT, value VARCHAR(255))` |
| 18 | |
| 19 | const testData = Array.from({ length: 100 }, (_, i) => ({ value: `row_${i}` })) |
| 20 | yield* sql`INSERT INTO stream_regression_test ${sql.insert(testData)}` |
| 21 | |
| 22 | const directResults = yield* sql`SELECT * FROM stream_regression_test` |
| 23 | |
| 24 | const streamResults = yield* Stream.runCollect( |
| 25 | sql`SELECT * FROM stream_regression_test`.stream |
| 26 | ) |
| 27 | |
| 28 | yield* sql`DROP TABLE stream_regression_test` |
| 29 | |
| 30 | assert.strictEqual( |
| 31 | streamResults.length, |
| 32 | directResults.length, |
| 33 | `Stream returned ${streamResults.length} rows, expected ${directResults.length}` |
| 34 | ) |
| 35 | }).pipe( |
| 36 | Effect.provide(MysqlContainer.layerClient), |
| 37 | Effect.catchTag("ContainerError", () => Effect.void) |
| 38 | ), { timeout: 60_000 }) |
| 39 | |
| 40 | it.effect("uses query when prepared statements are disabled", () => |
| 41 | Effect.gen(function*() { |
| 42 | const calls: Array<"execute" | "query"> = [] |
| 43 | vi.mocked(Mysql.createPool).mockReturnValueOnce({ |
| 44 | query: (options: string | object, callback: (cause: null, rows?: Array<unknown>) => void) => { |
| 45 | if (typeof options !== "string") { |
| 46 | calls.push("query") |
| 47 | } |
| 48 | callback(null, []) |
| 49 | }, |
| 50 | execute: (_options: object, callback: (cause: null, rows: Array<unknown>) => void) => { |
| 51 | calls.push("execute") |
| 52 | callback(null, []) |
| 53 | }, |
| 54 | end: (callback: () => void) => callback() |
| 55 | } as unknown as Mysql.Pool) |
| 56 | |
| 57 | yield* Effect.gen(function*() { |
| 58 | const sql = yield* MysqlClient.MysqlClient |
| 59 | yield* sql`SELECT ${1}` |
| 60 | yield* sql`SELECT ${1}`.values |
| 61 | yield* sql.unsafe("SELECT ?", [1]).raw |
| 62 | }).pipe(Effect.provide(MysqlClient.layer({ disablePreparedStatements: true }))) |
| 63 | |
| 64 | assert.deepStrictEqual(calls, ["query", "query", "query"]) |
| 65 | })) |
| 66 | }) |