1/**
2 * MySQL adapter for the shared Effect SQL migration runner.
3 *
4 * This module re-exports the shared `Migrator` loaders and error types, then
5 * provides `run` and `layer` helpers that apply ordered migrations through the
6 * current mysql2-backed `SqlClient`. `run` returns the applied migration IDs
7 * and names, while `layer` runs migrations during layer construction and
8 * provides no services.
9 *
10 * @since 4.0.0
11 */
12import type * as Effect from "effect/Effect"
13import * as Layer from "effect/Layer"
14import * as Migrator from "effect/sql/Migrator"
15import type * as Client from "effect/sql/SqlClient"
16import type { SqlError } from "effect/sql/SqlError"
17
18/**
19 * @since 4.0.0
20 */
21export * from "effect/sql/Migrator"
22
23/**
24 * Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
25 *
26 * @category running
27 * @since 4.0.0
28 */
29export const run: <R2 = never>(
30 { loader, schemaDirectory, table }: Migrator.MigratorOptions<R2>
31) => Effect.Effect<
32 ReadonlyArray<readonly [id: number, name: string]>,
33 Migrator.MigrationError | SqlError,
34 Client.SqlClient | R2
35> = Migrator.make({
36 // TODO: re-add when Command module is available
37 // dumpSchema(path, table) {
38 // const mysqlDump = (args: Array<string>) =>
39 // Effect.gen(function*() {
40 // const sql = yield* MysqlClient
41 // const dump = yield* pipe(
42 // Command.make(
43 // "mysqldump",
44 // ...(sql.config.host ? ["-h", sql.config.host] : []),
45 // ...(sql.config.port ? ["-P", sql.config.port.toString()] : []),
46 // ...(sql.config.username ? ["-u", sql.config.username] : []),
47 // ...(sql.config.password ? [`-p${Redacted.value(sql.config.password)}`] : []),
48 // ...(sql.config.database ? [sql.config.database] : []),
49 // "--skip-comments",
50 // "--compact",
51 // ...args
52 // ),
53 // Command.env({
54 // PATH: (globalThis as any).process?.env.PATH
55 // }),
56 // Command.string
57 // )
58 //
59 // return dump.replace(/^\/\*.*$/gm, "")
60 // .replace(/\n{2,}/gm, "\n\n")
61 // .trim()
62 // }).pipe(
63 // Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
64 // )
65 //
66 // const dumpSchema = mysqlDump(["--no-data"])
67 //
68 // const dumpMigrations = mysqlDump(["--no-create-info", "--tables", table])
69 //
70 // const dumpAll = Effect.map(
71 // Effect.all([dumpSchema, dumpMigrations], { concurrency: 2 }),
72 // ([schema, migrations]) => schema + "\n\n" + migrations
73 // )
74 //
75 // const dumpFile = (file: string) =>
76 // Effect.gen(function*() {
77 // const fs = yield* FileSystem
78 // const path = yield* Path
79 // const dump = yield* dumpAll
80 // yield* fs.makeDirectory(path.dirname(file), { recursive: true })
81 // yield* fs.writeFileString(file, dump)
82 // }).pipe(
83 // Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
84 // )
85 //
86 // return dumpFile(path)
87 // }
88})
89
90/**
91 * Creates a layer that runs the configured SQL migrations during layer construction.
92 *
93 * @category layers
94 * @since 4.0.0
95 */
96export const layer = <R>(
97 options: Migrator.MigratorOptions<R>
98): Layer.Layer<
99 never,
100 Migrator.MigrationError | SqlError,
101 Client.SqlClient | R
102> => Layer.effectDiscard(run(options))