@nextlyhq/adapter-drizzle 0.0.2-alpha.4 → 0.0.2-alpha.41

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.
@@ -1,5 +1,6 @@
1
+ import { AnyRelations } from 'drizzle-orm';
1
2
  import { S as SupportedDialect, a as SqlParam, T as TableResolver } from './core-CVO7WYDj.cjs';
2
- import { T as TransactionContext, e as TransactionOptions, D as DatabaseCapabilities, P as PoolStats, S as SelectOptions, I as InsertOptions, W as WhereClause, U as UpdateOptions, f as DeleteOptions, g as UpsertOptions, a as Migration, d as MigrationResult } from './migration-BbO5meEV.cjs';
3
+ import { T as TransactionContext, e as TransactionOptions, D as DatabaseCapabilities, P as PoolStats, S as SelectOptions, I as InsertOptions, W as WhereClause, U as UpdateOptions, f as DeleteOptions, g as UpsertOptions, a as Migration, d as MigrationResult } from './migration-B41DME-y.cjs';
3
4
  import { T as TableDefinition, C as CreateTableOptions, D as DropTableOptions, A as AlterTableOperation, a as AlterTableOptions } from './schema-BDn8WfSL.cjs';
4
5
  import { D as DatabaseErrorKind, a as DatabaseError } from './error-um1d_3Uo.cjs';
5
6
 
@@ -16,53 +17,6 @@ import { D as DatabaseErrorKind, a as DatabaseError } from './error-um1d_3Uo.cjs
16
17
  * @packageDocumentation
17
18
  */
18
19
 
