drizzle-orm 1.0.0-beta.8-dbc3565 → 1.0.0-beta.8-e601f80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,12 +4,14 @@ import type * as V1 from "../../_relations.cjs";
4
4
  import type { EffectCache } from "../../cache/core/cache-effect.cjs";
5
5
  import type { WithCacheConfig } from "../../cache/core/types.cjs";
6
6
  import { entityKind } from "../../entity.cjs";
7
- import { DrizzleQueryError } from "../../errors.cjs";
7
+ import { DrizzleQueryError, TransactionRollbackError } from "../../errors.cjs";
8
+ import type { MigrationConfig, MigrationMeta, MigratorInitFailResponse } from "../../migrator.cjs";
8
9
  import type { AnyRelations, EmptyRelations } from "../../relations.cjs";
9
- import type { Query } from "../../sql/index.cjs";
10
+ import { type Query, type SQL } from "../../sql/sql.cjs";
10
11
  import type { PgDialect } from "../dialect.cjs";
11
12
  import type { SelectedFieldsOrdered } from "../query-builders/select.types.cjs";
12
- import { PgBasePreparedQuery, PgSession, type PreparedQueryConfig } from "../session.cjs";
13
+ import { PgBasePreparedQuery, type PgQueryResultHKT, PgSession, type PgTransactionConfig, type PreparedQueryConfig } from "../session.cjs";
14
+ import { PgEffectDatabase } from "./db.cjs";
13
15
  export declare abstract class PgEffectPreparedQuery<T extends PreparedQueryConfig> extends PgBasePreparedQuery {
14
16
  private cache;
15
17
  private queryMetadata;
@@ -22,7 +24,7 @@ export declare abstract class PgEffectPreparedQuery<T extends PreparedQueryConfi
22
24
  protected queryWithCache<T>(queryString: string, params: any[], query: Effect.Effect<T, SqlError>): Effect.Effect<T, DrizzleQueryError>;
23
25
  abstract execute(placeholderValues?: Record<string, unknown>): Effect.Effect<T['execute'], DrizzleQueryError>;
24
26
  }
25
- export declare abstract class PgEffectSession<TFullSchema extends Record<string, unknown> = Record<string, never>, _TRelations extends AnyRelations = EmptyRelations, _TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgSession {
27
+ export declare abstract class PgEffectSession<TQueryResult extends PgQueryResultHKT = PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations, TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgSession {
26
28
  static readonly [entityKind]: string;
27
29
  constructor(dialect: PgDialect);
28
30
  abstract prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query, fields: SelectedFieldsOrdered | undefined, name: string | undefined, isResponseInArrayMode: boolean, customResultMapper?: (rows: unknown[][], mapColumnValue?: (value: unknown) => unknown) => T['execute'], queryMetadata?: {
@@ -30,4 +32,26 @@ export declare abstract class PgEffectSession<TFullSchema extends Record<string,
30
32
  tables: string[];
31
33
  }, cacheConfig?: WithCacheConfig): PgEffectPreparedQuery<T>;
32
34
  abstract prepareRelationalQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query, fields: SelectedFieldsOrdered | undefined, name: string | undefined, customResultMapper: (rows: Record<string, unknown>[], mapColumnValue?: (value: unknown) => unknown) => T['execute']): PgEffectPreparedQuery<T>;
