1import { MysqlClient } from "@effect/sql-mysql2"
2import { assert, describe, it } from "@effect/vitest"
3import { Effect, Stream } from "effect"
4import * as Mysql from "mysql2"
5import { vi } from "vitest"
6
7import { MysqlContainer } from "./utils.ts"
8
9vi.mock("mysql2", { spy: true })
10
11describe("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})