@nextlyhq/adapter-drizzle 0.0.2-alpha.66 → 0.0.2-alpha.67
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.
- package/dist/{adapter-Cs3Jl9Fb.d.cts → adapter-bUAaPzjV.d.cts} +219 -2
- package/dist/{adapter-CHlx_Taa.d.ts → adapter-iJ5hbUvL.d.ts} +219 -2
- package/dist/index.cjs +299 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +300 -29
- package/dist/index.mjs.map +1 -1
- package/dist/{migration-CgoxgWOL.d.ts → migration-BqHebSwM.d.ts} +40 -3
- package/dist/{migration-Ce0hkgr_.d.cts → migration-Bu0WLdX4.d.cts} +40 -3
- package/dist/migrations.d.cts +3 -3
- package/dist/migrations.d.ts +3 -3
- package/dist/schema-name.cjs +20 -0
- package/dist/schema-name.cjs.map +1 -0
- package/dist/schema-name.d.cts +24 -0
- package/dist/schema-name.d.ts +24 -0
- package/dist/schema-name.mjs +17 -0
- package/dist/schema-name.mjs.map +1 -0
- package/dist/text-match.cjs +16 -0
- package/dist/text-match.cjs.map +1 -0
- package/dist/text-match.d.cts +44 -0
- package/dist/text-match.d.ts +44 -0
- package/dist/text-match.mjs +13 -0
- package/dist/text-match.mjs.map +1 -0
- package/dist/types/index.cjs +7 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +16 -2
- package/dist/types/index.d.ts +16 -2
- package/dist/types/index.mjs +7 -0
- package/dist/types/index.mjs.map +1 -1
- package/dist/version-check.cjs +10 -1
- package/dist/version-check.cjs.map +1 -1
- package/dist/version-check.d.cts +18 -2
- package/dist/version-check.d.ts +18 -2
- package/dist/version-check.mjs +10 -2
- package/dist/version-check.mjs.map +1 -1
- package/package.json +14 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { D as DrizzleAdapter, T as TransactionCrudDelegator, a as TransactionCrudForwarders } from './adapter-
|
|
1
|
+
export { D as DrizzleAdapter, T as TransactionCrudDelegator, a as TransactionCrudForwarders } from './adapter-bUAaPzjV.cjs';
|
|
2
2
|
export { T as TableResolver } from './core-CVO7WYDj.cjs';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
|
-
import './migration-
|
|
4
|
+
import './migration-Bu0WLdX4.cjs';
|
|
5
5
|
import './schema-BDn8WfSL.cjs';
|
|
6
6
|
import './error-BrdknH2s.cjs';
|
|
7
7
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { D as DrizzleAdapter, T as TransactionCrudDelegator, a as TransactionCrudForwarders } from './adapter-
|
|
1
|
+
export { D as DrizzleAdapter, T as TransactionCrudDelegator, a as TransactionCrudForwarders } from './adapter-iJ5hbUvL.js';
|
|
2
2
|
export { T as TableResolver } from './core-CVO7WYDj.js';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
|
-
import './migration-
|
|
4
|
+
import './migration-BqHebSwM.js';
|
|
5
5
|
import './schema-BIQ0YQZ_.js';
|
|
6
6
|
import './error-BrdknH2s.js';
|
|
7
7
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
|
+
import { getColumns, count, sql, desc, asc, and, or, not, is, SQL, Column, notBetween, between, isNotNull, isNull, notInArray, inArray, like, lte, gte, lt, gt, ne, eq } from 'drizzle-orm';
|
|
2
3
|
|
|
3
4
|
// src/adapter.ts
|
|
4
5
|
|
|
@@ -26,6 +27,14 @@ function buildDrizzleOrderBy(columns, orderBy) {
|
|
|
26
27
|
return [spec.nulls === "last" ? asc(isNull2) : desc(isNull2), direction];
|
|
27
28
|
});
|
|
28
29
|
}
|
|
30
|
+
function containsPattern(value) {
|
|
31
|
+
return `%${value.replace(/[!%_]/g, (character) => `!${character}`)}%`;
|
|
32
|
+
}
|
|
33
|
+
function caseInsensitiveContains(column, value) {
|
|
34
|
+
return sql`lower(${column}) like lower(${containsPattern(value)}) escape '!'`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/drizzle-where.ts
|
|
29
38
|
function buildDrizzleWhere(table, where) {
|
|
30
39
|
const columns = getColumns(table);
|
|
31
40
|
return processWhereClause(columns, where);
|
|
@@ -78,9 +87,6 @@ function isWhereCondition(item) {
|
|
|
78
87
|
function namesABranch(where) {
|
|
79
88
|
return Boolean(where.and?.length || where.or?.length || where.not);
|
|
80
89
|
}
|
|
81
|
-
function containsPattern(value) {
|
|
82
|
-
return `%${value.replace(/[!%_]/g, (character) => `!${character}`)}%`;
|
|
83
|
-
}
|
|
84
90
|
function buildCondition(columns, cond) {
|
|
85
91
|
const column = columns[cond.column];
|
|
86
92
|
if (!column) {
|
|
@@ -105,7 +111,7 @@ function buildCondition(columns, cond) {
|
|
|
105
111
|
case "LIKE":
|
|
106
112
|
return like(col, cond.value);
|
|
107
113
|
case "ILIKE":
|
|
108
|
-
return
|
|
114
|
+
return sql`lower(${col}) like lower(${cond.value})`;
|
|
109
115
|
case "IN":
|
|
110
116
|
return inArray(col, cond.value);
|
|
111
117
|
case "NOT IN":
|
|
@@ -120,11 +126,45 @@ function buildCondition(columns, cond) {
|
|
|
120
126
|
return notBetween(col, cond.value, cond.valueTo);
|
|
121
127
|
case "CONTAINS":
|
|
122
128
|
return sql`${col} like ${containsPattern(String(cond.value))} escape '!'`;
|
|
129
|
+
case "ICONTAINS":
|
|
130
|
+
return caseInsensitiveContains(col, String(cond.value));
|
|
123
131
|
default:
|
|
124
132
|
throw new Error(`Unsupported operator: ${cond.op}`);
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
|
|
136
|
+
// src/pinned-transaction.ts
|
|
137
|
+
function pinTransactions(db, checkout) {
|
|
138
|
+
const pinned = async (work, config) => {
|
|
139
|
+
const connection = await checkout();
|
|
140
|
+
let dirty = false;
|
|
141
|
+
let workFailure;
|
|
142
|
+
try {
|
|
143
|
+
return await connection.drizzle.transaction(async (tx) => {
|
|
144
|
+
try {
|
|
145
|
+
return await work(tx);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
workFailure = { error };
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
}, config);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
await connection.rollback().catch(() => {
|
|
153
|
+
dirty = true;
|
|
154
|
+
});
|
|
155
|
+
throw workFailure ? workFailure.error : error;
|
|
156
|
+
} finally {
|
|
157
|
+
connection.release(dirty);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
Object.defineProperty(db, "transaction", {
|
|
161
|
+
value: pinned,
|
|
162
|
+
configurable: true,
|
|
163
|
+
writable: true
|
|
164
|
+
});
|
|
165
|
+
return db;
|
|
166
|
+
}
|
|
167
|
+
|
|
128
168
|
// src/transaction-forwarders.ts
|
|
129
169
|
function createTransactionForwarders(delegator, txDb) {
|
|
130
170
|
return {
|
|
@@ -146,6 +186,20 @@ function createTransactionForwarders(delegator, txDb) {
|
|
|
146
186
|
getDrizzle: () => txDb()
|
|
147
187
|
};
|
|
148
188
|
}
|
|
189
|
+
function transactionDrizzleHandles(build) {
|
|
190
|
+
let bareInstance;
|
|
191
|
+
const bare = () => bareInstance ??= build();
|
|
192
|
+
const relational = /* @__PURE__ */ new WeakMap();
|
|
193
|
+
const withRelations = (relations) => {
|
|
194
|
+
let cached = relational.get(relations);
|
|
195
|
+
if (cached === void 0) {
|
|
196
|
+
cached = build(relations);
|
|
197
|
+
relational.set(relations, cached);
|
|
198
|
+
}
|
|
199
|
+
return cached;
|
|
200
|
+
};
|
|
201
|
+
return { bare, withRelations };
|
|
202
|
+
}
|
|
149
203
|
|
|
150
204
|
// src/types/error.ts
|
|
151
205
|
function isDatabaseError(error) {
|
|
@@ -280,6 +334,155 @@ function affectedRowCount(result) {
|
|
|
280
334
|
return 0;
|
|
281
335
|
}
|
|
282
336
|
var DrizzleAdapter = class {
|
|
337
|
+
/**
|
|
338
|
+
* Whether a `transaction()` call made from the current async context would
|
|
339
|
+
* join a transaction already open on this adapter, as a savepoint, rather
|
|
340
|
+
* than open one of its own.
|
|
341
|
+
*
|
|
342
|
+
* A caller about to do something no rollback can undo — removing a stored
|
|
343
|
+
* file, say — asks this first: work that joins an enclosing transaction is
|
|
344
|
+
* undone with it, while the effect it performs after its own savepoint
|
|
345
|
+
* releases is not.
|
|
346
|
+
*
|
|
347
|
+
* False here. Concrete rather than abstract so existing adapters keep
|
|
348
|
+
* working unchanged, and false is right for a pooled adapter: a call made
|
|
349
|
+
* inside another transaction's work opens its own transaction on its own
|
|
350
|
+
* connection, which commits independently.
|
|
351
|
+
*
|
|
352
|
+
* @returns True when the call would nest in an open transaction
|
|
353
|
+
*/
|
|
354
|
+
inTransaction() {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* The transaction each async flow is inside, kept per flow rather than per
|
|
359
|
+
* connection: on SQLite every request shares the one connection, and
|
|
360
|
+
* another request's open transaction says nothing about this one.
|
|
361
|
+
*/
|
|
362
|
+
flowTransactions = new AsyncLocalStorage();
|
|
363
|
+
/**
|
|
364
|
+
* Whether the calling async flow is inside a transaction on this adapter
|
|
365
|
+
* that has not finished: its own, or one it was started from inside.
|
|
366
|
+
*
|
|
367
|
+
* A write that must outlive any rollback — a count of a failed attempt, the
|
|
368
|
+
* spend of a single-use secret — asks this before running in a transaction
|
|
369
|
+
* of its own. Made inside an open transaction on SQLite, it joins that
|
|
370
|
+
* transaction as a savepoint and is undone with it. On PostgreSQL and MySQL
|
|
371
|
+
* it would commit on a connection of its own, so refusing it there too
|
|
372
|
+
* keeps code that passes on one dialect from failing on another. Unlike
|
|
373
|
+
* {@link inTransaction}, which asks whether a call would nest and is always
|
|
374
|
+
* false on a pooled adapter, this answers alike on every dialect, and
|
|
375
|
+
* another flow's open transaction never answers true.
|
|
376
|
+
*
|
|
377
|
+
* Covers transactions opened through {@link transaction} and through the
|
|
378
|
+
* Drizzle handle's own `transaction` on the dialects whose handle takes
|
|
379
|
+
* async work. A dialect that keeps scopes of its own judges from those
|
|
380
|
+
* instead; an adapter that does neither answers false.
|
|
381
|
+
*
|
|
382
|
+
* @experimental
|
|
383
|
+
* @returns True while a transaction the calling flow is inside is open
|
|
384
|
+
*/
|
|
385
|
+
transactionOpenInFlow() {
|
|
386
|
+
for (let at = this.flowTransactions.getStore(); at !== void 0; at = at.enclosing) {
|
|
387
|
+
if (at.open) return true;
|
|
388
|
+
}
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Run a whole transaction, from its BEGIN until its COMMIT or ROLLBACK has
|
|
393
|
+
* run, as the calling flow's open transaction, for
|
|
394
|
+
* {@link transactionOpenInFlow}. A dialect's `transaction` runs through
|
|
395
|
+
* this unless it judges the flow from scopes of its own.
|
|
396
|
+
*
|
|
397
|
+
* The transaction counts as open for its work and for anything the work
|
|
398
|
+
* starts, awaited or not, until it has finished. Something the work starts
|
|
399
|
+
* that outlives it then sees it closed, or the one enclosing it still open.
|
|
400
|
+
*
|
|
401
|
+
* @param run - The transaction, BEGIN to COMMIT or ROLLBACK
|
|
402
|
+
* @returns What `run` resolves to
|
|
403
|
+
*/
|
|
404
|
+
runInFlowTransaction(run) {
|
|
405
|
+
const scope = {
|
|
406
|
+
open: true,
|
|
407
|
+
enclosing: this.flowTransactions.getStore()
|
|
408
|
+
};
|
|
409
|
+
return this.flowTransactions.run(scope, async () => {
|
|
410
|
+
try {
|
|
411
|
+
return await run();
|
|
412
|
+
} finally {
|
|
413
|
+
scope.open = false;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Run each of a pool-bound Drizzle handle's transactions on a connection
|
|
419
|
+
* `checkout` hands it, and return that connection as the adapter's own
|
|
420
|
+
* `transaction()` does: closed rather than pooled when no ROLLBACK can be
|
|
421
|
+
* confirmed on it, and never leaked by a failed BEGIN (`pinTransactions`).
|
|
422
|
+
*
|
|
423
|
+
* For PostgreSQL's and MySQL's handles. Apply it before
|
|
424
|
+
* {@link trackFlowTransactions}, which wraps whatever `transaction` the
|
|
425
|
+
* handle has at that point.
|
|
426
|
+
*
|
|
427
|
+
* @param db - A Drizzle handle on this adapter's pool
|
|
428
|
+
* @param checkout - Checks out a connection for one transaction
|
|
429
|
+
* @returns The same handle, its `transaction` replaced
|
|
430
|
+
*/
|
|
431
|
+
pinDrizzleTransactions(db, checkout) {
|
|
432
|
+
return pinTransactions(db, checkout);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Make a Drizzle handle's own `transaction` count for
|
|
436
|
+
* {@link transactionOpenInFlow}, as the adapter's does.
|
|
437
|
+
*
|
|
438
|
+
* Core's services run their transactions through the handle on PostgreSQL
|
|
439
|
+
* and MySQL; without this, a call made inside one would be refused on
|
|
440
|
+
* SQLite, where they go through the adapter, and let through on the
|
|
441
|
+
* others. Not for SQLite's handle: its `transaction` takes only
|
|
442
|
+
* synchronous work, which no async flow can be inside.
|
|
443
|
+
*
|
|
444
|
+
* @param db - A Drizzle handle this adapter created
|
|
445
|
+
* @returns The same handle, its `transaction` tracked
|
|
446
|
+
*/
|
|
447
|
+
trackFlowTransactions(db) {
|
|
448
|
+
const transactor = db;
|
|
449
|
+
const untracked = transactor.transaction.bind(transactor);
|
|
450
|
+
const tracked = (work, config) => this.runInFlowTransaction(() => untracked(work, config));
|
|
451
|
+
Object.defineProperty(db, "transaction", {
|
|
452
|
+
value: tracked,
|
|
453
|
+
configurable: true,
|
|
454
|
+
writable: true
|
|
455
|
+
});
|
|
456
|
+
return db;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Run `effect` once the write made from the current async context has
|
|
460
|
+
* committed: an event, a hook, a cache flush, anything outside the database
|
|
461
|
+
* that must not happen for a change that is rolled back.
|
|
462
|
+
*
|
|
463
|
+
* A caller invokes this after its own transaction has resolved. Where that
|
|
464
|
+
* transaction was nested in an enclosing one, as a savepoint, the change is
|
|
465
|
+
* not durable yet, and an adapter that nests (see {@link inTransaction})
|
|
466
|
+
* holds `effect` until the outermost transaction commits, and drops it when
|
|
467
|
+
* that transaction, or the savepoint it was registered in, rolls back. A
|
|
468
|
+
* held effect runs after the commit, before the outermost `transaction()`
|
|
469
|
+
* call resolves, in registration order; one that then throws or rejects is
|
|
470
|
+
* handed to `onDeferredFailure` rather than failing a transaction that has
|
|
471
|
+
* committed.
|
|
472
|
+
*
|
|
473
|
+
* Here `effect` runs now and the returned promise settles with it, its
|
|
474
|
+
* failure included. Concrete rather than abstract, as `inTransaction` is,
|
|
475
|
+
* and right for a pooled adapter: each transaction has its own connection
|
|
476
|
+
* and has committed by the time its caller continues.
|
|
477
|
+
*
|
|
478
|
+
* @experimental
|
|
479
|
+
* @param effect - What to run once the change is durable
|
|
480
|
+
* @param onDeferredFailure - Receives the error of a held effect that fails
|
|
481
|
+
* @returns Settles once `effect` has run, or once it has been held
|
|
482
|
+
*/
|
|
483
|
+
async afterCommit(effect, _onDeferredFailure) {
|
|
484
|
+
await effect();
|
|
485
|
+
}
|
|
283
486
|
// ============================================================
|
|
284
487
|
// Drizzle Query API Support
|
|
285
488
|
// ============================================================
|
|
@@ -1227,7 +1430,8 @@ var DrizzleAdapter = class {
|
|
|
1227
1430
|
* @remarks
|
|
1228
1431
|
* Default implementation uses dialect-specific ON CONFLICT syntax.
|
|
1229
1432
|
* PostgreSQL/SQLite: ON CONFLICT ... DO UPDATE
|
|
1230
|
-
* MySQL:
|
|
1433
|
+
* MySQL: the MySQL adapter overrides this, resolving the conflict by the
|
|
1434
|
+
* conflict columns (see its `upsert`)
|
|
1231
1435
|
*
|
|
1232
1436
|
* @param table - Table name
|
|
1233
1437
|
* @param data - Record data
|
|
@@ -1264,9 +1468,12 @@ var DrizzleAdapter = class {
|
|
|
1264
1468
|
updateData[key] = data[key];
|
|
1265
1469
|
}
|
|
1266
1470
|
}
|
|
1471
|
+
const keepExisting = Object.keys(updateData).length === 0;
|
|
1472
|
+
this.assertUpsertTarget(table, data, options, keepExisting);
|
|
1267
1473
|
let query;
|
|
1268
1474
|
if (caps.supportsOnConflict) {
|
|
1269
|
-
|
|
1475
|
+
const inserted = db.insert(tableObj).values(data);
|
|
1476
|
+
query = keepExisting ? inserted.onConflictDoNothing({ target: conflictTarget }) : inserted.onConflictDoUpdate({
|
|
1270
1477
|
target: conflictTarget,
|
|
1271
1478
|
set: updateData
|
|
1272
1479
|
});
|
|
@@ -1275,21 +1482,24 @@ var DrizzleAdapter = class {
|
|
|
1275
1482
|
}
|
|
1276
1483
|
if (caps.supportsReturning) {
|
|
1277
1484
|
const result = await query.returning();
|
|
1278
|
-
|
|
1485
|
+
const row = Array.isArray(result) ? result[0] : result;
|
|
1486
|
+
if (row !== void 0) return row;
|
|
1487
|
+
} else {
|
|
1488
|
+
await query;
|
|
1279
1489
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1490
|
+
const conflictValues = options.conflictColumns.map(
|
|
1491
|
+
(column) => [column, data[column]]
|
|
1492
|
+
);
|
|
1493
|
+
if (conflictValues.length > 0 && conflictValues.every(([, value]) => value !== void 0)) {
|
|
1282
1494
|
return await this.selectOne(
|
|
1283
1495
|
table,
|
|
1284
1496
|
{
|
|
1285
1497
|
where: {
|
|
1286
|
-
and: [
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
]
|
|
1498
|
+
and: conflictValues.map(([column, value]) => ({
|
|
1499
|
+
column,
|
|
1500
|
+
op: "=",
|
|
1501
|
+
value
|
|
1502
|
+
}))
|
|
1293
1503
|
}
|
|
1294
1504
|
},
|
|
1295
1505
|
executor
|
|
@@ -1533,11 +1743,11 @@ var DrizzleAdapter = class {
|
|
|
1533
1743
|
*/
|
|
1534
1744
|
async tableExists(tableName, schema) {
|
|
1535
1745
|
try {
|
|
1536
|
-
let
|
|
1746
|
+
let sql6;
|
|
1537
1747
|
const params = [];
|
|
1538
1748
|
switch (this.dialect) {
|
|
1539
1749
|
case "postgresql":
|
|
1540
|
-
|
|
1750
|
+
sql6 = `
|
|
1541
1751
|
SELECT EXISTS (
|
|
1542
1752
|
SELECT FROM information_schema.tables
|
|
1543
1753
|
WHERE table_schema = COALESCE($1, (
|
|
@@ -1551,7 +1761,7 @@ var DrizzleAdapter = class {
|
|
|
1551
1761
|
params.push(schema ?? null, tableName);
|
|
1552
1762
|
break;
|
|
1553
1763
|
case "mysql":
|
|
1554
|
-
|
|
1764
|
+
sql6 = `
|
|
1555
1765
|
SELECT COUNT(*) as count
|
|
1556
1766
|
FROM information_schema.tables
|
|
1557
1767
|
WHERE table_schema = DATABASE()
|
|
@@ -1560,7 +1770,7 @@ var DrizzleAdapter = class {
|
|
|
1560
1770
|
params.push(tableName);
|
|
1561
1771
|
break;
|
|
1562
1772
|
case "sqlite":
|
|
1563
|
-
|
|
1773
|
+
sql6 = `
|
|
1564
1774
|
SELECT COUNT(*) as count
|
|
1565
1775
|
FROM sqlite_master
|
|
1566
1776
|
WHERE type = 'table'
|
|
@@ -1576,7 +1786,7 @@ var DrizzleAdapter = class {
|
|
|
1576
1786
|
);
|
|
1577
1787
|
}
|
|
1578
1788
|
const results = await this.executeQuery(
|
|
1579
|
-
|
|
1789
|
+
sql6,
|
|
1580
1790
|
params
|
|
1581
1791
|
);
|
|
1582
1792
|
if (results.length === 0) {
|
|
@@ -1608,11 +1818,11 @@ var DrizzleAdapter = class {
|
|
|
1608
1818
|
*/
|
|
1609
1819
|
async listTables(schema) {
|
|
1610
1820
|
try {
|
|
1611
|
-
let
|
|
1821
|
+
let sql6;
|
|
1612
1822
|
const params = [];
|
|
1613
1823
|
switch (this.dialect) {
|
|
1614
1824
|
case "postgresql":
|
|
1615
|
-
|
|
1825
|
+
sql6 = `
|
|
1616
1826
|
SELECT table_name
|
|
1617
1827
|
FROM information_schema.tables
|
|
1618
1828
|
WHERE table_schema = $1
|
|
@@ -1622,7 +1832,7 @@ var DrizzleAdapter = class {
|
|
|
1622
1832
|
params.push(schema ?? "public");
|
|
1623
1833
|
break;
|
|
1624
1834
|
case "mysql":
|
|
1625
|
-
|
|
1835
|
+
sql6 = `
|
|
1626
1836
|
SELECT table_name AS table_name
|
|
1627
1837
|
FROM information_schema.tables
|
|
1628
1838
|
WHERE table_schema = DATABASE()
|
|
@@ -1631,7 +1841,7 @@ var DrizzleAdapter = class {
|
|
|
1631
1841
|
`;
|
|
1632
1842
|
break;
|
|
1633
1843
|
case "sqlite":
|
|
1634
|
-
|
|
1844
|
+
sql6 = `
|
|
1635
1845
|
SELECT name as table_name
|
|
1636
1846
|
FROM sqlite_master
|
|
1637
1847
|
WHERE type = 'table'
|
|
@@ -1647,7 +1857,7 @@ var DrizzleAdapter = class {
|
|
|
1647
1857
|
);
|
|
1648
1858
|
}
|
|
1649
1859
|
const results = await this.executeQuery(
|
|
1650
|
-
|
|
1860
|
+
sql6,
|
|
1651
1861
|
params
|
|
1652
1862
|
);
|
|
1653
1863
|
return results.map((row) => row.table_name);
|
|
@@ -1713,6 +1923,16 @@ var DrizzleAdapter = class {
|
|
|
1713
1923
|
createTransactionForwarders(txDb) {
|
|
1714
1924
|
return createTransactionForwarders(this, txDb);
|
|
1715
1925
|
}
|
|
1926
|
+
/**
|
|
1927
|
+
* The Drizzle handles one transaction hands out; see
|
|
1928
|
+
* `transactionDrizzleHandles`. `build` makes an instance on the
|
|
1929
|
+
* transaction's own connection, with the relations config when given one.
|
|
1930
|
+
*
|
|
1931
|
+
* @protected
|
|
1932
|
+
*/
|
|
1933
|
+
transactionDrizzleHandles(build) {
|
|
1934
|
+
return transactionDrizzleHandles(build);
|
|
1935
|
+
}
|
|
1716
1936
|
/**
|
|
1717
1937
|
* A transaction context's `update`, for each adapter to bind.
|
|
1718
1938
|
*
|
|
@@ -1812,6 +2032,29 @@ var DrizzleAdapter = class {
|
|
|
1812
2032
|
bindUnmodeledStructuredAsJson(value) {
|
|
1813
2033
|
return bindStructuredAsJson(value);
|
|
1814
2034
|
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Refuse an upsert target every dialect would not answer alike: a conflict
|
|
2037
|
+
* column named twice, which SQLite rejects as no constraint's target and
|
|
2038
|
+
* MySQL would accept; and, when nothing is to be updated, a conflict column
|
|
2039
|
+
* left for the database to fill, since the row that stands is then read
|
|
2040
|
+
* back by a value the caller never gave. Shared with the dialects that
|
|
2041
|
+
* override `upsert`, so the refusals are one rule.
|
|
2042
|
+
*/
|
|
2043
|
+
assertUpsertTarget(table, data, options, keepExisting) {
|
|
2044
|
+
const columns = options.conflictColumns;
|
|
2045
|
+
if (new Set(columns).size !== columns.length) {
|
|
2046
|
+
throw createDatabaseError({
|
|
2047
|
+
kind: "query",
|
|
2048
|
+
message: `upsert on ${table} names a conflict column more than once (${columns.join(", ")}).`
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
if (keepExisting && columns.some((column) => data[column] === void 0)) {
|
|
2052
|
+
throw createDatabaseError({
|
|
2053
|
+
kind: "query",
|
|
2054
|
+
message: `upsert on ${table} needs a value for every conflict column (${columns.join(", ")}).`
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
1815
2058
|
/**
|
|
1816
2059
|
* The columns of a table-level `primaryKey({ columns })`, as the dialect's
|
|
1817
2060
|
* table config reports them. The base class cannot read that config without
|
|
@@ -1870,6 +2113,34 @@ var DrizzleAdapter = class {
|
|
|
1870
2113
|
updateReturnsRows(returning) {
|
|
1871
2114
|
return returning !== void 0 && !(Array.isArray(returning) && returning.length === 0);
|
|
1872
2115
|
}
|
|
2116
|
+
/**
|
|
2117
|
+
* The driver's own error inside `error`: the first in its `cause` chain that
|
|
2118
|
+
* `isDriverError` recognises, or `error` itself when none does.
|
|
2119
|
+
*
|
|
2120
|
+
* A query that runs through Drizzle fails with Drizzle's `DrizzleQueryError`,
|
|
2121
|
+
* whose message is the SQL statement and which carries no driver code; the
|
|
2122
|
+
* driver's error, the only object that knows what actually went wrong, is
|
|
2123
|
+
* its `cause`. A dialect's {@link classifyError} classifies from what this
|
|
2124
|
+
* returns, so a failure reads the same whether or not Drizzle wrapped it.
|
|
2125
|
+
*
|
|
2126
|
+
* The walk is bounded, because an error chain can be made cyclic and a
|
|
2127
|
+
* classifier that can hang is worse than one that gives up. Falling back to
|
|
2128
|
+
* `error` keeps an error that carries no code anywhere classified as before.
|
|
2129
|
+
*
|
|
2130
|
+
* @param error - The error as it was caught
|
|
2131
|
+
* @param isDriverError - Whether a link in the chain is the driver's error
|
|
2132
|
+
* @returns The driver's error, or `error` when no link is
|
|
2133
|
+
*/
|
|
2134
|
+
driverErrorIn(error, isDriverError) {
|
|
2135
|
+
let cursor = error;
|
|
2136
|
+
for (let depth = 0; depth < 10; depth++) {
|
|
2137
|
+
if (cursor === null || typeof cursor !== "object") break;
|
|
2138
|
+
const candidate = cursor;
|
|
2139
|
+
if (isDriverError(candidate)) return candidate;
|
|
2140
|
+
cursor = candidate.cause;
|
|
2141
|
+
}
|
|
2142
|
+
return error ?? {};
|
|
2143
|
+
}
|
|
1873
2144
|
/**
|
|
1874
2145
|
* Classify an error into a DatabaseError.
|
|
1875
2146
|
*
|
|
@@ -1882,14 +2153,14 @@ var DrizzleAdapter = class {
|
|
|
1882
2153
|
*
|
|
1883
2154
|
* @protected
|
|
1884
2155
|
*/
|
|
1885
|
-
classifyError(error,
|
|
2156
|
+
classifyError(error, sql6) {
|
|
1886
2157
|
if (isDatabaseError(error)) {
|
|
1887
2158
|
return error;
|
|
1888
2159
|
}
|
|
1889
2160
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1890
2161
|
return this.createDatabaseError(
|
|
1891
2162
|
"query",
|
|
1892
|
-
|
|
2163
|
+
sql6 ? `Query failed: ${errorMessage}` : errorMessage,
|
|
1893
2164
|
error instanceof Error ? error : void 0
|
|
1894
2165
|
);
|
|
1895
2166
|
}
|