{"version":3,"file":"session.cjs","names":["PgBasePreparedQuery","entityKind","Effect","EffectCache","NoopCache","EffectDrizzleQueryError","Cause","PgSession","PgEffectDatabase","EffectTransactionRollbackError","sql","MigratorInitError"],"sources":["../../../src/pg-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 { MigratorInitError } from '~/effect-core/errors.ts';\nimport { EffectDrizzleQueryError, EffectTransactionRollbackError } 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-pg.ts';\nimport { assertUnreachable } from '~/utils.ts';\nimport type { PgDialect } from '../dialect.ts';\nimport {\n\tPgBasePreparedQuery,\n\ttype PgQueryResultHKT,\n\tPgSession,\n\ttype PgTransactionConfig,\n\ttype PreparedQueryConfig,\n} from '../session.ts';\nimport { PgEffectDatabase } from './db.ts';\n\nexport class PgEffectPreparedQuery<\n\tT extends PreparedQueryConfig,\n\tTEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase,\n> extends PgBasePreparedQuery {\n\tstatic override readonly [entityKind]: string = 'PgEffectPreparedQuery';\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 params = fillPlaceholders(this.query.params, placeholderValues);\n\t\t\tconst { query: { sql }, mapper, logger } = this;\n\n\t\t\tyield* logger.logQuery(sql, params);\n\n\t\t\tconst query = this.queryWithCache(sql, params, Effect.suspend(() => this.executor(params)));\n\n\t\t\tif (!mapper) return yield* query;\n\n\t\t\treturn yield* query.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 PgEffectSession<\n\tTEffectHKT extends QueryEffectHKTBase = QueryEffectHKTBase,\n\tTQueryResult extends PgQueryResultHKT = PgQueryResultHKT,\n\tTRelations extends AnyRelations = EmptyRelations,\n> extends PgSession {\n\tstatic override readonly [entityKind]: string = 'PgEffectSession';\n\n\tconstructor(dialect: PgDialect) {\n\t\tsuper(dialect);\n\t}\n\n\tabstract override prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(\n\t\tquery: Query,\n\t\tmode: 'arrays' | 'objects' | 'raw',\n\t\tname: string | boolean,\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): PgEffectPreparedQuery<T, TEffectHKT>;\n\n\toverride execute<T>(query: SQL) {\n\t\tconst prepared = this.prepareQuery<PreparedQueryConfig & { execute: T[] }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'raw',\n\t\t\tfalse,\n\t\t);\n\n\t\treturn prepared.execute();\n\t}\n\n\toverride arrays<T>(query: SQL) {\n\t\tconst prepared = this.prepareQuery<PreparedQueryConfig & { execute: T[] }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'arrays',\n\t\t\tfalse,\n\t\t);\n\n\t\treturn prepared.execute();\n\t}\n\n\toverride objects<T>(query: SQL) {\n\t\tconst prepared = this.prepareQuery<PreparedQueryConfig & { execute: T[] }>(\n\t\t\tthis.dialect.sqlToQuery(query),\n\t\t\t'objects',\n\t\t\tfalse,\n\t\t);\n\n\t\treturn prepared.execute();\n\t}\n\n\tabstract transaction<A, E, R>(\n\t\ttransaction: (\n\t\t\ttx: PgEffectTransaction<TEffectHKT, TQueryResult, TRelations>,\n\t\t) => Effect.Effect<A, E, R>,\n\t\tconfig?: PgTransactionConfig,\n\t): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport abstract class PgEffectTransaction<\n\tTEffectHKT extends QueryEffectHKTBase,\n\tTQueryResult extends PgQueryResultHKT,\n\tTRelations extends AnyRelations = EmptyRelations,\n> extends PgEffectDatabase<TEffectHKT, TQueryResult, TRelations> {\n\tstatic override readonly [entityKind]: string = 'PgEffectTransaction';\n\n\tconstructor(\n\t\tdialect: PgDialect,\n\t\tsession: PgEffectSession<TEffectHKT, any, any>,\n\t\tprotected relations: TRelations,\n\t\tprotected readonly nestedIndex = 0,\n\t\tparseRqbJson?: boolean,\n\t) {\n\t\tsuper(dialect, session, relations, parseRqbJson);\n\t}\n\n\trollback() {\n\t\treturn new EffectTransactionRollbackError();\n\t}\n\n\t/** @internal */\n\tgetTransactionConfigChunks(config: PgTransactionConfig): string[] {\n\t\tconst chunks: string[] = [];\n\t\tif (config.isolationLevel) {\n\t\t\tchunks.push(`isolation level ${config.isolationLevel}`);\n\t\t}\n\t\tif (config.accessMode) {\n\t\t\tchunks.push(config.accessMode);\n\t\t}\n\t\tif (typeof config.deferrable === 'boolean') {\n\t\t\tchunks.push(config.deferrable ? 'deferrable' : 'not deferrable');\n\t\t}\n\t\treturn chunks;\n\t}\n\n\t/** @internal */\n\tgetTransactionConfigSQL(config: PgTransactionConfig): SQL {\n\t\treturn sql.raw(this.getTransactionConfigChunks(config).join(' '));\n\t}\n\n\t/** @internal */\n\tsetTransactionSnapshotSQL(snapshot: string): SQL {\n\t\treturn sql`set transaction snapshot ${snapshot}`.inlineParams();\n\t}\n\n\t/** @internal */\n\tgetTransactionConfigStatements(config: PgTransactionConfig): string[] {\n\t\tconst statements: string[] = [];\n\n\t\tconst chunks = this.getTransactionConfigChunks(config);\n\t\tif (chunks.length) statements.push(`set transaction ${chunks.join(' ')}`);\n\n\t\tif (typeof config.snapshot === 'string') {\n\t\t\tstatements.push(this.dialect.sqlToQuery(this.setTransactionSnapshotSQL(config.snapshot)).sql);\n\t\t}\n\n\t\treturn statements;\n\t}\n\n\tsetTransaction(config: PgTransactionConfig) {\n\t\tconst chunks = this.getTransactionConfigChunks(config);\n\t\tconst setOptions = chunks.length\n\t\t\t? Effect.asVoid(this.session.execute<void>(sql.raw(`set transaction ${chunks.join(' ')}`)))\n\t\t\t: Effect.void;\n\n\t\tif (typeof config.snapshot === 'string') {\n\t\t\treturn Effect.flatMap(\n\t\t\t\tsetOptions,\n\t\t\t\t() => Effect.asVoid(this.session.execute<void>(this.setTransactionSnapshotSQL(config.snapshot!))),\n\t\t\t);\n\t\t}\n\t\treturn setOptions;\n\t}\n\n\tabstract override transaction<A, E, R>(\n\t\ttransaction: (\n\t\t\ttx: PgEffectTransaction<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: PgEffectSession<TEffectHKT>,\n\tconfig: string | MigrationConfig,\n) {\n\tconst migrationsTable = typeof config === 'string'\n\t\t? '__drizzle_migrations'\n\t\t: config.migrationsTable ?? '__drizzle_migrations';\n\tconst migrationsSchema = typeof config === 'string' ? 'drizzle' : config.migrationsSchema ?? 'drizzle';\n\n\tyield* session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);\n\n\tconst { newDb } = yield* upgradeIfNeeded(migrationsSchema, migrationsTable, session, migrations);\n\n\tif (newDb) {\n\t\tconst migrationTableCreate = sql`\n\t\t\tCREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${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 with time zone DEFAULT now()\n\t\t\t)\n\t\t`;\n\n\t\tyield* session.execute(migrationTableCreate);\n\t}\n\n\tconst dbMigrations = yield* session.objects<{ id: number; hash: string; created_at: string; name: string | null }>(\n\t\tsql`select id, hash, created_at, name from ${sql.identifier(migrationsSchema)}.${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 ${sql.identifier(migrationsSchema)}.${\n\t\t\t\tsql.identifier(migrationsTable)\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({ localMigrations: migrations, dbMigrations });\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 ${sql.identifier(migrationsSchema)}.${\n\t\t\t\t\t\tsql.identifier(migrationsTable)\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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"}