35
+ execute<T>(query: SQL): Effect.Effect<T, DrizzleQueryError>;
36
+ all<T>(query: SQL): Effect.Effect<T[], DrizzleQueryError>;
37
+ abstract transaction<T>(transaction: (tx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;
33
38
  }
39
+ export declare abstract class PgEffectTransaction<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations, TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgEffectDatabase<TQueryResult, TFullSchema, TRelations, TSchema> {
40
+ protected relations: TRelations;
41
+ protected schema: {
42
+ fullSchema: Record<string, unknown>;
43
+ schema: TSchema;
44
+ tableNamesMap: Record<string, string>;
45
+ } | undefined;
46
+ protected readonly nestedIndex: number;
47
+ static readonly [entityKind]: string;
48
+ constructor(dialect: PgDialect, session: PgEffectSession<any, any, any, any>, relations: TRelations, schema: {
49
+ fullSchema: Record<string, unknown>;
50
+ schema: TSchema;
51
+ tableNamesMap: Record<string, string>;
52
+ } | undefined, nestedIndex?: number, parseRqbJson?: boolean);
53
+ rollback: () => Generator<import("effect/Utils").YieldWrap<Effect.Effect<never, TransactionRollbackError, never>>, void, any>;
54
+ setTransaction(config: PgTransactionConfig): Effect.Effect<void, DrizzleQueryError>;
55
+ abstract transaction<T>(transaction: (tx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;
56
+ }
57
+ export declare function migrate(migrations: MigrationMeta[], session: PgEffectSession, config: string | MigrationConfig): Effect.Effect<void | MigratorInitFailResponse, DrizzleQueryError, never>;
@@ -4,12 +4,14 @@ import type * as V1 from "../../_relations.js";
4
4
  import type { EffectCache } from "../../cache/core/cache-effect.js";
5
5
  import type { WithCacheConfig } from "../../cache/core/types.js";
6
6
  import { entityKind } from "../../entity.js";
7
- import { DrizzleQueryError } from "../../errors.js";
7
+ import { DrizzleQueryError, TransactionRollbackError } from "../../errors.js";
8
+ import type { MigrationConfig, MigrationMeta, MigratorInitFailResponse } from "../../migrator.js";
8
9
  import type { AnyRelations, EmptyRelations } from "../../relations.js";
9
- import type { Query } from "../../sql/index.js";
10
+ import { type Query, type SQL } from "../../sql/sql.js";
10
11
  import type { PgDialect } from "../dialect.js";
11
12
  import type { SelectedFieldsOrdered } from "../query-builders/select.types.js";
12
- import { PgBasePreparedQuery, PgSession, type PreparedQueryConfig } from "../session.js";
13
+ import { PgBasePreparedQuery, type PgQueryResultHKT, PgSession, type PgTransactionConfig, type PreparedQueryConfig } from "../session.js";
14
+ import { PgEffectDatabase } from "./db.js";
13
15
  export declare abstract class PgEffectPreparedQuery<T extends PreparedQueryConfig> extends PgBasePreparedQuery {
14
16
  private cache;
15
17
  private queryMetadata;
@@ -22,7 +24,7 @@ export declare abstract class PgEffectPreparedQuery<T extends PreparedQueryConfi
22
24
  protected queryWithCache<T>(queryString: string, params: any[], query: Effect.Effect<T, SqlError>): Effect.Effect<T, DrizzleQueryError>;
23
25
  abstract execute(placeholderValues?: Record<string, unknown>): Effect.Effect<T['execute'], DrizzleQueryError>;
24
26
  }
25
- export declare abstract class PgEffectSession<TFullSchema extends Record<string, unknown> = Record<string, never>, _TRelations extends AnyRelations = EmptyRelations, _TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgSession {
27
+ export declare abstract class PgEffectSession<TQueryResult extends PgQueryResultHKT = PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations, TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgSession {
26
28
  static readonly [entityKind]: string;
27
29
  constructor(dialect: PgDialect);
28
30
  abstract prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query, fields: SelectedFieldsOrdered | undefined, name: string | undefined, isResponseInArrayMode: boolean, customResultMapper?: (rows: unknown[][], mapColumnValue?: (value: unknown) => unknown) => T['execute'], queryMetadata?: {
@@ -30,4 +32,26 @@ export declare abstract class PgEffectSession<TFullSchema extends Record<string,
30
32
  tables: string[];
31
33
  }, cacheConfig?: WithCacheConfig): PgEffectPreparedQuery<T>;
32
34
  abstract prepareRelationalQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query, fields: SelectedFieldsOrdered | undefined, name: string | undefined, customResultMapper: (rows: Record<string, unknown>[], mapColumnValue?: (value: unknown) => unknown) => T['execute']): PgEffectPreparedQuery<T>;
35
+ execute<T>(query: SQL): Effect.Effect<T, DrizzleQueryError>;
36
+ all<T>(query: SQL): Effect.Effect<T[], DrizzleQueryError>;
37
+ abstract transaction<T>(transaction: (tx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;
33
38
  }
39
+ export declare abstract class PgEffectTransaction<TQueryResult extends PgQueryResultHKT, TFullSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations, TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>> extends PgEffectDatabase<TQueryResult, TFullSchema, TRelations, TSchema> {
40
+ protected relations: TRelations;
41
+ protected schema: {
42
+ fullSchema: Record<string, unknown>;
43
+ schema: TSchema;
44
+ tableNamesMap: Record<string, string>;
45
+ } | undefined;
46
+ protected readonly nestedIndex: number;
47
+ static readonly [entityKind]: string;
48
+ constructor(dialect: PgDialect, session: PgEffectSession<any, any, any, any>, relations: TRelations, schema: {
49
+ fullSchema: Record<string, unknown>;
50
+ schema: TSchema;
51
+ tableNamesMap: Record<string, string>;
52
+ } | undefined, nestedIndex?: number, parseRqbJson?: boolean);
53
+ rollback: () => Generator<import("effect/Utils").YieldWrap<Effect.Effect<never, TransactionRollbackError, never>>, void, any>;
54
+ setTransaction(config: PgTransactionConfig): Effect.Effect<void, DrizzleQueryError>;
55
+ abstract transaction<T>(transaction: (tx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;
56
+ }
57
+ export declare function migrate(migrations: MigrationMeta[], session: PgEffectSession, config: string | MigrationConfig): Effect.Effect<void | MigratorInitFailResponse, DrizzleQueryError, never>;
@@ -1,9 +1,14 @@
1
1
  import { Effect } from "effect";
2
2
  import { strategyFor } from "../../cache/core/cache.js";
3
3
  import { entityKind } from "../../entity.js";
4
- import { DrizzleQueryError } from "../../errors.js";
4
+ import { DrizzleQueryError, TransactionRollbackError } from "../../errors.js";
5
+ import { sql } from "../../sql/sql.js";
5
6
  import { assertUnreachable } from "../../utils.js";
6
- import { PgBasePreparedQuery, PgSession } from "../session.js";
7
+ import {
8
+ PgBasePreparedQuery,
9
+ PgSession
10
+ } from "../session.js";
11
+ import { PgEffectDatabase } from "./db.js";
7
12
  class PgEffectPreparedQuery extends PgBasePreparedQuery {
8
13
  constructor(query, cache, queryMetadata, cacheConfig) {
9
14
  super(query);
@@ -62,9 +67,96 @@ class PgEffectSession extends PgSession {
62
67
  constructor(dialect) {
63
68
  super(dialect);
64
69
  }
70
+ execute(query) {
71
+ const { sql: sql2, params } = this.dialect.sqlToQuery(query);
72
+ return this.prepareQuery({ sql: sql2, params }, void 0, void 0, false).execute();
73
+ }
74
+ all(query) {
75
+ const { sql: sql2, params } = this.dialect.sqlToQuery(query);
76
+ return this.prepareQuery({ sql: sql2, params }, void 0, void 0, false).all();
77
+ }
78
+ }
79
+ class PgEffectTransaction extends PgEffectDatabase {
80
+ constructor(dialect, session, relations, schema, nestedIndex = 0, parseRqbJson) {
81
+ super(dialect, session, relations, schema, parseRqbJson);
82
+ this.relations = relations;
83
+ this.schema = schema;
84
+ this.nestedIndex = nestedIndex;
85
+ }
86
+ static [entityKind] = "PgEffectTransaction";
87
+ rollback = function* () {
88
+ yield* Effect.fail(new TransactionRollbackError());
89
+ };
90
+ /** @internal */
91
+ getTransactionConfigSQL(config) {
92
+ const chunks = [];
93
+ if (config.isolationLevel) {
94
+ chunks.push(`isolation level ${config.isolationLevel}`);
95
+ }
96
+ if (config.accessMode) {
97
+ chunks.push(config.accessMode);
98
+ }
99
+ if (typeof config.deferrable === "boolean") {
100
+ chunks.push(config.deferrable ? "deferrable" : "not deferrable");
101
+ }
102
+ return sql.raw(chunks.join(" "));
103
+ }
104
+ setTransaction(config) {
105
+ return this.session.execute(sql`set transaction ${this.getTransactionConfigSQL(config)}`);
106
+ }
107
+ }
108
+ function migrate(migrations, session, config) {
109
+ return Effect.gen(function* () {
110
+ const migrationsTable = typeof config === "string" ? "__drizzle_migrations" : config.migrationsTable ?? "__drizzle_migrations";
111
+ const migrationsSchema = typeof config === "string" ? "drizzle" : config.migrationsSchema ?? "drizzle";
112
+ const migrationTableCreate = sql`
113
+ CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} (
114
+ id SERIAL PRIMARY KEY,
115
+ hash text NOT NULL,
116
+ created_at bigint
117
+ )
118
+ `;
119
+ yield* session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);
120
+ yield* session.execute(migrationTableCreate);
121
+ const dbMigrations = yield* session.all(
122
+ sql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} order by created_at desc limit 1`
123
+ );
124
+ if (typeof config === "object" && config.init) {
125
+ if (dbMigrations.length) {
126
+ return { exitCode: "databaseMigrations" };
127
+ }
128
+ if (migrations.length > 1) {
129
+ return { exitCode: "localMigrations" };
130
+ }
131
+ const [migration] = migrations;
132
+ if (!migration) return;
133
+ yield* session.execute(
134
+ sql`insert into ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} ("hash", "created_at") values(${migration.hash}, ${migration.folderMillis})`
135
+ );
136
+ return;
137
+ }
138
+ const lastDbMigration = dbMigrations[0];
139
+ yield* session.transaction(
140
+ (tx) => Effect.gen(function* () {
141
+ for (const migration of migrations) {
142
+ if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
143
+ for (const stmt of migration.sql) {
144
+ yield* tx.execute(sql.raw(stmt));
145
+ }
146
+ yield* tx.execute(
147
+ sql`insert into ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} ("hash", "created_at") values(${migration.hash}, ${migration.folderMillis})`
148
+ );
149
+ }
150
+ }
151
+ })
152
+ );
153
+ return;
154
+ });
65
155
  }
66
156
  export {
67
157
  PgEffectPreparedQuery,
68
- PgEffectSession
158
+ PgEffectSession,
159
+ PgEffectTransaction,
160
+ migrate
69
161
  };
70
162
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/pg-core/effect/session.ts"],"sourcesContent":["import type { SqlError } from '@effect/sql/SqlError';\nimport { Effect } from 'effect';\nimport type * as V1 from '~/_relations.ts';\nimport type { EffectCache } from '~/cache/core/cache-effect.ts';\nimport { strategyFor } from '~/cache/core/cache.ts';\nimport type { WithCacheConfig } from '~/cache/core/types.ts';\nimport { entityKind } from '~/entity.ts';\nimport { DrizzleQueryError } from '~/errors.ts';\nimport type { AnyRelations, EmptyRelations } from '~/relations.ts';\nimport type { Query } from '~/sql/index.ts';\nimport { assertUnreachable } from '~/utils.ts';\nimport type { PgDialect } from '../dialect.ts';\nimport type { SelectedFieldsOrdered } from '../query-builders/select.types.ts';\nimport { PgBasePreparedQuery, PgSession, type PreparedQueryConfig } from '../session.ts';\n\nexport abstract class PgEffectPreparedQuery<T extends PreparedQueryConfig> extends PgBasePreparedQuery {\n\tstatic override readonly [entityKind]: string = 'PgEffectPreparedQuery';\n\n\tconstructor(\n\t\tquery: Query,\n\t\tprivate cache: EffectCache | undefined,\n\t\tprivate queryMetadata: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t} | undefined,\n\t\tprivate cacheConfig?: WithCacheConfig,\n\t) {\n\t\tsuper(query);\n\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\tprotected override queryWithCache<T>(\n\t\tqueryString: string,\n\t\tparams: any[],\n\t\tquery: Effect.Effect<T, SqlError>,\n\t): Effect.Effect<T, DrizzleQueryError> {\n\t\tconst { cache, cacheConfig, queryMetadata } = this;\n\t\treturn Effect.gen(function*() {\n\t\t\tconst cacheStrat: Awaited<ReturnType<typeof strategyFor>> = cache\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 T;\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(Effect.catchAll((e) => {\n\t\t\t// eslint-disable-next-line @drizzle-internal/no-instanceof\n\t\t\treturn Effect.fail(new DrizzleQueryError(queryString, params, e instanceof Error ? e : undefined));\n\t\t}));\n\t}\n\n\tabstract override execute(\n\t\tplaceholderValues?: Record<string, unknown>,\n\t): Effect.Effect<T['execute'], DrizzleQueryError>;\n\n\t/** @internal */\n\tabstract override all(placeholderValues?: Record<string, unknown>): Effect.Effect<T['all'], DrizzleQueryError>;\n}\n\nexport abstract class PgEffectSession<\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\t_TRelations extends AnyRelations = EmptyRelations,\n\t_TSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>,\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\tfields: SelectedFieldsOrdered | undefined,\n\t\tname: string | undefined,\n\t\tisResponseInArrayMode: boolean,\n\t\tcustomResultMapper?: (rows: unknown[][], mapColumnValue?: (value: unknown) => unknown) => T['execute'],\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>;\n\n\tabstract override prepareRelationalQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(\n\t\tquery: Query,\n\t\tfields: SelectedFieldsOrdered | undefined,\n\t\tname: string | undefined,\n\t\tcustomResultMapper: (\n\t\t\trows: Record<string, unknown>[],\n\t\t\tmapColumnValue?: (value: unknown) => unknown,\n\t\t) => T['execute'],\n\t): PgEffectPreparedQuery<T>;\n}\n"],"mappings":"AACA,SAAS,cAAc;AAGvB,SAAS,mBAAmB;AAE5B,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAGlC,SAAS,yBAAyB;AAGlC,SAAS,qBAAqB,iBAA2C;AAElE,MAAe,8BAA6D,oBAAoB;AAAA,EAGtG,YACC,OACQ,OACA,eAIA,aACP;AACD,UAAM,KAAK;AAPH;AACA;AAIA;AAIR,QAAI,SAAS,MAAM,SAAS,MAAM,SAAS,gBAAgB,QAAW;AACrE,WAAK,cAAc,EAAE,SAAS,MAAM,gBAAgB,KAAK;AAAA,IAC1D;AACA,QAAI,CAAC,KAAK,aAAa,SAAS;AAC/B,WAAK,cAAc;AAAA,IACpB;AAAA,EACD;AAAA,EAnBA,QAA0B,UAAU,IAAY;AAAA,EAqB7B,eAClB,aACA,QACA,OACsC;AACtC,UAAM,EAAE,OAAO,aAAa,cAAc,IAAI;AAC9C,WAAO,OAAO,IAAI,aAAY;AAC7B,YAAM,aAAsD,QACzD,OAAO,OAAO;AAAA,QACf,MAAM,YAAY,aAAa,QAAQ,eAAe,WAAW;AAAA,MAClE,IACE,EAAE,MAAM,OAAgB;AAE3B,UAAI,WAAW,SAAS,QAAQ;AAC/B,eAAO,OAAO;AAAA,MACf;AAGA,UAAI,WAAW,SAAS,cAAc;AACrC,cAAM,SAAS,OAAO;AACtB,eAAO,MAAO,SAAS,EAAE,QAAQ,WAAW,OAAO,CAAC;AAEpD,eAAO;AAAA,MACR;AAEA,UAAI,WAAW,SAAS,OAAO;AAC9B,cAAM,EAAE,QAAQ,KAAK,OAAO,gBAAgB,OAAO,IAAI;AACvD,cAAM,YAA+B,OAAO,MAAO;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAEA,YAAI,OAAO,cAAc,YAAa,QAAO;AAE7C,cAAM,SAAS,OAAO;AAEtB,eAAO,MAAO;AAAA,UACb;AAAA,UACA;AAAA,UACA,iBAAiB,SAAS,CAAC;AAAA,UAC3B;AAAA,UACA;AAAA,QACD;AAEA,eAAO;AAAA,MACR;AAEA,wBAAkB,UAAU;AAAA,IAC7B,CAAC,EAAE,KAAK,OAAO,SAAS,CAAC,MAAM;AAE9B,aAAO,OAAO,KAAK,IAAI,kBAAkB,aAAa,QAAQ,aAAa,QAAQ,IAAI,MAAS,CAAC;AAAA,IAClG,CAAC,CAAC;AAAA,EACH;AAQD;AAEO,MAAe,wBAIZ,UAAU;AAAA,EACnB,QAA0B,UAAU,IAAY;AAAA,EAEhD,YAAY,SAAoB;AAC/B,UAAM,OAAO;AAAA,EACd;AAwBD;","names":[]}
1
+ {"version":3,"sources":["../../../src/pg-core/effect/session.ts"],"sourcesContent":["import type { SqlError } from '@effect/sql/SqlError';\nimport { Effect } from 'effect';\nimport type * as V1 from '~/_relations.ts';\nimport type { EffectCache } from '~/cache/core/cache-effect.ts';\nimport { strategyFor } from '~/cache/core/cache.ts';\nimport type { WithCacheConfig } from '~/cache/core/types.ts';\nimport { entityKind } from '~/entity.ts';\nimport { DrizzleQueryError, TransactionRollbackError } from '~/errors.ts';\nimport type { MigrationConfig, MigrationMeta, MigratorInitFailResponse } from '~/migrator.ts';\nimport type { AnyRelations, EmptyRelations } from '~/relations.ts';\nimport { type Query, type SQL, sql } from '~/sql/sql.ts';\nimport { assertUnreachable } from '~/utils.ts';\nimport type { PgDialect } from '../dialect.ts';\nimport type { SelectedFieldsOrdered } from '../query-builders/select.types.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 abstract class PgEffectPreparedQuery<T extends PreparedQueryConfig> extends PgBasePreparedQuery {\n\tstatic override readonly [entityKind]: string = 'PgEffectPreparedQuery';\n\n\tconstructor(\n\t\tquery: Query,\n\t\tprivate cache: EffectCache | undefined,\n\t\tprivate queryMetadata: {\n\t\t\ttype: 'select' | 'update' | 'delete' | 'insert';\n\t\t\ttables: string[];\n\t\t} | undefined,\n\t\tprivate cacheConfig?: WithCacheConfig,\n\t) {\n\t\tsuper(query);\n\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\tprotected override queryWithCache<T>(\n\t\tqueryString: string,\n\t\tparams: any[],\n\t\tquery: Effect.Effect<T, SqlError>,\n\t): Effect.Effect<T, DrizzleQueryError> {\n\t\tconst { cache, cacheConfig, queryMetadata } = this;\n\t\treturn Effect.gen(function*() {\n\t\t\tconst cacheStrat: Awaited<ReturnType<typeof strategyFor>> = cache\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 T;\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(Effect.catchAll((e) => {\n\t\t\t// eslint-disable-next-line @drizzle-internal/no-instanceof\n\t\t\treturn Effect.fail(new DrizzleQueryError(queryString, params, e instanceof Error ? e : undefined));\n\t\t}));\n\t}\n\n\tabstract override execute(\n\t\tplaceholderValues?: Record<string, unknown>,\n\t): Effect.Effect<T['execute'], DrizzleQueryError>;\n\n\t/** @internal */\n\tabstract override all(placeholderValues?: Record<string, unknown>): Effect.Effect<T['all'], DrizzleQueryError>;\n}\n\nexport abstract class PgEffectSession<\n\tTQueryResult extends PgQueryResultHKT = PgQueryResultHKT,\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\tTRelations extends AnyRelations = EmptyRelations,\n\tTSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>,\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\tfields: SelectedFieldsOrdered | undefined,\n\t\tname: string | undefined,\n\t\tisResponseInArrayMode: boolean,\n\t\tcustomResultMapper?: (rows: unknown[][], mapColumnValue?: (value: unknown) => unknown) => T['execute'],\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>;\n\n\tabstract override prepareRelationalQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(\n\t\tquery: Query,\n\t\tfields: SelectedFieldsOrdered | undefined,\n\t\tname: string | undefined,\n\t\tcustomResultMapper: (\n\t\t\trows: Record<string, unknown>[],\n\t\t\tmapColumnValue?: (value: unknown) => unknown,\n\t\t) => T['execute'],\n\t): PgEffectPreparedQuery<T>;\n\n\toverride execute<T>(query: SQL): Effect.Effect<T, DrizzleQueryError> {\n\t\tconst { sql, params } = this.dialect.sqlToQuery(query);\n\t\treturn this.prepareQuery<PreparedQueryConfig & { execute: T }>({ sql, params }, undefined, undefined, false)\n\t\t\t.execute();\n\t}\n\n\toverride all<T>(query: SQL): Effect.Effect<T[], DrizzleQueryError> {\n\t\tconst { sql, params } = this.dialect.sqlToQuery(query);\n\t\treturn this.prepareQuery<PreparedQueryConfig & { all: T[] }>({ sql, params }, undefined, undefined, false)\n\t\t\t.all();\n\t}\n\n\tabstract transaction<T>(\n\t\ttransaction: (\n\t\t\ttx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>,\n\t\t) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>,\n\t): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;\n}\n\nexport abstract class PgEffectTransaction<\n\tTQueryResult extends PgQueryResultHKT,\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\tTRelations extends AnyRelations = EmptyRelations,\n\tTSchema extends V1.TablesRelationalConfig = V1.ExtractTablesWithRelations<TFullSchema>,\n> extends PgEffectDatabase<TQueryResult, TFullSchema, TRelations, TSchema> {\n\tstatic override readonly [entityKind]: string = 'PgEffectTransaction';\n\n\tconstructor(\n\t\tdialect: PgDialect,\n\t\tsession: PgEffectSession<any, any, any, any>,\n\t\tprotected relations: TRelations,\n\t\tprotected schema: {\n\t\t\tfullSchema: Record<string, unknown>;\n\t\t\tschema: TSchema;\n\t\t\ttableNamesMap: Record<string, string>;\n\t\t} | undefined,\n\t\tprotected readonly nestedIndex = 0,\n\t\tparseRqbJson?: boolean,\n\t) {\n\t\tsuper(dialect, session, relations, schema, parseRqbJson);\n\t}\n\n\trollback = function*() {\n\t\tyield* Effect.fail(new TransactionRollbackError());\n\t};\n\n\t/** @internal */\n\tgetTransactionConfigSQL(config: PgTransactionConfig): SQL {\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 sql.raw(chunks.join(' '));\n\t}\n\n\tsetTransaction(config: PgTransactionConfig): Effect.Effect<void, DrizzleQueryError> {\n\t\treturn this.session.execute(sql`set transaction ${this.getTransactionConfigSQL(config)}`);\n\t}\n\n\tabstract override transaction<T>(\n\t\ttransaction: (\n\t\t\ttx: PgEffectTransaction<TQueryResult, TFullSchema, TRelations, TSchema>,\n\t\t) => Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>,\n\t): Effect.Effect<T, DrizzleQueryError | TransactionRollbackError>;\n}\n\nexport function migrate(\n\tmigrations: MigrationMeta[],\n\tsession: PgEffectSession,\n\tconfig: string | MigrationConfig,\n): Effect.Effect<void | MigratorInitFailResponse, DrizzleQueryError, never> {\n\treturn Effect.gen(function*() {\n\t\tconst migrationsTable = typeof config === 'string'\n\t\t\t? '__drizzle_migrations'\n\t\t\t: config.migrationsTable ?? '__drizzle_migrations';\n\t\tconst migrationsSchema = typeof config === 'string' ? 'drizzle' : config.migrationsSchema ?? 'drizzle';\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)\n\t\t`;\n\t\tyield* session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);\n\t\tyield* session.execute(migrationTableCreate);\n\n\t\tconst dbMigrations = yield* session.all<{ id: number; hash: string; created_at: string }>(\n\t\t\tsql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${\n\t\t\t\tsql.identifier(migrationsTable)\n\t\t\t} order by created_at desc limit 1`,\n\t\t);\n\n\t\tif (typeof config === 'object' && config.init) {\n\t\t\tif (dbMigrations.length) {\n\t\t\t\treturn { exitCode: 'databaseMigrations' as const };\n\t\t\t}\n\n\t\t\tif (migrations.length > 1) {\n\t\t\t\treturn { exitCode: 'localMigrations' as const };\n\t\t\t}\n\n\t\t\tconst [migration] = migrations;\n\n\t\t\tif (!migration) return;\n\n\t\t\tyield* session.execute(\n\t\t\t\tsql`insert into ${sql.identifier(migrationsSchema)}.${\n\t\t\t\t\tsql.identifier(migrationsTable)\n\t\t\t\t} (\"hash\", \"created_at\") values(${migration.hash}, ${migration.folderMillis})`,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst lastDbMigration = dbMigrations[0];\n\t\tyield* session.transaction((tx) =>\n\t\t\tEffect.gen(function*() {\n\t\t\t\tfor (const migration of migrations) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t!lastDbMigration\n\t\t\t\t\t\t|| Number(lastDbMigration.created_at) < migration.folderMillis\n\t\t\t\t\t) {\n\t\t\t\t\t\tfor (const stmt of migration.sql) {\n\t\t\t\t\t\t\tyield* tx.execute(sql.raw(stmt));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield* tx.execute(\n\t\t\t\t\t\t\tsql`insert into ${sql.identifier(migrationsSchema)}.${\n\t\t\t\t\t\t\t\tsql.identifier(migrationsTable)\n\t\t\t\t\t\t\t} (\"hash\", \"created_at\") values(${migration.hash}, ${migration.folderMillis})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t);\n\n\t\treturn;\n\t}) as Effect.Effect<void | MigratorInitFailResponse, DrizzleQueryError, never>;\n}\n"],"mappings":"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","names":["sql"]}