@nextlyhq/adapter-drizzle 0.0.2-alpha.50 → 0.0.2-alpha.52
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-C-DmzBg8.d.ts → adapter-BRcXAStD.d.ts} +87 -0
- package/dist/{adapter-CZUQ2aV4.d.cts → adapter-DVoa72DA.d.cts} +87 -0
- package/dist/index.cjs +210 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +210 -2
- package/dist/index.mjs.map +1 -1
- package/dist/migrations.d.cts +1 -1
- package/dist/migrations.d.ts +1 -1
- package/package.json +3 -3
|
@@ -197,6 +197,93 @@ declare abstract class DrizzleAdapter {
|
|
|
197
197
|
* no change.
|
|
198
198
|
*/
|
|
199
199
|
protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T;
|
|
200
|
+
/**
|
|
201
|
+
* Decode a raw-SQL result row's DATE column values the way a Drizzle query
|
|
202
|
+
* would, so a write answers with the same representation a read of the same
|
|
203
|
+
* column gives.
|
|
204
|
+
*
|
|
205
|
+
* A Drizzle query path runs every value through its column definition; a
|
|
206
|
+
* raw-SQL path does not, so a dialect that stores a timestamp as a number
|
|
207
|
+
* answers a write with that number while every read answers a `Date`. Only
|
|
208
|
+
* date columns are touched, and a value that is already a `Date` is left
|
|
209
|
+
* alone, so a driver that decodes on its own is unaffected.
|
|
210
|
+
*
|
|
211
|
+
* Runs after {@link mapRowKeysToJs}: keys are Drizzle property names by then,
|
|
212
|
+
* which is what the table definition is keyed by.
|
|
213
|
+
*/
|
|
214
|
+
protected mapDateValuesFromDriver<T = unknown>(tableObj: unknown, row: T): T;
|
|
215
|
+
/**
|
|
216
|
+
* Encode a row's DATE values the way a Drizzle query would before binding
|
|
217
|
+
* them, so what lands in the column does not depend on the server's timezone.
|
|
218
|
+
*
|
|
219
|
+
* A column declared without a time zone stores a wall clock and records
|
|
220
|
+
* nothing about which zone it belongs to, so both ends have to agree. Drizzle
|
|
221
|
+
* writes UTC and reads UTC. A driver handed a `Date` writes the LOCAL wall
|
|
222
|
+
* clock instead, and the same row then reads back shifted by the offset --
|
|
223
|
+
* on a UTC server the two agree and nothing is visibly wrong, which is why
|
|
224
|
+
* this survives CI.
|
|
225
|
+
*
|
|
226
|
+
* Only date columns are touched. A value that is not a `Date` is left as it
|
|
227
|
+
* is, so a caller that already encoded one is not encoded twice.
|
|
228
|
+
*
|
|
229
|
+
* Keys may be spelled either way at this point, so both the Drizzle property
|
|
230
|
+
* name and the SQL column name resolve.
|
|
231
|
+
*/
|
|
232
|
+
protected mapDateValuesToDriver(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
|
|
233
|
+
/**
|
|
234
|
+
* Bring a row about to be written through a raw-SQL statement into the shape
|
|
235
|
+
* a Drizzle query would have bound: SQL column names for keys, encoded values
|
|
236
|
+
* for date columns.
|
|
237
|
+
*
|
|
238
|
+
* The mirror of {@link mapRowFromRawSql}. The raw-SQL write paths exist
|
|
239
|
+
* because a dialect needs SQL a Drizzle query cannot express, not because
|
|
240
|
+
* their callers want different values in the table.
|
|
241
|
+
*/
|
|
242
|
+
protected mapRowToRawSql(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
|
|
243
|
+
/**
|
|
244
|
+
* Bring a raw-SQL result row into the shape a Drizzle query would have
|
|
245
|
+
* produced: Drizzle property names for keys, decoded values for date columns.
|
|
246
|
+
*
|
|
247
|
+
* The raw-SQL write paths exist because a dialect needs SQL a Drizzle query
|
|
248
|
+
* cannot express, not because their callers want a different row shape, so
|
|
249
|
+
* every one of them ends here.
|
|
250
|
+
*/
|
|
251
|
+
protected mapRowFromRawSql<T = unknown>(tableObj: unknown, row: T, aliases?: ReadonlyArray<{
|
|
252
|
+
alias: string;
|
|
253
|
+
jsName: string;
|
|
254
|
+
}>): T;
|
|
255
|
+
/**
|
|
256
|
+
* The date columns a statement is about to return, and the alias each one's
|
|
257
|
+
* wall clock is spelled out under.
|
|
258
|
+
*
|
|
259
|
+
* A driver turns a timestamp into a `Date` using ITS zone before any of this
|
|
260
|
+
* code runs, and that conversion is lossy: a wall clock inside a
|
|
261
|
+
* daylight-saving gap is a local time that does not exist, so the driver
|
|
262
|
+
* normalizes it and the original is gone. Asking the database for the wall
|
|
263
|
+
* clock as text alongside the row is the only way to read it exactly.
|
|
264
|
+
*
|
|
265
|
+
* `"*"` covers every date column; a projection covers only the ones it asked
|
|
266
|
+
* for, so a caller still gets back what it requested and nothing more.
|
|
267
|
+
*/
|
|
268
|
+
protected dateWallClockAliases(tableObj: unknown, returning: string[] | "*" | undefined): Array<{
|
|
269
|
+
sqlName: string;
|
|
270
|
+
alias: string;
|
|
271
|
+
jsName: string;
|
|
272
|
+
}>;
|
|
273
|
+
/**
|
|
274
|
+
* Replace each date in a row with the wall clock the database spelled out,
|
|
275
|
+
* read as UTC, and drop the aliases that carried it.
|
|
276
|
+
*
|
|
277
|
+
* The statement writes a UTC wall clock, so reading one back as UTC is what
|
|
278
|
+
* makes a write and a later read agree. Whatever the column actually stored
|
|
279
|
+
* is what arrives -- a column keeping only whole seconds reports whole
|
|
280
|
+
* seconds -- because this is the database's own text, not a value
|
|
281
|
+
* reconstructed from the one that was bound.
|
|
282
|
+
*/
|
|
283
|
+
protected applyWallClockAliases<T>(row: T, aliases: ReadonlyArray<{
|
|
284
|
+
alias: string;
|
|
285
|
+
jsName: string;
|
|
286
|
+
}>): T;
|
|
200
287
|
/**
|
|
201
288
|
* Build a Drizzle column projection object (`{ propertyName: column }`) from a
|
|
202
289
|
* requested column list, used by `select` (columns) and `insert` (returning).
|
|
@@ -197,6 +197,93 @@ declare abstract class DrizzleAdapter {
|
|
|
197
197
|
* no change.
|
|
198
198
|
*/
|
|
199
199
|
protected mapRowKeysToJs<T = unknown>(tableObj: unknown, row: T): T;
|
|
200
|
+
/**
|
|
201
|
+
* Decode a raw-SQL result row's DATE column values the way a Drizzle query
|
|
202
|
+
* would, so a write answers with the same representation a read of the same
|
|
203
|
+
* column gives.
|
|
204
|
+
*
|
|
205
|
+
* A Drizzle query path runs every value through its column definition; a
|
|
206
|
+
* raw-SQL path does not, so a dialect that stores a timestamp as a number
|
|
207
|
+
* answers a write with that number while every read answers a `Date`. Only
|
|
208
|
+
* date columns are touched, and a value that is already a `Date` is left
|
|
209
|
+
* alone, so a driver that decodes on its own is unaffected.
|
|
210
|
+
*
|
|
211
|
+
* Runs after {@link mapRowKeysToJs}: keys are Drizzle property names by then,
|
|
212
|
+
* which is what the table definition is keyed by.
|
|
213
|
+
*/
|
|
214
|
+
protected mapDateValuesFromDriver<T = unknown>(tableObj: unknown, row: T): T;
|
|
215
|
+
/**
|
|
216
|
+
* Encode a row's DATE values the way a Drizzle query would before binding
|
|
217
|
+
* them, so what lands in the column does not depend on the server's timezone.
|
|
218
|
+
*
|
|
219
|
+
* A column declared without a time zone stores a wall clock and records
|
|
220
|
+
* nothing about which zone it belongs to, so both ends have to agree. Drizzle
|
|
221
|
+
* writes UTC and reads UTC. A driver handed a `Date` writes the LOCAL wall
|
|
222
|
+
* clock instead, and the same row then reads back shifted by the offset --
|
|
223
|
+
* on a UTC server the two agree and nothing is visibly wrong, which is why
|
|
224
|
+
* this survives CI.
|
|
225
|
+
*
|
|
226
|
+
* Only date columns are touched. A value that is not a `Date` is left as it
|
|
227
|
+
* is, so a caller that already encoded one is not encoded twice.
|
|
228
|
+
*
|
|
229
|
+
* Keys may be spelled either way at this point, so both the Drizzle property
|
|
230
|
+
* name and the SQL column name resolve.
|
|
231
|
+
*/
|
|
232
|
+
protected mapDateValuesToDriver(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
|
|
233
|
+
/**
|
|
234
|
+
* Bring a row about to be written through a raw-SQL statement into the shape
|
|
235
|
+
* a Drizzle query would have bound: SQL column names for keys, encoded values
|
|
236
|
+
* for date columns.
|
|
237
|
+
*
|
|
238
|
+
* The mirror of {@link mapRowFromRawSql}. The raw-SQL write paths exist
|
|
239
|
+
* because a dialect needs SQL a Drizzle query cannot express, not because
|
|
240
|
+
* their callers want different values in the table.
|
|
241
|
+
*/
|
|
242
|
+
protected mapRowToRawSql(tableObj: unknown, data: Record<string, unknown>): Record<string, unknown>;
|
|
243
|
+
/**
|
|
244
|
+
* Bring a raw-SQL result row into the shape a Drizzle query would have
|
|
245
|
+
* produced: Drizzle property names for keys, decoded values for date columns.
|
|
246
|
+
*
|
|
247
|
+
* The raw-SQL write paths exist because a dialect needs SQL a Drizzle query
|
|
248
|
+
* cannot express, not because their callers want a different row shape, so
|
|
249
|
+
* every one of them ends here.
|
|
250
|
+
*/
|
|
251
|
+
protected mapRowFromRawSql<T = unknown>(tableObj: unknown, row: T, aliases?: ReadonlyArray<{
|
|
252
|
+
alias: string;
|
|
253
|
+
jsName: string;
|
|
254
|
+
}>): T;
|
|
255
|
+
/**
|
|
256
|
+
* The date columns a statement is about to return, and the alias each one's
|
|
257
|
+
* wall clock is spelled out under.
|
|
258
|
+
*
|
|
259
|
+
* A driver turns a timestamp into a `Date` using ITS zone before any of this
|
|
260
|
+
* code runs, and that conversion is lossy: a wall clock inside a
|
|
261
|
+
* daylight-saving gap is a local time that does not exist, so the driver
|
|
262
|
+
* normalizes it and the original is gone. Asking the database for the wall
|
|
263
|
+
* clock as text alongside the row is the only way to read it exactly.
|
|
264
|
+
*
|
|
265
|
+
* `"*"` covers every date column; a projection covers only the ones it asked
|
|
266
|
+
* for, so a caller still gets back what it requested and nothing more.
|
|
267
|
+
*/
|
|
268
|
+
protected dateWallClockAliases(tableObj: unknown, returning: string[] | "*" | undefined): Array<{
|
|
269
|
+
sqlName: string;
|
|
270
|
+
alias: string;
|
|
271
|
+
jsName: string;
|
|
272
|
+
}>;
|
|
273
|
+
/**
|
|
274
|
+
* Replace each date in a row with the wall clock the database spelled out,
|
|
275
|
+
* read as UTC, and drop the aliases that carried it.
|
|
276
|
+
*
|
|
277
|
+
* The statement writes a UTC wall clock, so reading one back as UTC is what
|
|
278
|
+
* makes a write and a later read agree. Whatever the column actually stored
|
|
279
|
+
* is what arrives -- a column keeping only whole seconds reports whole
|
|
280
|
+
* seconds -- because this is the database's own text, not a value
|
|
281
|
+
* reconstructed from the one that was bound.
|
|
282
|
+
*/
|
|
283
|
+
protected applyWallClockAliases<T>(row: T, aliases: ReadonlyArray<{
|
|
284
|
+
alias: string;
|
|
285
|
+
jsName: string;
|
|
286
|
+
}>): T;
|
|
200
287
|
/**
|
|
201
288
|
* Build a Drizzle column projection object (`{ propertyName: column }`) from a
|
|
202
289
|
* requested column list, used by `select` (columns) and `insert` (returning).
|
package/dist/index.cjs
CHANGED
|
@@ -108,6 +108,36 @@ function createDatabaseError(options) {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// src/adapter.ts
|
|
111
|
+
var DATE_DATA_TYPE = /(?:^|\s)date$/;
|
|
112
|
+
var WALL_CLOCK_ALIAS_STEM = "__nx_wc";
|
|
113
|
+
var WALL_CLOCK_PATTERN = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?$/;
|
|
114
|
+
function parseWallClockAsUtc(text) {
|
|
115
|
+
const match = WALL_CLOCK_PATTERN.exec(text.trim());
|
|
116
|
+
if (!match) return void 0;
|
|
117
|
+
const [, year, month, day, hour, minute, second, fraction = ""] = match;
|
|
118
|
+
const millis = Number(`${fraction}000`.slice(0, 3));
|
|
119
|
+
const parsed = new Date(
|
|
120
|
+
Date.UTC(
|
|
121
|
+
Number(year),
|
|
122
|
+
Number(month) - 1,
|
|
123
|
+
Number(day),
|
|
124
|
+
Number(hour),
|
|
125
|
+
Number(minute),
|
|
126
|
+
Number(second),
|
|
127
|
+
millis
|
|
128
|
+
)
|
|
129
|
+
);
|
|
130
|
+
if (Number(year) < 100) parsed.setUTCFullYear(Number(year));
|
|
131
|
+
return parsed;
|
|
132
|
+
}
|
|
133
|
+
function isDateColumn(colDef) {
|
|
134
|
+
if (!colDef || typeof colDef !== "object") return false;
|
|
135
|
+
const candidate = colDef;
|
|
136
|
+
return typeof candidate.mapFromDriverValue === "function" && typeof candidate.mapToDriverValue === "function" && DATE_DATA_TYPE.test(String(candidate.dataType));
|
|
137
|
+
}
|
|
138
|
+
function carriesTimeZone(colDef) {
|
|
139
|
+
return colDef.withTimezone === true;
|
|
140
|
+
}
|
|
111
141
|
function affectedRowCount(result) {
|
|
112
142
|
if (Array.isArray(result)) {
|
|
113
143
|
const header = result[0];
|
|
@@ -304,6 +334,180 @@ var DrizzleAdapter = class {
|
|
|
304
334
|
}
|
|
305
335
|
return out;
|
|
306
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Decode a raw-SQL result row's DATE column values the way a Drizzle query
|
|
339
|
+
* would, so a write answers with the same representation a read of the same
|
|
340
|
+
* column gives.
|
|
341
|
+
*
|
|
342
|
+
* A Drizzle query path runs every value through its column definition; a
|
|
343
|
+
* raw-SQL path does not, so a dialect that stores a timestamp as a number
|
|
344
|
+
* answers a write with that number while every read answers a `Date`. Only
|
|
345
|
+
* date columns are touched, and a value that is already a `Date` is left
|
|
346
|
+
* alone, so a driver that decodes on its own is unaffected.
|
|
347
|
+
*
|
|
348
|
+
* Runs after {@link mapRowKeysToJs}: keys are Drizzle property names by then,
|
|
349
|
+
* which is what the table definition is keyed by.
|
|
350
|
+
*/
|
|
351
|
+
mapDateValuesFromDriver(tableObj, row) {
|
|
352
|
+
if (!tableObj || typeof tableObj !== "object" || !row || typeof row !== "object") {
|
|
353
|
+
return row;
|
|
354
|
+
}
|
|
355
|
+
let decoded;
|
|
356
|
+
for (const [jsName, colDef] of Object.entries(
|
|
357
|
+
tableObj
|
|
358
|
+
)) {
|
|
359
|
+
if (!isDateColumn(colDef)) continue;
|
|
360
|
+
const value = row[jsName];
|
|
361
|
+
if (value == null || value instanceof Date) continue;
|
|
362
|
+
decoded ??= { ...row };
|
|
363
|
+
decoded[jsName] = colDef.mapFromDriverValue(value);
|
|
364
|
+
}
|
|
365
|
+
return decoded ?? row;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Encode a row's DATE values the way a Drizzle query would before binding
|
|
369
|
+
* them, so what lands in the column does not depend on the server's timezone.
|
|
370
|
+
*
|
|
371
|
+
* A column declared without a time zone stores a wall clock and records
|
|
372
|
+
* nothing about which zone it belongs to, so both ends have to agree. Drizzle
|
|
373
|
+
* writes UTC and reads UTC. A driver handed a `Date` writes the LOCAL wall
|
|
374
|
+
* clock instead, and the same row then reads back shifted by the offset --
|
|
375
|
+
* on a UTC server the two agree and nothing is visibly wrong, which is why
|
|
376
|
+
* this survives CI.
|
|
377
|
+
*
|
|
378
|
+
* Only date columns are touched. A value that is not a `Date` is left as it
|
|
379
|
+
* is, so a caller that already encoded one is not encoded twice.
|
|
380
|
+
*
|
|
381
|
+
* Keys may be spelled either way at this point, so both the Drizzle property
|
|
382
|
+
* name and the SQL column name resolve.
|
|
383
|
+
*/
|
|
384
|
+
mapDateValuesToDriver(tableObj, data) {
|
|
385
|
+
if (!tableObj || typeof tableObj !== "object" || !data) return data;
|
|
386
|
+
const dateColumns = /* @__PURE__ */ new Map();
|
|
387
|
+
for (const [jsName, colDef] of Object.entries(
|
|
388
|
+
tableObj
|
|
389
|
+
)) {
|
|
390
|
+
if (!isDateColumn(colDef)) continue;
|
|
391
|
+
dateColumns.set(jsName, colDef);
|
|
392
|
+
const sqlName = colDef.name;
|
|
393
|
+
if (typeof sqlName === "string") dateColumns.set(sqlName, colDef);
|
|
394
|
+
}
|
|
395
|
+
if (dateColumns.size === 0) return data;
|
|
396
|
+
let encoded;
|
|
397
|
+
for (const [key, value] of Object.entries(data)) {
|
|
398
|
+
if (!(value instanceof Date)) continue;
|
|
399
|
+
const column = dateColumns.get(key);
|
|
400
|
+
if (!column) continue;
|
|
401
|
+
encoded ??= { ...data };
|
|
402
|
+
encoded[key] = column.mapToDriverValue(value);
|
|
403
|
+
}
|
|
404
|
+
return encoded ?? data;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Bring a row about to be written through a raw-SQL statement into the shape
|
|
408
|
+
* a Drizzle query would have bound: SQL column names for keys, encoded values
|
|
409
|
+
* for date columns.
|
|
410
|
+
*
|
|
411
|
+
* The mirror of {@link mapRowFromRawSql}. The raw-SQL write paths exist
|
|
412
|
+
* because a dialect needs SQL a Drizzle query cannot express, not because
|
|
413
|
+
* their callers want different values in the table.
|
|
414
|
+
*/
|
|
415
|
+
mapRowToRawSql(tableObj, data) {
|
|
416
|
+
return this.mapDateValuesToDriver(
|
|
417
|
+
tableObj,
|
|
418
|
+
this.mapKeysToSqlColumns(tableObj, data)
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Bring a raw-SQL result row into the shape a Drizzle query would have
|
|
423
|
+
* produced: Drizzle property names for keys, decoded values for date columns.
|
|
424
|
+
*
|
|
425
|
+
* The raw-SQL write paths exist because a dialect needs SQL a Drizzle query
|
|
426
|
+
* cannot express, not because their callers want a different row shape, so
|
|
427
|
+
* every one of them ends here.
|
|
428
|
+
*/
|
|
429
|
+
mapRowFromRawSql(tableObj, row, aliases = []) {
|
|
430
|
+
const mapped = this.mapDateValuesFromDriver(
|
|
431
|
+
tableObj,
|
|
432
|
+
this.mapRowKeysToJs(tableObj, row)
|
|
433
|
+
);
|
|
434
|
+
return this.applyWallClockAliases(mapped, aliases);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* The date columns a statement is about to return, and the alias each one's
|
|
438
|
+
* wall clock is spelled out under.
|
|
439
|
+
*
|
|
440
|
+
* A driver turns a timestamp into a `Date` using ITS zone before any of this
|
|
441
|
+
* code runs, and that conversion is lossy: a wall clock inside a
|
|
442
|
+
* daylight-saving gap is a local time that does not exist, so the driver
|
|
443
|
+
* normalizes it and the original is gone. Asking the database for the wall
|
|
444
|
+
* clock as text alongside the row is the only way to read it exactly.
|
|
445
|
+
*
|
|
446
|
+
* `"*"` covers every date column; a projection covers only the ones it asked
|
|
447
|
+
* for, so a caller still gets back what it requested and nothing more.
|
|
448
|
+
*/
|
|
449
|
+
dateWallClockAliases(tableObj, returning) {
|
|
450
|
+
if (!tableObj || typeof tableObj !== "object" || returning === void 0) {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
const requested = returning === "*" ? void 0 : new Set(returning.map(String));
|
|
454
|
+
const taken = /* @__PURE__ */ new Set();
|
|
455
|
+
for (const [jsName, colDef] of Object.entries(
|
|
456
|
+
tableObj
|
|
457
|
+
)) {
|
|
458
|
+
taken.add(jsName);
|
|
459
|
+
const columnName = colDef.name;
|
|
460
|
+
if (typeof columnName === "string") taken.add(columnName);
|
|
461
|
+
}
|
|
462
|
+
let next = 0;
|
|
463
|
+
const freeAlias = () => {
|
|
464
|
+
let candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;
|
|
465
|
+
while (taken.has(candidate)) {
|
|
466
|
+
candidate = `${WALL_CLOCK_ALIAS_STEM}${next++}`;
|
|
467
|
+
}
|
|
468
|
+
taken.add(candidate);
|
|
469
|
+
return candidate;
|
|
470
|
+
};
|
|
471
|
+
const aliases = [];
|
|
472
|
+
for (const [jsName, colDef] of Object.entries(
|
|
473
|
+
tableObj
|
|
474
|
+
)) {
|
|
475
|
+
if (!isDateColumn(colDef)) continue;
|
|
476
|
+
if (carriesTimeZone(colDef)) continue;
|
|
477
|
+
const sqlName = colDef.name;
|
|
478
|
+
if (typeof sqlName !== "string") continue;
|
|
479
|
+
if (requested && !requested.has(sqlName) && !requested.has(jsName)) {
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
aliases.push({ sqlName, alias: freeAlias(), jsName });
|
|
483
|
+
}
|
|
484
|
+
return aliases;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Replace each date in a row with the wall clock the database spelled out,
|
|
488
|
+
* read as UTC, and drop the aliases that carried it.
|
|
489
|
+
*
|
|
490
|
+
* The statement writes a UTC wall clock, so reading one back as UTC is what
|
|
491
|
+
* makes a write and a later read agree. Whatever the column actually stored
|
|
492
|
+
* is what arrives -- a column keeping only whole seconds reports whole
|
|
493
|
+
* seconds -- because this is the database's own text, not a value
|
|
494
|
+
* reconstructed from the one that was bound.
|
|
495
|
+
*/
|
|
496
|
+
applyWallClockAliases(row, aliases) {
|
|
497
|
+
if (!row || typeof row !== "object" || aliases.length === 0) return row;
|
|
498
|
+
const record = row;
|
|
499
|
+
let resolved;
|
|
500
|
+
for (const { alias, jsName } of aliases) {
|
|
501
|
+
if (!(alias in record)) continue;
|
|
502
|
+
resolved ??= { ...record };
|
|
503
|
+
const text = resolved[alias];
|
|
504
|
+
delete resolved[alias];
|
|
505
|
+
if (typeof text !== "string") continue;
|
|
506
|
+
const parsed = parseWallClockAsUtc(text);
|
|
507
|
+
if (parsed !== void 0) resolved[jsName] = parsed;
|
|
508
|
+
}
|
|
509
|
+
return resolved ?? row;
|
|
510
|
+
}
|
|
307
511
|
/**
|
|
308
512
|
* Build a Drizzle column projection object (`{ propertyName: column }`) from a
|
|
309
513
|
* requested column list, used by `select` (columns) and `insert` (returning).
|
|
@@ -1072,11 +1276,15 @@ var DrizzleAdapter = class {
|
|
|
1072
1276
|
sql = `
|
|
1073
1277
|
SELECT EXISTS (
|
|
1074
1278
|
SELECT FROM information_schema.tables
|
|
1075
|
-
WHERE table_schema = $1
|
|
1279
|
+
WHERE table_schema = COALESCE($1, (
|
|
1280
|
+
SELECT n.nspname FROM pg_class c
|
|
1281
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1282
|
+
WHERE c.oid = to_regclass($2)
|
|
1283
|
+
))
|
|
1076
1284
|
AND table_name = $2
|
|
1077
1285
|
) as exists
|
|
1078
1286
|
`;
|
|
1079
|
-
params.push(schema ??
|
|
1287
|
+
params.push(schema ?? null, tableName);
|
|
1080
1288
|
break;
|
|
1081
1289
|
case "mysql":
|
|
1082
1290
|
sql = `
|