{"version":3,"file":"session.cjs","names":["MySqlBasePreparedQuery","entityKind","Effect","EffectCache","NoopCache","EffectDrizzleQueryError","Cause","MySqlSession","MySqlEffectDatabase","EffectTransactionRollbackError","sql","MigratorInitError"],"sources":["../../../src/mysql-core/effect/session.ts"],"sourcesContent":["import * as Cause from 'effect/Cause';\nimport * as Effect from 'effect/Effect';\nimport type { SqlError } from 'effect/unstable/sql/SqlError';\nimport { EffectCache, type EffectCacheShape } from '~/cache/core/cache-effect.ts';\nimport { NoopCache, strategyFor } from '~/cache/core/cache.ts';\nimport type { WithCacheConfig } from '~/cache/core/types.ts';\nimport { EffectDrizzleQueryError, EffectTransactionRollbackError, MigratorInitError } from '~/effect-core/errors.ts';\nimport type { EffectLoggerShape } from '~/effect-core/logger.ts';\nimport type { QueryEffectHKTBase, QueryEffectKind } from '~/effect-core/query-effect.ts';\nimport { entityKind, is } from '~/entity.ts';\nimport type { MigrationConfig, MigrationMeta } from '~/migrator.ts';\nimport { getMigrationsToRun } from '~/migrator.utils.ts';\nimport type { AnyRelations, EmptyRelations } from '~/relations.ts';\nimport { fillPlaceholders, type Query, type SQL, sql } from '~/sql/sql.ts';\nimport { upgradeIfNeeded } from '~/up-migrations/effect-mysql.ts';\nimport { assertUnreachable } from '~/utils.ts';\nimport type { MySqlDialect } from '../dialect.ts';\nimport {\n\tMySqlBasePreparedQuery,\n\ttype MySqlPreparedQueryConfig,\n\ttype MySqlQueryResultHKT,\n\tMySqlSession,\n} from '../session.ts';\nimport { MySqlEffectDatabase } from './db.ts';\n\nexport class MySqlEffectPreparedQuery<\n\tT extends MySqlPreparedQueryConfig,\n\tTEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase,\n> extends MySqlBasePreparedQuery {\n\tstatic override readonly [entityKind]: string = 'MySqlEffectPreparedQuery';\n\n\t/** @internal */\n\treadonly mapper: {\n\t\t(rows: any[]): any;\n\t\tbody?: string;\n\t} | undefined;\n\n\tconstructor(\n\t\tprotected executor: (params?: unknown[]) => Effect.Effect<unknown, unknown, unknown>,\n\t\tquery: Query,\n\t\tmapper: ((rows: any[]) => any) | undefined,\n\t\treadonly mode: 'arrays' | 'objects' | 'raw',\n\t\tprivate logger: EffectLoggerShape,\n\t\t// cache instance\n\t\tprotected cache: EffectCacheShape,\n\t\t// per query related metadata\n\t\tprotected queryMetadata: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t} | undefined,\n\t\t// config that was passed through $withCache\n\t\tprotected cacheConfig: WithCacheConfig | undefined,\n\t) {\n\t\tsuper(query);\n\t\tthis.mapper = mapper;\n\t\tif (cache && cache.strategy() === 'all' && cacheConfig === undefined) {\n\t\t\tthis.cacheConfig = { enabled: true, autoInvalidate: true };\n\t\t}\n\t\tif (!this.cacheConfig?.enabled) {\n\t\t\tthis.cacheConfig = undefined;\n\t\t}\n\t}\n\n\toverride execute(placeholderValues: Record<string, unknown> = {}): QueryEffectKind<TEffectHKT, T['execute']> {\n\t\treturn Effect.gen({ self: this }, function*() {\n\t\t\tconst { query, mapper, logger } = this;\n\t\t\tconst sql = query._sql ? query._sql.join(' ') : query.sql;\n\t\t\tconst params = query.params.length === 0\n\t\t\t\t? query.params\n\t\t\t\t: fillPlaceholders(query.params, placeholderValues);\n\n\t\t\tyield* logger.logQuery(sql, params);\n\n\t\t\tconst result = this.queryWithCache(sql, params, Effect.suspend(() => this.executor(params)));\n\n\t\t\tif (!mapper) return yield* result;\n\n\t\t\treturn yield* result.pipe(Effect.map((rows) => mapper(rows as unknown[])));\n\t\t});\n\t}\n\n\t/** @internal */\n\tprotected queryWithCache<A, E, R>(\n\t\tqueryString: string,\n\t\tparams: any[],\n\t\tquery: Effect.Effect<A, E, R>,\n\t) {\n\t\treturn Effect.gen({ self: this }, function*() {\n\t\t\tconst { cacheConfig, queryMetadata } = this;\n\t\t\tconst cache = yield* EffectCache;\n\n\t\t\tconst cacheStrat: Awaited<ReturnType<typeof strategyFor>> = cache && !(cache.cache && is(cache.cache, NoopCache))\n\t\t\t\t? yield* Effect.tryPromise(\n\t\t\t\t\t() => strategyFor(queryString, params, queryMetadata, cacheConfig),\n\t\t\t\t)\n\t\t\t\t: { type: 'skip' as const };\n\n\t\t\tif (cacheStrat.type === 'skip') {\n\t\t\t\treturn yield* query;\n\t\t\t}\n\n\t\t\t// For mutate queries, we should query the database, wait for a response, and then perform invalidation\n\t\t\tif (cacheStrat.type === 'invalidate') {\n\t\t\t\tconst result = yield* query;\n\t\t\t\tyield* cache!.onMutate({ tables: cacheStrat.tables });\n\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif (cacheStrat.type === 'try') {\n\t\t\t\tconst { tables, key, isTag, autoInvalidate, config } = cacheStrat;\n\t\t\t\tconst fromCache: any[] | undefined = yield* cache!.get(\n\t\t\t\t\tkey,\n\t\t\t\t\ttables,\n\t\t\t\t\tisTag,\n\t\t\t\t\tautoInvalidate,\n\t\t\t\t);\n\n\t\t\t\tif (typeof fromCache !== 'undefined') return fromCache as unknown as A;\n\n\t\t\t\tconst result = yield* query;\n\n\t\t\t\tyield* cache!.put(\n\t\t\t\t\tkey,\n\t\t\t\t\tresult,\n\t\t\t\t\tautoInvalidate ? tables : [],\n\t\t\t\t\tisTag,\n\t\t\t\t\tconfig,\n\t\t\t\t);\n\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tassertUnreachable(cacheStrat);\n\t\t}).pipe(\n\t\t\tEffect.provideService(EffectCache, this.cache),\n\t\t\tEffect.catch((e) => {\n\t\t\t\treturn Effect.fail(new EffectDrizzleQueryError({ query: queryString, params, cause: Cause.fail(e) }));\n\t\t\t}),\n\t\t);\n\t}\n}\n\nexport abstract class MySqlEffectSession<\n\tTEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase,\n\tTQueryResult extends MySqlQueryResultHKT = MySqlQueryResultHKT,\n\tTRelations extends AnyRelations = EmptyRelations,\n> extends MySqlSession {\n\tstatic override readonly [entityKind]: string = 'MySqlEffectSession';\n\n\tconstructor(dialect: MySqlDialect) {\n\t\tsuper(dialect);\n\t}\n\n\tabstract override prepareQuery<T extends MySqlPreparedQueryConfig>(\n\t\tquery: Query,\n\t\tmode: 'arrays' | 'objects' | 'raw',\n\t\tmapper?: (rows: any) => any,\n\t\tqueryMetadata?: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t},\n\t\tcacheConfig?: WithCacheConfig,\n\t): MySqlEffectPreparedQuery<T, TEffectHKT>;\n\n\toverride execute<T>(query: SQL) {\n\t\treturn this.prepareQuery<MySqlPreparedQueryConfig & { execute: T }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'raw',\n\t\t).execute();\n\t}\n\n\toverride arrays<T>(query: SQL) {\n\t\treturn this.prepareQuery<MySqlPreparedQueryConfig & { execute: T[] }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'arrays',\n\t\t).execute();\n\t}\n\n\toverride objects<T>(query: SQL) {\n\t\treturn this.prepareQuery<MySqlPreparedQueryConfig & { execute: T[] }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'objects',\n\t\t).execute();\n\t}\n\n\tabstract transaction<A, E, R>(\n\t\ttransaction: (\n\t\t\ttx: MySqlEffectTransaction<TEffectHKT, TQueryResult, TRelations>,\n\t\t) => Effect.Effect<A, E, R>,\n\t): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport abstract class MySqlEffectTransaction<\n\tTEffectHKT extends QueryEffectHKTBase,\n\tTQueryResult extends MySqlQueryResultHKT,\n\tTRelations extends AnyRelations = EmptyRelations,\n> extends MySqlEffectDatabase<TEffectHKT, TQueryResult, TRelations> {\n\tstatic override readonly [entityKind]: string = 'MySqlEffectTransaction';\n\n\tconstructor(\n\t\tdialect: MySqlDialect,\n\t\tsession: MySqlEffectSession<TEffectHKT, any, any>,\n\t\tprotected relations: TRelations,\n\t\tprotected readonly nestedIndex = 0,\n\t) {\n\t\tsuper(dialect, session, relations);\n\t}\n\n\trollback() {\n\t\treturn new EffectTransactionRollbackError();\n\t}\n\n\t/** Nested transactions (aka savepoints) only work with InnoDB engine. */\n\tabstract override transaction<A, E, R>(\n\t\ttransaction: (\n\t\t\ttx: MySqlEffectTransaction<TEffectHKT, TQueryResult, TRelations>,\n\t\t) => Effect.Effect<A, E, R>,\n\t): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport const migrate = Effect.fn('migrate')(function*<TEffectHKT extends QueryEffectHKTBase>(\n\tmigrations: MigrationMeta[],\n\tsession: MySqlEffectSession<TEffectHKT>,\n\tconfig: Omit<MigrationConfig, 'migrationsSchema'>,\n) {\n\tconst migrationsTable = config.migrationsTable ?? '__drizzle_migrations';\n\n\tconst { newDb } = yield* upgradeIfNeeded(migrationsTable, session, migrations);\n\n\tif (newDb) {\n\t\tconst migrationTableCreate = sql`\n\t\t\tCREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsTable)} (\n\t\t\t\tid SERIAL PRIMARY KEY,\n\t\t\t\thash TEXT NOT NULL,\n\t\t\t\tcreated_at BIGINT,\n\t\t\t\tname TEXT,\n\t\t\t\tapplied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n\t\t\t)\n\t\t`;\n\t\tyield* session.execute(migrationTableCreate);\n\t}\n\n\tconst dbMigrations = yield* session.objects<{\n\t\tid: number;\n\t\thash: string;\n\t\tcreated_at: string;\n\t\tname: string | null;\n\t}>(\n\t\tsql`select id, hash, created_at, name from ${sql.identifier(migrationsTable)}`,\n\t);\n\n\tif (typeof config === 'object' && config.init) {\n\t\tif (dbMigrations.length) {\n\t\t\treturn yield* new MigratorInitError({ exitCode: 'databaseMigrations' });\n\t\t}\n\n\t\tif (migrations.length > 1) {\n\t\t\treturn yield* new MigratorInitError({ exitCode: 'localMigrations' });\n\t\t}\n\n\t\tconst [migration] = migrations;\n\n\t\tif (!migration) return;\n\n\t\tyield* session.execute(\n\t\t\tsql`insert into ${\n\t\t\t\tsql.identifier(\n\t\t\t\t\tmigrationsTable,\n\t\t\t\t)\n\t\t\t} (\\`hash\\`, \\`created_at\\`, \\`name\\`) values(${migration.hash}, ${migration.folderMillis}, ${migration.name})`,\n\t\t);\n\n\t\treturn;\n\t}\n\n\tconst migrationsToRun = getMigrationsToRun({\n\t\tlocalMigrations: migrations,\n\t\tdbMigrations,\n\t});\n\n\tyield* session.transaction((tx) =>\n\t\tEffect.gen(function*() {\n\t\t\tfor (const migration of migrationsToRun) {\n\t\t\t\tfor (const stmt of migration.sql) {\n\t\t\t\t\tyield* tx.execute(sql.raw(stmt));\n\t\t\t\t}\n\t\t\t\tyield* tx.execute(\n\t\t\t\t\tsql`insert into ${\n\t\t\t\t\t\tsql.identifier(\n\t\t\t\t\t\t\tmigrationsTable,\n\t\t\t\t\t\t)\n\t\t\t\t\t} (\\`hash\\`, \\`created_at\\`, \\`name\\`) values(${migration.hash}, ${migration.folderMillis}, ${migration.name})`,\n\t\t\t\t);\n\t\t\t}\n\t\t})\n\t);\n});\n"],"mappings":"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"}