19
- /**
20
- * Abstract base class for database adapters.
21
- *
22
- * @remarks
23
- * All dialect-specific adapters must extend this class and implement the abstract methods.
24
- * Default implementations are provided for CRUD operations, which can be overridden for
25
- * optimization or dialect-specific behavior.
26
- *
27
- * ## Required Implementations
28
- *
29
- * Subclasses must implement:
30
- * - `dialect` - Database dialect identifier
31
- * - `connect()` - Establish database connection
32
- * - `disconnect()` - Close database connection
33
- * - `executeQuery()` - Execute raw SQL query
34
- * - `transaction()` - Execute operations within a transaction
35
- * - `getCapabilities()` - Report database feature support
36
- *
37
- * ## Optional Overrides
38
- *
39
- * Subclasses can override default CRUD methods for optimization:
40
- * - `select()`, `selectOne()` - Custom query optimization
41
- * - `insert()`, `insertMany()` - Bulk insert optimization
42
- * - `update()`, `delete()` - Custom update/delete logic
43
- * - `upsert()` - Dialect-specific upsert syntax
44
- *
45
- * @example
46
- * ```typescript
47
- * export class PostgresAdapter extends DrizzleAdapter {
48
- * readonly dialect = 'postgresql' as const;
49
- *
50
- * async connect() {
51
- * this.pool = new Pool({ connectionString: this.config.url });
52
- * // ... connection logic
53
- * }
54
- *
55
- * async executeQuery<T>(sql: string, params?: SqlParam[]) {
56
- * const result = await this.pool.query(sql, params);
57
- * return result.rows as T[];
58
- * }
59
- *
60
- * // ... other required methods
61
- * }
62
- * ```
63
- *
64
- * @public
65
- */
66
20
  declare abstract class DrizzleAdapter {
67
21
  /**
68
22
  * Database dialect identifier.
@@ -136,17 +90,18 @@ declare abstract class DrizzleAdapter {
136
90
  * - Consistent error handling
137
91
  * - Proper connection pooling
138
92
  *
139
- * @param schema - Optional schema object for typed queries
93
+ * @param relations - Optional drizzle v1 relations config (defineRelations
94
+ * output) that enables the typed relational query API on the instance
140
95
  * @returns Raw Drizzle ORM database instance
141
96
  *
142
97
  * @example
143
98
  * ```typescript
144
99
  * // For legacy code that needs direct Drizzle access
145
- * const db = adapter.getDrizzle(mySchemas);
100
+ * const db = adapter.getDrizzle(myRelations); // defineRelations output
146
101
  * const result = await db.insert(users).values({ ... }).returning();
147
102
  * ```
148
103
  */
149
- abstract getDrizzle<T = unknown>(schema?: Record<string, unknown>): T;
104
+ abstract getDrizzle<T = unknown>(relations?: AnyRelations): T;
150
105
  /**
151
106
  * Table resolver for looking up Drizzle table objects by name.
152
107
  * When set, CRUD methods use Drizzle's query API instead of raw SQL.
@@ -174,6 +129,44 @@ declare abstract class DrizzleAdapter {
174
129
  * because they match the DB column names. This method maps them to the JS names Drizzle expects.
175
130
  */
176
131
  protected mapDataToColumnNames(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
132
+ /**
133
+ * Map data keys from Drizzle JS property names to SQL column names for the
134
+ * raw-SQL transaction insert path. The transaction context builds INSERT
135
+ * statements from Object.keys(data) used directly as column identifiers, so a
136
+ * table whose Drizzle property names differ from its SQL column names
137
+ * (camelCase core tables like nextly_versions) needs its keys translated
138
+ * first. For tables whose property names already equal their column names
139
+ * (the dynamic dc_/single_/comp_ tables) every lookup is identity, so
140
+ * existing callers are unaffected.
141
+ */
142
+ protected mapKeysToSqlColumns(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
143
+ /**
144
+ * Map a list of column identifiers (Drizzle property names) to their SQL
145
+ * column names, for the raw-SQL transaction insert paths that build a
146
+ * RETURNING clause from `options.returning`. Same identity behavior as
147
+ * `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic
148
+ * dc_/single_/comp_ tables) pass through unchanged.
149
+ */
150
+ protected mapColumnNamesToSql(tableObj: unknown, names: string[]): string[];
151
+ /**
152
+ * Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property
153
+ * names, so the raw-SQL transaction insert paths return the same key casing
154
+ * as the non-transactional (Drizzle) insert. Keys only - values are left
155
+ * untouched, so this does not change how JSON/date columns are decoded. For
156
+ * tables whose property names already equal their SQL columns (the dynamic
157
+ * dc_/single_/comp_ tables) every lookup is identity, so existing callers see
158
+ * no change.
159
+ */
160
+ protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T;
161
+ /**
162
+ * Build a Drizzle column projection object (`{ propertyName: column }`) from a
163
+ * requested column list, used by `select` (columns) and `insert` (returning).
164
+ * A requested name resolves against either the Drizzle property name
165
+ * (camelCase) or the SQL column name (snake_case); the projection is keyed by
166
+ * the property name so the row shape matches a full select. Returns undefined
167
+ * for `"*"` or when nothing resolves, so callers fall back to all columns.
168
+ */
169
+ protected buildColumnProjection(tableObj: unknown, names: string[] | "*" | undefined): Record<string, unknown> | undefined;
177
170
  /**
178
171
  * Check if the adapter is currently connected.
179
172
  *
@@ -286,7 +279,7 @@ declare abstract class DrizzleAdapter {
286
279
  * });
287
280
  * ```
288
281
  */
289
- select<T = unknown>(table: string, options?: SelectOptions): Promise<T[]>;
282
+ select<T = unknown>(table: string, options?: SelectOptions, executor?: unknown): Promise<T[]>;
290
283
  /**
291
284
  * Select a single record from a table.
292
285
  *
@@ -307,7 +300,7 @@ declare abstract class DrizzleAdapter {
307
300
  * });
308
301
  * ```
309
302
  */
310
- selectOne<T = unknown>(table: string, options?: SelectOptions): Promise<T | null>;
303
+ selectOne<T = unknown>(table: string, options?: SelectOptions, executor?: unknown): Promise<T | null>;
311
304
  /**
312
305
  * Insert a single record into a table.
313
306
  *
@@ -378,7 +371,7 @@ declare abstract class DrizzleAdapter {
378
371
  * );
379
372
  * ```
380
373
  */
381
- update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions): Promise<T[]>;
374
+ update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions, executor?: unknown): Promise<T[]>;
382
375
  /**
383
376
  * Delete records from a table.
384
377
  *
@@ -401,7 +394,7 @@ declare abstract class DrizzleAdapter {
401
394
  * console.log(`Deleted ${count} users`);
402
395
  * ```
403
396
  */
404
- delete(table: string, where: WhereClause, _options?: DeleteOptions): Promise<number>;
397
+ delete(table: string, where: WhereClause, _options?: DeleteOptions, executor?: unknown): Promise<number>;
405
398
  /**
406
399
  * Upsert (INSERT or UPDATE) a record.
407
400
  *
@@ -429,7 +422,7 @@ declare abstract class DrizzleAdapter {
429
422
  * });
430
423
  * ```
431
424
  */
432
- upsert<T = unknown>(table: string, data: Record<string, unknown>, options: UpsertOptions): Promise<T>;
425
+ upsert<T = unknown>(table: string, data: Record<string, unknown>, options: UpsertOptions, executor?: unknown): Promise<T>;
433
426
  /**
434
427
  * Run pending migrations.
435
428
  *
@@ -1,5 +1,6 @@
1
+ import { AnyRelations } from 'drizzle-orm';
1
2
  import { S as SupportedDialect, a as SqlParam, T as TableResolver } from './core-CVO7WYDj.js';
2
- import { T as TransactionContext, e as TransactionOptions, D as DatabaseCapabilities, P as PoolStats, S as SelectOptions, I as InsertOptions, W as WhereClause, U as UpdateOptions, f as DeleteOptions, g as UpsertOptions, a as Migration, d as MigrationResult } from './migration-Qe70wDOC.js';
3
+ import { T as TransactionContext, e as TransactionOptions, D as DatabaseCapabilities, P as PoolStats, S as SelectOptions, I as InsertOptions, W as WhereClause, U as UpdateOptions, f as DeleteOptions, g as UpsertOptions, a as Migration, d as MigrationResult } from './migration-XV8CXMZT.js';
3
4
  import { T as TableDefinition, C as CreateTableOptions, D as DropTableOptions, A as AlterTableOperation, a as AlterTableOptions } from './schema-BIQ0YQZ_.js';
4
5
  import { D as DatabaseErrorKind, a as DatabaseError } from './error-um1d_3Uo.js';
5
6
 
@@ -16,53 +17,6 @@ import { D as DatabaseErrorKind, a as DatabaseError } from './error-um1d_3Uo.js'
16
17
  * @packageDocumentation
17
18
  */
18
19
 
19
- /**
20
- * Abstract base class for database adapters.
21
- *
22
- * @remarks
23
- * All dialect-specific adapters must extend this class and implement the abstract methods.
24
- * Default implementations are provided for CRUD operations, which can be overridden for
25
- * optimization or dialect-specific behavior.
26
- *
27
- * ## Required Implementations
28
- *
29
- * Subclasses must implement:
30
- * - `dialect` - Database dialect identifier
31
- * - `connect()` - Establish database connection
32
- * - `disconnect()` - Close database connection
33
- * - `executeQuery()` - Execute raw SQL query
34
- * - `transaction()` - Execute operations within a transaction
35
- * - `getCapabilities()` - Report database feature support
36
- *
37
- * ## Optional Overrides
38
- *
39
- * Subclasses can override default CRUD methods for optimization:
40
- * - `select()`, `selectOne()` - Custom query optimization
41
- * - `insert()`, `insertMany()` - Bulk insert optimization
42
- * - `update()`, `delete()` - Custom update/delete logic
43
- * - `upsert()` - Dialect-specific upsert syntax
44
- *
45
- * @example
46
- * ```typescript
47
- * export class PostgresAdapter extends DrizzleAdapter {
48
- * readonly dialect = 'postgresql' as const;
49
- *
50
- * async connect() {
51
- * this.pool = new Pool({ connectionString: this.config.url });
52
- * // ... connection logic
53
- * }
54
- *
55
- * async executeQuery<T>(sql: string, params?: SqlParam[]) {
56
- * const result = await this.pool.query(sql, params);
57
- * return result.rows as T[];
58
- * }
59
- *
60
- * // ... other required methods
61
- * }
62
- * ```
63
- *
64
- * @public
65
- */
66
20
  declare abstract class DrizzleAdapter {
67
21
  /**
68
22
  * Database dialect identifier.
@@ -136,17 +90,18 @@ declare abstract class DrizzleAdapter {
136
90
  * - Consistent error handling
137
91
  * - Proper connection pooling
138
92
  *
139
- * @param schema - Optional schema object for typed queries
93
+ * @param relations - Optional drizzle v1 relations config (defineRelations
94
+ * output) that enables the typed relational query API on the instance
140
95
  * @returns Raw Drizzle ORM database instance
141
96
  *
142
97
  * @example
143
98
  * ```typescript
144
99
  * // For legacy code that needs direct Drizzle access
145
- * const db = adapter.getDrizzle(mySchemas);
100
+ * const db = adapter.getDrizzle(myRelations); // defineRelations output
146
101
  * const result = await db.insert(users).values({ ... }).returning();
147
102
  * ```
148
103
  */
149
- abstract getDrizzle<T = unknown>(schema?: Record<string, unknown>): T;
104
+ abstract getDrizzle<T = unknown>(relations?: AnyRelations): T;
150
105
  /**
151
106
  * Table resolver for looking up Drizzle table objects by name.
152
107
  * When set, CRUD methods use Drizzle's query API instead of raw SQL.
@@ -174,6 +129,44 @@ declare abstract class DrizzleAdapter {
174
129
  * because they match the DB column names. This method maps them to the JS names Drizzle expects.
175
130
  */
176
131
  protected mapDataToColumnNames(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
132
+ /**
133
+ * Map data keys from Drizzle JS property names to SQL column names for the
134
+ * raw-SQL transaction insert path. The transaction context builds INSERT
135
+ * statements from Object.keys(data) used directly as column identifiers, so a
136
+ * table whose Drizzle property names differ from its SQL column names
137
+ * (camelCase core tables like nextly_versions) needs its keys translated
138
+ * first. For tables whose property names already equal their column names
139
+ * (the dynamic dc_/single_/comp_ tables) every lookup is identity, so
140
+ * existing callers are unaffected.
141
+ */
142
+ protected mapKeysToSqlColumns(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
143
+ /**
144
+ * Map a list of column identifiers (Drizzle property names) to their SQL
145
+ * column names, for the raw-SQL transaction insert paths that build a
146
+ * RETURNING clause from `options.returning`. Same identity behavior as
147
+ * `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic
148
+ * dc_/single_/comp_ tables) pass through unchanged.
149
+ */
150
+ protected mapColumnNamesToSql(tableObj: unknown, names: string[]): string[];
151
+ /**
152
+ * Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property
153
+ * names, so the raw-SQL transaction insert paths return the same key casing
154
+ * as the non-transactional (Drizzle) insert. Keys only - values are left
155
+ * untouched, so this does not change how JSON/date columns are decoded. For
156
+ * tables whose property names already equal their SQL columns (the dynamic
157
+ * dc_/single_/comp_ tables) every lookup is identity, so existing callers see
158
+ * no change.
159
+ */
160
+ protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T;
161
+ /**
162
+ * Build a Drizzle column projection object (`{ propertyName: column }`) from a
163
+ * requested column list, used by `select` (columns) and `insert` (returning).
164
+ * A requested name resolves against either the Drizzle property name
165
+ * (camelCase) or the SQL column name (snake_case); the projection is keyed by
166
+ * the property name so the row shape matches a full select. Returns undefined
167
+ * for `"*"` or when nothing resolves, so callers fall back to all columns.
168
+ */
169
+ protected buildColumnProjection(tableObj: unknown, names: string[] | "*" | undefined): Record<string, unknown> | undefined;
177
170
  /**
178
171
  * Check if the adapter is currently connected.
179
172
  *
@@ -286,7 +279,7 @@ declare abstract class DrizzleAdapter {
286
279
  * });
287
280
  * ```
288
281
  */
289
- select<T = unknown>(table: string, options?: SelectOptions): Promise<T[]>;
282
+ select<T = unknown>(table: string, options?: SelectOptions, executor?: unknown): Promise<T[]>;
290
283
  /**
291
284
  * Select a single record from a table.
292
285
  *
@@ -307,7 +300,7 @@ declare abstract class DrizzleAdapter {
307
300
  * });
308
301
  * ```
309
302
  */
310
- selectOne<T = unknown>(table: string, options?: SelectOptions): Promise<T | null>;
303
+ selectOne<T = unknown>(table: string, options?: SelectOptions, executor?: unknown): Promise<T | null>;
311
304
  /**
312
305
  * Insert a single record into a table.
313
306
  *
@@ -378,7 +371,7 @@ declare abstract class DrizzleAdapter {
378
371
  * );
379
372
  * ```
380
373
  */
381
- update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions): Promise<T[]>;
374
+ update<T = unknown>(table: string, data: Record<string, unknown>, where: WhereClause, options?: UpdateOptions, executor?: unknown): Promise<T[]>;
382
375
  /**
383
376
  * Delete records from a table.
384
377
  *
@@ -401,7 +394,7 @@ declare abstract class DrizzleAdapter {
401
394
  * console.log(`Deleted ${count} users`);
402
395
  * ```
403
396
  */
404
- delete(table: string, where: WhereClause, _options?: DeleteOptions): Promise<number>;
397
+ delete(table: string, where: WhereClause, _options?: DeleteOptions, executor?: unknown): Promise<number>;
405
398
  /**
406
399
  * Upsert (INSERT or UPDATE) a record.
407
400
  *
@@ -429,7 +422,7 @@ declare abstract class DrizzleAdapter {
429
422
  * });
430
423
  * ```
431
424
  */
432
- upsert<T = unknown>(table: string, data: Record<string, unknown>, options: UpsertOptions): Promise<T>;
425
+ upsert<T = unknown>(table: string, data: Record<string, unknown>, options: UpsertOptions, executor?: unknown): Promise<T>;
433
426
  /**
434
427
  * Run pending migrations.
435
428
  *
package/dist/index.cjs CHANGED
@@ -4,7 +4,7 @@ var drizzleOrm = require('drizzle-orm');
4
4
 
5
5
  // src/adapter.ts
6
6
  function buildDrizzleWhere(table, where) {
7
- const columns = drizzleOrm.getTableColumns(table);
7
+ const columns = drizzleOrm.getColumns(table);
8
8
  return processWhereClause(columns, where);
9
9
  }
10
10
  function processWhereClause(columns, where) {
@@ -108,6 +108,21 @@ function createDatabaseError(options) {
108
108
  }
109
109
 
110
110
  // src/adapter.ts
111
+ function affectedRowCount(result) {
112
+ if (Array.isArray(result)) {
113
+ const header = result[0];
114
+ if (header && typeof header.affectedRows === "number") {
115
+ return header.affectedRows;
116
+ }
117
+ return result.length;
118
+ }
119
+ const record = result;
120
+ const rowCount = record?.rowCount;
121
+ if (typeof rowCount === "number") return rowCount;
122
+ const changes = record?.changes;
123
+ if (typeof changes === "number") return changes;
124
+ return 0;
125
+ }
111
126
  var DrizzleAdapter = class {
112
127
  // ============================================================
113
128
  // Drizzle Query API Support
@@ -175,6 +190,107 @@ var DrizzleAdapter = class {
175
190
  }
176
191
  return mapped;
177
192
  }
193
+ /**
194
+ * Map data keys from Drizzle JS property names to SQL column names for the
195
+ * raw-SQL transaction insert path. The transaction context builds INSERT
196
+ * statements from Object.keys(data) used directly as column identifiers, so a
197
+ * table whose Drizzle property names differ from its SQL column names
198
+ * (camelCase core tables like nextly_versions) needs its keys translated
199
+ * first. For tables whose property names already equal their column names
200
+ * (the dynamic dc_/single_/comp_ tables) every lookup is identity, so
201
+ * existing callers are unaffected.
202
+ */
203
+ mapKeysToSqlColumns(tableObj, data) {
204
+ if (!tableObj || typeof tableObj !== "object") return data;
205
+ const jsToSql = /* @__PURE__ */ new Map();
206
+ for (const [jsName, colDef] of Object.entries(
207
+ tableObj
208
+ )) {
209
+ if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
210
+ jsToSql.set(jsName, colDef.name);
211
+ }
212
+ }
213
+ if (jsToSql.size === 0) return data;
214
+ const out = {};
215
+ for (const [key, value] of Object.entries(data)) {
216
+ out[jsToSql.get(key) ?? key] = value;
217
+ }
218
+ return out;
219
+ }
220
+ /**
221
+ * Map a list of column identifiers (Drizzle property names) to their SQL
222
+ * column names, for the raw-SQL transaction insert paths that build a
223
+ * RETURNING clause from `options.returning`. Same identity behavior as
224
+ * `mapKeysToSqlColumns`: names that are already SQL columns (the dynamic
225
+ * dc_/single_/comp_ tables) pass through unchanged.
226
+ */
227
+ mapColumnNamesToSql(tableObj, names) {
228
+ if (!tableObj || typeof tableObj !== "object") return names;
229
+ const jsToSql = /* @__PURE__ */ new Map();
230
+ for (const [jsName, colDef] of Object.entries(
231
+ tableObj
232
+ )) {
233
+ if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
234
+ jsToSql.set(jsName, colDef.name);
235
+ }
236
+ }
237
+ if (jsToSql.size === 0) return names;
238
+ return names.map((n) => jsToSql.get(n) ?? n);
239
+ }
240
+ /**
241
+ * Remap a raw-SQL result row's KEYS from SQL column names to Drizzle property
242
+ * names, so the raw-SQL transaction insert paths return the same key casing
243
+ * as the non-transactional (Drizzle) insert. Keys only - values are left
244
+ * untouched, so this does not change how JSON/date columns are decoded. For
245
+ * tables whose property names already equal their SQL columns (the dynamic
246
+ * dc_/single_/comp_ tables) every lookup is identity, so existing callers see
247
+ * no change.
248
+ */
249
+ mapRowKeysToJs(tableObj, row) {
250
+ if (!tableObj || typeof tableObj !== "object" || !row || typeof row !== "object") {
251
+ return row;
252
+ }
253
+ const sqlToJs = /* @__PURE__ */ new Map();
254
+ for (const [jsName, colDef] of Object.entries(
255
+ tableObj
256
+ )) {
257
+ if (colDef && typeof colDef === "object" && "name" in colDef && typeof colDef.name === "string") {
258
+ sqlToJs.set(colDef.name, jsName);
259
+ }
260
+ }
261
+ if (sqlToJs.size === 0) return row;
262
+ const out = {};
263
+ for (const [key, value] of Object.entries(row)) {
264
+ out[sqlToJs.get(key) ?? key] = value;
265
+ }
266
+ return out;
267
+ }
268
+ /**
269
+ * Build a Drizzle column projection object (`{ propertyName: column }`) from a
270
+ * requested column list, used by `select` (columns) and `insert` (returning).
271
+ * A requested name resolves against either the Drizzle property name
272
+ * (camelCase) or the SQL column name (snake_case); the projection is keyed by
273
+ * the property name so the row shape matches a full select. Returns undefined
274
+ * for `"*"` or when nothing resolves, so callers fall back to all columns.
275
+ */
276
+ buildColumnProjection(tableObj, names) {
277
+ if (names == null || names === "*" || !tableObj || typeof tableObj !== "object") {
278
+ return void 0;
279
+ }
280
+ const cols = drizzleOrm.getColumns(tableObj);
281
+ const byAnyName = {};
282
+ for (const [jsName, col] of Object.entries(cols)) {
283
+ byAnyName[jsName] = { jsName, col };
284
+ const sqlName = col?.name;
285
+ if (typeof sqlName === "string") byAnyName[sqlName] = { jsName, col };
286
+ }
287
+ const projection = {};
288
+ for (const name of names) {
289
+ const hit = byAnyName[name];
290
+ if (hit) projection[hit.jsName] = hit.col;
291
+ }
292
+ return Object.keys(projection).length ? projection : void 0;
293
+ }
178
294
  // ============================================================
179
295
  // Connection Status (Default implementations, can override)
180
296
  // ============================================================
@@ -328,12 +444,13 @@ var DrizzleAdapter = class {
328
444
  * });
