103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
/**
|
|
* MySQL adapter for the shared Effect SQL migration runner.
|
|
*
|
|
* This module re-exports the shared `Migrator` loaders and error types, then
|
|
* provides `run` and `layer` helpers that apply ordered migrations through the
|
|
* current mysql2-backed `SqlClient`. `run` returns the applied migration IDs
|
|
* and names, while `layer` runs migrations during layer construction and
|
|
* provides no services.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
import type * as Effect from "effect/Effect"
|
|
import * as Layer from "effect/Layer"
|
|
import * as Migrator from "effect/unstable/sql/Migrator"
|
|
import type * as Client from "effect/unstable/sql/SqlClient"
|
|
import type { SqlError } from "effect/unstable/sql/SqlError"
|
|
|
|
/**
|
|
* @since 4.0.0
|
|
*/
|
|
export * from "effect/unstable/sql/Migrator"
|
|
|
|
/**
|
|
* Runs SQL migrations using the configured `SqlClient`, returning the migrations that were applied.
|
|
*
|
|
* @category constructors
|
|
* @since 4.0.0
|
|
*/
|
|
export const run: <R2 = never>(
|
|
{ loader, schemaDirectory, table }: Migrator.MigratorOptions<R2>
|
|
) => Effect.Effect<
|
|
ReadonlyArray<readonly [id: number, name: string]>,
|
|
Migrator.MigrationError | SqlError,
|
|
Client.SqlClient | R2
|
|
> = Migrator.make({
|
|
// TODO: re-add when Command module is available
|
|
// dumpSchema(path, table) {
|
|
// const mysqlDump = (args: Array<string>) =>
|
|
// Effect.gen(function*() {
|
|
// const sql = yield* MysqlClient
|
|
// const dump = yield* pipe(
|
|
// Command.make(
|
|
// "mysqldump",
|
|
// ...(sql.config.host ? ["-h", sql.config.host] : []),
|
|
// ...(sql.config.port ? ["-P", sql.config.port.toString()] : []),
|
|
// ...(sql.config.username ? ["-u", sql.config.username] : []),
|
|
// ...(sql.config.password ? [`-p${Redacted.value(sql.config.password)}`] : []),
|
|
// ...(sql.config.database ? [sql.config.database] : []),
|
|
// "--skip-comments",
|
|
// "--compact",
|
|
// ...args
|
|
// ),
|
|
// Command.env({
|
|
// PATH: (globalThis as any).process?.env.PATH
|
|
// }),
|
|
// Command.string
|
|
// )
|
|
//
|
|
// return dump.replace(/^\/\*.*$/gm, "")
|
|
// .replace(/\n{2,}/gm, "\n\n")
|
|
// .trim()
|
|
// }).pipe(
|
|
// Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
|
|
// )
|
|
//
|
|
// const dumpSchema = mysqlDump(["--no-data"])
|
|
//
|
|
// const dumpMigrations = mysqlDump(["--no-create-info", "--tables", table])
|
|
//
|
|
// const dumpAll = Effect.map(
|
|
// Effect.all([dumpSchema, dumpMigrations], { concurrency: 2 }),
|
|
// ([schema, migrations]) => schema + "\n\n" + migrations
|
|
// )
|
|
//
|
|
// const dumpFile = (file: string) =>
|
|
// Effect.gen(function*() {
|
|
// const fs = yield* FileSystem
|
|
// const path = yield* Path
|
|
// const dump = yield* dumpAll
|
|
// yield* fs.makeDirectory(path.dirname(file), { recursive: true })
|
|
// yield* fs.writeFileString(file, dump)
|
|
// }).pipe(
|
|
// Effect.mapError((error) => new Migrator.MigrationError({ kind: "Failed", message: error.message }))
|
|
// )
|
|
//
|
|
// return dumpFile(path)
|
|
// }
|
|
})
|
|
|
|
/**
|
|
* Creates a layer that runs the configured SQL migrations during layer construction.
|
|
*
|
|
* @category layers
|
|
* @since 4.0.0
|
|
*/
|
|
export const layer = <R>(
|
|
options: Migrator.MigratorOptions<R>
|
|
): Layer.Layer<
|
|
never,
|
|
Migrator.MigrationError | SqlError,
|
|
Client.SqlClient | R
|
|
> => Layer.effectDiscard(run(options))
|