329
445
  * ```
330
446
  */
331
- async select(table, options) {
447
+ async select(table, options, executor) {
332
448
  const tableObj = this.getTableObject(table);
333
449
  if (tableObj) {
334
450
  try {
335
- const db = this.getDrizzle();
336
- let query = db.select().from(tableObj);
451
+ const db = executor ?? this.getDrizzle();
452
+ const projection = options?.columns?.length ? this.buildColumnProjection(tableObj, options.columns) : void 0;
453
+ let query = projection ? db.select(projection).from(tableObj) : db.select().from(tableObj);
337
454
  if (options?.where) {
338
455
  const whereCondition = buildDrizzleWhere(
339
456
  tableObj,
@@ -344,7 +461,7 @@ var DrizzleAdapter = class {
344
461
  }
345
462
  }
346
463
  if (options?.orderBy?.length) {
347
- const columns = drizzleOrm.getTableColumns(tableObj);
464
+ const columns = drizzleOrm.getColumns(tableObj);
348
465
  const orderClauses = options.orderBy.map((o) => {
349
466
  const col = columns[o.column];
350
467
  if (!col) return void 0;
@@ -360,6 +477,16 @@ var DrizzleAdapter = class {
360
477
  if (options?.offset !== void 0) {
361
478
  query = query.offset(options.offset);
362
479
  }
480
+ if (options?.forUpdate && !executor) {
481
+ throw this.createDatabaseError(
482
+ "query",
483
+ "forUpdate requires a transaction executor: a lock request on the pooled connection takes no durable lock and cannot prevent a concurrent write.",
484
+ void 0
485
+ );
486
+ }
487
+ if (options?.forUpdate && this.dialect !== "sqlite") {
488
+ query = query.for("update");
489
+ }
363
490
  return await query;
364
491
  } catch (error) {
365
492
  throw this.handleQueryError(error, "select", table);
@@ -391,8 +518,12 @@ var DrizzleAdapter = class {
391
518
  * });
392
519
  * ```
393
520
  */
394
- async selectOne(table, options) {
395
- const results = await this.select(table, { ...options, limit: 1 });
521
+ async selectOne(table, options, executor) {
522
+ const results = await this.select(
523
+ table,
524
+ { ...options, limit: 1 },
525
+ executor
526
+ );
396
527
  return results.length > 0 ? results[0] : null;
397
528
  }
398
529
  /**
@@ -424,19 +555,22 @@ var DrizzleAdapter = class {
424
555
  const mappedData = this.mapDataToColumnNames(tableObj, data);
425
556
  const db = this.getDrizzle();
426
557
  const caps = this.getCapabilities();
427
- if (caps.supportsReturning && options?.returning) {
428
- const result2 = await db.insert(tableObj).values(mappedData).returning();
558
+ const returning = options?.returning;
559
+ const wantsReturning = returning != null && !(Array.isArray(returning) && returning.length === 0);
560
+ if (caps.supportsReturning && wantsReturning) {
561
+ const projection = this.buildColumnProjection(tableObj, returning);
562
+ const insertQuery = db.insert(tableObj).values(mappedData);
563
+ const result2 = await (projection ? insertQuery.returning(projection) : insertQuery.returning());
429
564
  return Array.isArray(result2) ? result2[0] : result2;
430
565
  }
431
566
  const result = await db.insert(tableObj).values(mappedData);
432
- if (!caps.supportsReturning && options?.returning) {
433
- if (data.id !== void 0) {
434
- return await this.selectOne(table, {
435
- where: {
436
- and: [{ column: "id", op: "=", value: data.id }]
437
- }
438
- });
439
- }
567
+ if (!caps.supportsReturning && wantsReturning && data.id !== void 0) {
568
+ return await this.selectOne(table, {
569
+ columns: returning === "*" ? void 0 : returning,
570
+ where: {
571
+ and: [{ column: "id", op: "=", value: data.id }]
572
+ }
573
+ });
440
574
  }
441
575
  return Array.isArray(result) ? result[0] : result;
442
576
  } catch (error) {
@@ -506,11 +640,11 @@ var DrizzleAdapter = class {
506
640
  * );
507
641
  * ```
508
642
  */
509
- async update(table, data, where, options) {
643
+ async update(table, data, where, options, executor) {
510
644
  const tableObj = this.getTableObject(table);
511
645
  if (tableObj) {
512
646
  try {
513
- const db = this.getDrizzle();
647
+ const db = executor ?? this.getDrizzle();
514
648
  const caps = this.getCapabilities();
515
649
  const mappedData = this.mapDataToColumnNames(tableObj, data);
516
650
  let query = db.update(tableObj).set(mappedData);
@@ -523,7 +657,7 @@ var DrizzleAdapter = class {
523
657
  }
524
658
  await query;
525
659
  if (!caps.supportsReturning && options?.returning) {
526
- return await this.select(table, { where });
660
+ return await this.select(table, { where }, executor);
527
661
  }
528
662
  return [];
529
663
  } catch (error) {
@@ -558,18 +692,18 @@ var DrizzleAdapter = class {
558
692
  * console.log(`Deleted ${count} users`);
559
693
  * ```
560
694
  */
561
- async delete(table, where, _options) {
695
+ async delete(table, where, _options, executor) {
562
696
  const tableObj = this.getTableObject(table);
563
697
  if (tableObj) {
564
698
  try {
565
- const db = this.getDrizzle();
699
+ const db = executor ?? this.getDrizzle();
566
700
  let query = db.delete(tableObj);
567
701
  const whereCondition = buildDrizzleWhere(tableObj, where);
568
702
  if (whereCondition) {
569
703
  query = query.where(whereCondition);
570
704
  }
571
705
  const result = await query;
572
- return Array.isArray(result) ? result.length : result?.rowCount ?? result?.changes ?? 0;
706
+ return affectedRowCount(result);
573
707
  } catch (error) {
574
708
  throw this.handleQueryError(error, "delete", table);
575
709
  }
@@ -607,13 +741,13 @@ var DrizzleAdapter = class {
607
741
  * });
608
742
  * ```
609
743
  */
610
- async upsert(table, data, options) {
744
+ async upsert(table, data, options, executor) {
611
745
  const tableObj = this.getTableObject(table);
612
746
  if (tableObj) {
613
747
  try {
614
- const db = this.getDrizzle();
748
+ const db = executor ?? this.getDrizzle();
615
749
  const caps = this.getCapabilities();
616
- const columns = drizzleOrm.getTableColumns(tableObj);
750
+ const columns = drizzleOrm.getColumns(tableObj);
617
751
  const conflictTarget = options.conflictColumns.map((col) => columns[col]).filter(Boolean);
618
752
  const conflictSet = new Set(options.conflictColumns);
619
753
  const updateData = {};
@@ -638,17 +772,21 @@ var DrizzleAdapter = class {
638
772
  }
639
773
  await query;
640
774
  if (options.conflictColumns.length && data[options.conflictColumns[0]] !== void 0) {
641
- return await this.selectOne(table, {
642
- where: {
643
- and: [
644
- {
645
- column: options.conflictColumns[0],
646
- op: "=",
647
- value: data[options.conflictColumns[0]]
648
- }
649
- ]
650
- }
651
- });
775
+ return await this.selectOne(
776
+ table,
777
+ {
778
+ where: {
779
+ and: [
780
+ {
781
+ column: options.conflictColumns[0],
782
+ op: "=",
783
+ value: data[options.conflictColumns[0]]
784
+ }
785
+ ]
786
+ }
787
+ },
788
+ executor
789
+ );
652
790
  }
653
791
  return data;
654
792
  } catch (error) {
@@ -974,7 +1112,7 @@ var DrizzleAdapter = class {
974
1112
  break;
975
1113
  case "mysql":
976
1114
  sql = `
977
- SELECT table_name
1115
+ SELECT table_name AS table_name
978
1116
  FROM information_schema.tables
979
1117
  WHERE table_schema = DATABASE()
980
1118
  AND table_type = 'BASE TABLE'