@prisma-next/adapter-postgres 0.13.0 → 0.14.0-dev.2
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-CAlWA4ug.mjs → adapter-CwkcdpM_.mjs} +3 -3
- package/dist/adapter-CwkcdpM_.mjs.map +1 -0
- package/dist/adapter.d.mts +1 -1
- package/dist/adapter.d.mts.map +1 -1
- package/dist/adapter.mjs +1 -1
- package/dist/column-types.d.mts +1 -6
- package/dist/column-types.d.mts.map +1 -1
- package/dist/column-types.mjs +2 -17
- package/dist/column-types.mjs.map +1 -1
- package/dist/{control-adapter-ZWrjGBq7.mjs → control-adapter-Dspz5uKp.mjs} +227 -226
- package/dist/control-adapter-Dspz5uKp.mjs.map +1 -0
- package/dist/control.d.mts +25 -22
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +3 -3
- package/dist/control.mjs.map +1 -1
- package/dist/{descriptor-meta-NBwpqHS7.mjs → descriptor-meta-DOgMfoqm.mjs} +10 -3
- package/dist/descriptor-meta-DOgMfoqm.mjs.map +1 -0
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/{types-Dv7M8jx8.d.mts → types-KXRwRZU8.d.mts} +3 -3
- package/dist/types-KXRwRZU8.d.mts.map +1 -0
- package/dist/types.d.mts +1 -1
- package/package.json +22 -22
- package/src/core/adapter.ts +5 -4
- package/src/core/codec-lookup.ts +5 -5
- package/src/core/control-adapter.ts +261 -86
- package/src/core/control-codecs.ts +25 -0
- package/src/core/descriptor-meta.ts +3 -0
- package/src/core/marker-ledger.ts +2 -18
- package/src/core/sql-renderer.ts +146 -8
- package/src/core/types.ts +2 -2
- package/src/exports/column-types.ts +0 -20
- package/src/exports/control.ts +1 -0
- package/dist/adapter-CAlWA4ug.mjs.map +0 -1
- package/dist/control-adapter-ZWrjGBq7.mjs.map +0 -1
- package/dist/descriptor-meta-NBwpqHS7.mjs.map +0 -1
- package/dist/types-Dv7M8jx8.d.mts.map +0 -1
- package/src/core/ddl-renderer.ts +0 -155
- package/src/core/enum-control-hooks.ts +0 -141
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
PG_TIMESTAMP_CODEC_ID,
|
|
28
28
|
PG_TIMESTAMPTZ_CODEC_ID,
|
|
29
29
|
PG_TIMETZ_CODEC_ID,
|
|
30
|
+
PG_UUID_CODEC_ID,
|
|
30
31
|
PG_VARBIT_CODEC_ID,
|
|
31
32
|
PG_VARCHAR_CODEC_ID,
|
|
32
33
|
SQL_CHAR_CODEC_ID,
|
|
@@ -215,6 +216,7 @@ export const postgresAdapterDescriptorMeta = {
|
|
|
215
216
|
[PG_JSON_CODEC_ID]: identityHooks,
|
|
216
217
|
[PG_JSONB_CODEC_ID]: identityHooks,
|
|
217
218
|
[PG_BYTEA_CODEC_ID]: identityHooks,
|
|
219
|
+
[PG_UUID_CODEC_ID]: identityHooks,
|
|
218
220
|
},
|
|
219
221
|
},
|
|
220
222
|
storage: [
|
|
@@ -281,6 +283,7 @@ export const postgresAdapterDescriptorMeta = {
|
|
|
281
283
|
{ typeId: PG_JSON_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'json' },
|
|
282
284
|
{ typeId: PG_JSONB_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'jsonb' },
|
|
283
285
|
{ typeId: PG_BYTEA_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bytea' },
|
|
286
|
+
{ typeId: PG_UUID_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'uuid' },
|
|
284
287
|
],
|
|
285
288
|
queryOperationTypes: {
|
|
286
289
|
import: {
|
|
@@ -4,13 +4,7 @@ import {
|
|
|
4
4
|
type LoweredStatement,
|
|
5
5
|
RawExpr,
|
|
6
6
|
} from '@prisma-next/sql-relational-core/ast';
|
|
7
|
-
import {
|
|
8
|
-
createAstCodecRegistry,
|
|
9
|
-
deriveParamMetadata,
|
|
10
|
-
encodeParamsWithMetadata,
|
|
11
|
-
} from '@prisma-next/sql-runtime';
|
|
12
7
|
import { PG_TIMESTAMPTZ_CODEC_ID } from '@prisma-next/target-postgres/codec-ids';
|
|
13
|
-
import { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';
|
|
14
8
|
import {
|
|
15
9
|
int4,
|
|
16
10
|
int8,
|
|
@@ -20,8 +14,7 @@ import {
|
|
|
20
14
|
textArray,
|
|
21
15
|
timestamptz,
|
|
22
16
|
} from '@prisma-next/target-postgres/contract-free';
|
|
23
|
-
|
|
24
|
-
const CONTROL_CODECS = createAstCodecRegistry(postgresCodecRegistry);
|
|
17
|
+
import { encodeControlQueryParams } from './control-codecs';
|
|
25
18
|
|
|
26
19
|
export const marker = pgTable(
|
|
27
20
|
{ name: 'marker', schema: 'prisma_contract' },
|
|
@@ -105,16 +98,7 @@ export async function execute(
|
|
|
105
98
|
query: AnyQueryAst,
|
|
106
99
|
): Promise<readonly Record<string, unknown>[]> {
|
|
107
100
|
const lowered = lower(query);
|
|
108
|
-
const
|
|
109
|
-
if (slot.kind === 'literal') return slot.value;
|
|
110
|
-
throw new Error('Postgres control DML lowered to a bind parameter, which is unsupported');
|
|
111
|
-
});
|
|
112
|
-
const encoded = await encodeParamsWithMetadata(
|
|
113
|
-
values,
|
|
114
|
-
deriveParamMetadata(query),
|
|
115
|
-
{},
|
|
116
|
-
CONTROL_CODECS,
|
|
117
|
-
);
|
|
101
|
+
const encoded = await encodeControlQueryParams(lowered, query);
|
|
118
102
|
const result = await driver.query(lowered.sql, encoded);
|
|
119
103
|
return result.rows;
|
|
120
104
|
}
|
package/src/core/sql-renderer.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { JsonValue } from '@prisma-next/contract/types';
|
|
1
2
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
2
3
|
import { runtimeError } from '@prisma-next/framework-components/runtime';
|
|
3
4
|
import {
|
|
@@ -31,7 +32,6 @@ import {
|
|
|
31
32
|
type UpdateAst,
|
|
32
33
|
type WindowFuncExpr,
|
|
33
34
|
} from '@prisma-next/sql-relational-core/ast';
|
|
34
|
-
import { PostgresTableSource } from '@prisma-next/target-postgres/contract-free';
|
|
35
35
|
import { escapeLiteral, quoteIdentifier } from '@prisma-next/target-postgres/sql-utils';
|
|
36
36
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
37
37
|
import type { PostgresContract } from './types';
|
|
@@ -175,12 +175,13 @@ function renderLimitOffset(
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
function renderSelect(ast: SelectAst, contract: PostgresContract, pim: ParamIndexMap): string {
|
|
178
|
-
const
|
|
178
|
+
const sourcesByRef = collectTableSources(ast);
|
|
179
|
+
const selectClause = `SELECT ${renderDistinctPrefix(ast.distinct, ast.distinctOn, sourcesByRef, contract, pim)}${renderProjection(
|
|
179
180
|
ast.projection,
|
|
180
181
|
contract,
|
|
181
182
|
pim,
|
|
182
183
|
)}`;
|
|
183
|
-
const fromClause = `FROM ${renderSource(ast.from, contract, pim)}
|
|
184
|
+
const fromClause = ast.from !== undefined ? `FROM ${renderSource(ast.from, contract, pim)}` : '';
|
|
184
185
|
|
|
185
186
|
const joinsClause = ast.joins?.length
|
|
186
187
|
? ast.joins.map((join) => renderJoin(join, contract, pim)).join(' ')
|
|
@@ -194,7 +195,7 @@ function renderSelect(ast: SelectAst, contract: PostgresContract, pim: ParamInde
|
|
|
194
195
|
const orderClause = ast.orderBy?.length
|
|
195
196
|
? `ORDER BY ${ast.orderBy
|
|
196
197
|
.map((order) => {
|
|
197
|
-
const expr =
|
|
198
|
+
const expr = renderOrderByExpr(order.expr, sourcesByRef, contract, pim);
|
|
198
199
|
return `${expr} ${order.dir.toUpperCase()}`;
|
|
199
200
|
})
|
|
200
201
|
.join(', ')}`
|
|
@@ -218,6 +219,129 @@ function renderSelect(ast: SelectAst, contract: PostgresContract, pim: ParamInde
|
|
|
218
219
|
return clauses.trim();
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Storage coordinate a query-level table reference (alias or bare name) resolves to. The ORDER BY enum hook uses this to look a column-ref's storage column up and read its value-set.
|
|
224
|
+
*/
|
|
225
|
+
interface TableSourceCoordinate {
|
|
226
|
+
readonly name: string;
|
|
227
|
+
readonly namespaceId: string | undefined;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Map a SELECT's table references (the FROM source and any JOIN sources) to their storage coordinate, keyed by the name a `ColumnRef.table` would carry (the alias when present, otherwise the table name). Derived-table sources are skipped — their columns are projected through a sub-select, not a base storage column, so the enum hook does not apply.
|
|
232
|
+
*/
|
|
233
|
+
function collectTableSources(ast: SelectAst): ReadonlyMap<string, TableSourceCoordinate> {
|
|
234
|
+
const sources = new Map<string, TableSourceCoordinate>();
|
|
235
|
+
const add = (source: AnyFromSource): void => {
|
|
236
|
+
if (source.kind !== 'table-source') {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const ref = source.alias ?? source.name;
|
|
240
|
+
sources.set(ref, { name: source.name, namespaceId: source.namespaceId });
|
|
241
|
+
};
|
|
242
|
+
if (ast.from !== undefined) add(ast.from);
|
|
243
|
+
for (const join of ast.joins ?? []) {
|
|
244
|
+
add(join.source);
|
|
245
|
+
}
|
|
246
|
+
return sources;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Ordered, codec-encoded values of the value-set a storage column restricts to, or `undefined` when the referenced column carries no value-set (the common, non-enum case). Resolves the column's storage coordinate from the SELECT's table sources, then the column's `valueSet` ref to the value-set's `values`.
|
|
251
|
+
*/
|
|
252
|
+
function allStrings(values: readonly JsonValue[]): values is readonly string[] {
|
|
253
|
+
return values.every((value) => typeof value === 'string');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function resolveEnumOrderValues(
|
|
257
|
+
ref: ColumnRef,
|
|
258
|
+
sourcesByRef: ReadonlyMap<string, TableSourceCoordinate>,
|
|
259
|
+
contract: PostgresContract,
|
|
260
|
+
): readonly JsonValue[] | undefined {
|
|
261
|
+
const source = sourcesByRef.get(ref.table);
|
|
262
|
+
if (source === undefined || source.namespaceId === undefined) {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
const sourceNs = contract.storage.namespaces[source.namespaceId];
|
|
266
|
+
const column =
|
|
267
|
+
sourceNs !== undefined ? sourceNs.entries.table?.[source.name]?.columns[ref.column] : undefined;
|
|
268
|
+
const valueSet = column?.valueSet;
|
|
269
|
+
if (valueSet === undefined) {
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
const valueSetNs = contract.storage.namespaces[valueSet.namespaceId];
|
|
273
|
+
return valueSetNs !== undefined
|
|
274
|
+
? valueSetNs.entries.valueSet?.[valueSet.entityName]?.values
|
|
275
|
+
: undefined;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Ordered values for an unqualified ORDER BY column (an `identifier-ref`, the shape the sql-builder emits for `.orderBy('col')`). Scans every FROM/JOIN source for a column of that name. Resolves only when exactly one source has a column of that name and it carries a value-set; if more than one source has such a column the bare identifier is ambiguous (regardless of which are enum-backed), so it falls through to the plain column rendering.
|
|
280
|
+
*/
|
|
281
|
+
function resolveEnumOrderValuesForIdentifier(
|
|
282
|
+
name: string,
|
|
283
|
+
sourcesByRef: ReadonlyMap<string, TableSourceCoordinate>,
|
|
284
|
+
contract: PostgresContract,
|
|
285
|
+
): readonly JsonValue[] | undefined {
|
|
286
|
+
let matchedColumns = 0;
|
|
287
|
+
let resolved: readonly JsonValue[] | undefined;
|
|
288
|
+
for (const source of sourcesByRef.values()) {
|
|
289
|
+
if (source.namespaceId === undefined) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const identNs = contract.storage.namespaces[source.namespaceId];
|
|
293
|
+
const column =
|
|
294
|
+
identNs !== undefined ? identNs.entries.table?.[source.name]?.columns[name] : undefined;
|
|
295
|
+
if (column === undefined) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
matchedColumns += 1;
|
|
299
|
+
if (matchedColumns > 1) {
|
|
300
|
+
return undefined;
|
|
301
|
+
}
|
|
302
|
+
const valueSet = column.valueSet;
|
|
303
|
+
if (valueSet === undefined) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
const valueSetNs = contract.storage.namespaces[valueSet.namespaceId];
|
|
307
|
+
resolved =
|
|
308
|
+
valueSetNs !== undefined
|
|
309
|
+
? valueSetNs.entries.valueSet?.[valueSet.entityName]?.values
|
|
310
|
+
: undefined;
|
|
311
|
+
}
|
|
312
|
+
return resolved;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Render an ORDER BY expression. A column reference onto an enum-restricted column sorts by declaration order via `array_position(ARRAY[…]::text[], <col>)` over the value-set's ordered values (NULLs return `NULL` from `array_position`, sorting per the clause's default NULL handling). Both qualified `column-ref`s and the unqualified `identifier-ref`s the sql-builder emits for `.orderBy('col')` are intercepted. Every other expression renders unchanged.
|
|
317
|
+
*/
|
|
318
|
+
function renderOrderByExpr(
|
|
319
|
+
expr: AnyExpression,
|
|
320
|
+
sourcesByRef: ReadonlyMap<string, TableSourceCoordinate>,
|
|
321
|
+
contract: PostgresContract,
|
|
322
|
+
pim: ParamIndexMap,
|
|
323
|
+
): string {
|
|
324
|
+
// Only TEXT enums lower to a value-set whose ORDER BY rewrite ships in this
|
|
325
|
+
// slice. Numeric-enum ORDER BY is future work; until then a non-string
|
|
326
|
+
// value-set falls through to plain column rendering rather than emitting a
|
|
327
|
+
// wrong numeric-as-text ARRAY.
|
|
328
|
+
if (expr.kind === 'column-ref') {
|
|
329
|
+
const orderValues = resolveEnumOrderValues(expr, sourcesByRef, contract);
|
|
330
|
+
if (orderValues !== undefined && allStrings(orderValues)) {
|
|
331
|
+
const array = orderValues.map((value) => `'${escapeLiteral(value)}'`).join(', ');
|
|
332
|
+
return `array_position(ARRAY[${array}]::text[], ${renderColumn(expr)})`;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (expr.kind === 'identifier-ref') {
|
|
336
|
+
const orderValues = resolveEnumOrderValuesForIdentifier(expr.name, sourcesByRef, contract);
|
|
337
|
+
if (orderValues !== undefined && allStrings(orderValues)) {
|
|
338
|
+
const array = orderValues.map((value) => `'${escapeLiteral(value)}'`).join(', ');
|
|
339
|
+
return `array_position(ARRAY[${array}]::text[], ${quoteIdentifier(expr.name)})`;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return renderExpr(expr, contract, pim);
|
|
343
|
+
}
|
|
344
|
+
|
|
221
345
|
function renderProjection(
|
|
222
346
|
projection: ReadonlyArray<ProjectionItem>,
|
|
223
347
|
contract: PostgresContract,
|
|
@@ -258,11 +382,14 @@ function renderReturning(
|
|
|
258
382
|
function renderDistinctPrefix(
|
|
259
383
|
distinct: true | undefined,
|
|
260
384
|
distinctOn: ReadonlyArray<AnyExpression> | undefined,
|
|
385
|
+
sourcesByRef: ReadonlyMap<string, TableSourceCoordinate>,
|
|
261
386
|
contract: PostgresContract,
|
|
262
387
|
pim: ParamIndexMap,
|
|
263
388
|
): string {
|
|
264
389
|
if (distinctOn && distinctOn.length > 0) {
|
|
265
|
-
const rendered = distinctOn
|
|
390
|
+
const rendered = distinctOn
|
|
391
|
+
.map((expr) => renderOrderByExpr(expr, sourcesByRef, contract, pim))
|
|
392
|
+
.join(', ');
|
|
266
393
|
return `DISTINCT ON (${rendered}) `;
|
|
267
394
|
}
|
|
268
395
|
if (distinct) {
|
|
@@ -271,11 +398,17 @@ function renderDistinctPrefix(
|
|
|
271
398
|
return '';
|
|
272
399
|
}
|
|
273
400
|
|
|
401
|
+
function hasExplicitSchema(
|
|
402
|
+
table: Pick<TableSource, 'name' | 'namespaceId'>,
|
|
403
|
+
): table is Pick<TableSource, 'name' | 'namespaceId'> & { readonly schema: string } {
|
|
404
|
+
return 'schema' in table && typeof table.schema === 'string';
|
|
405
|
+
}
|
|
406
|
+
|
|
274
407
|
function qualifyTableFromNamespaceCoordinate(
|
|
275
408
|
table: Pick<TableSource, 'name' | 'namespaceId'>,
|
|
276
409
|
contract: PostgresContract,
|
|
277
410
|
): string {
|
|
278
|
-
if (table
|
|
411
|
+
if (hasExplicitSchema(table)) {
|
|
279
412
|
return `${quoteIdentifier(table.schema)}.${quoteIdentifier(table.name)}`;
|
|
280
413
|
}
|
|
281
414
|
if (table.namespaceId === undefined) {
|
|
@@ -315,6 +448,11 @@ function renderSource(
|
|
|
315
448
|
return renderTableSource(node, contract);
|
|
316
449
|
case 'derived-table-source':
|
|
317
450
|
return `(${renderSelect(node.query, contract, pim)}) AS ${quoteIdentifier(node.alias)}`;
|
|
451
|
+
case 'function-source': {
|
|
452
|
+
const args = node.args.map((arg) => renderExpr(arg, contract, pim)).join(', ');
|
|
453
|
+
const call = `${node.fn}(${args})`;
|
|
454
|
+
return node.alias !== undefined ? `${call} AS ${quoteIdentifier(node.alias)}` : call;
|
|
455
|
+
}
|
|
318
456
|
// v8 ignore next 4
|
|
319
457
|
default:
|
|
320
458
|
throw new Error(
|
|
@@ -712,11 +850,11 @@ function getInsertColumnOrder(
|
|
|
712
850
|
let table: { columns: Readonly<Record<string, unknown>> } | undefined;
|
|
713
851
|
if (tableRef.namespaceId !== undefined) {
|
|
714
852
|
const ns = contract.storage.namespaces[tableRef.namespaceId];
|
|
715
|
-
table = ns
|
|
853
|
+
table = ns !== undefined ? ns.entries.table?.[tableName] : undefined;
|
|
716
854
|
}
|
|
717
855
|
if (table === undefined) {
|
|
718
856
|
for (const ns of Object.values(contract.storage.namespaces)) {
|
|
719
|
-
const found = ns.entries.table[tableName];
|
|
857
|
+
const found = ns.entries.table?.[tableName];
|
|
720
858
|
if (found !== undefined) {
|
|
721
859
|
table = found;
|
|
722
860
|
break;
|
package/src/core/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Contract } from '@prisma-next/contract/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { CodecRegistry } from '@prisma-next/framework-components/codec';
|
|
3
3
|
import type { SqlStorage, StorageColumn, StorageTable } from '@prisma-next/sql-contract/types';
|
|
4
4
|
import type {
|
|
5
5
|
AnyQueryAst,
|
|
@@ -29,7 +29,7 @@ export interface PostgresAdapterOptions {
|
|
|
29
29
|
* `SqlControlAdapterDescriptor.create(stack)`) supply the assembled stack
|
|
30
30
|
* lookup so extension codecs are visible to the renderer.
|
|
31
31
|
*/
|
|
32
|
-
readonly codecLookup?:
|
|
32
|
+
readonly codecLookup?: CodecRegistry;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export type PostgresContract = Contract<SqlStorage> & { readonly target: 'postgres' };
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
PG_BIT_CODEC_ID,
|
|
10
10
|
PG_BOOL_CODEC_ID,
|
|
11
11
|
PG_BYTEA_CODEC_ID,
|
|
12
|
-
PG_ENUM_CODEC_ID,
|
|
13
12
|
PG_FLOAT4_CODEC_ID,
|
|
14
13
|
PG_FLOAT8_CODEC_ID,
|
|
15
14
|
PG_INT2_CODEC_ID,
|
|
@@ -28,7 +27,6 @@ import {
|
|
|
28
27
|
SQL_CHAR_CODEC_ID,
|
|
29
28
|
SQL_VARCHAR_CODEC_ID,
|
|
30
29
|
} from '@prisma-next/target-postgres/codec-ids';
|
|
31
|
-
import { PostgresEnumType } from '@prisma-next/target-postgres/types';
|
|
32
30
|
|
|
33
31
|
export const textColumn = {
|
|
34
32
|
codecId: PG_TEXT_CODEC_ID,
|
|
@@ -185,21 +183,3 @@ export const jsonbColumn = {
|
|
|
185
183
|
codecId: PG_JSONB_CODEC_ID,
|
|
186
184
|
nativeType: 'jsonb',
|
|
187
185
|
} as const satisfies ColumnTypeDescriptor;
|
|
188
|
-
|
|
189
|
-
export function enumType<const Values extends readonly string[]>(
|
|
190
|
-
name: string,
|
|
191
|
-
values: Values,
|
|
192
|
-
): PostgresEnumType {
|
|
193
|
-
return new PostgresEnumType({ name, nativeType: name, values });
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export function enumColumn<TypeName extends string>(
|
|
197
|
-
typeName: TypeName,
|
|
198
|
-
nativeType: string,
|
|
199
|
-
): ColumnTypeDescriptor & { readonly typeRef: TypeName } {
|
|
200
|
-
return {
|
|
201
|
-
codecId: PG_ENUM_CODEC_ID,
|
|
202
|
-
nativeType,
|
|
203
|
-
typeRef: typeName,
|
|
204
|
-
};
|
|
205
|
-
}
|
package/src/exports/control.ts
CHANGED
|
@@ -30,5 +30,6 @@ export default postgresAdapterDescriptor;
|
|
|
30
30
|
|
|
31
31
|
export { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';
|
|
32
32
|
export { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';
|
|
33
|
+
export { createPostgresBuiltinCodecLookup } from '../core/codec-lookup';
|
|
33
34
|
export { PostgresControlAdapter } from '../core/control-adapter';
|
|
34
35
|
export { escapeLiteral, qualifyName, quoteIdentifier, SqlEscapeError };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-CAlWA4ug.mjs","names":[],"sources":["../src/core/adapter.ts"],"sourcesContent":["import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AnyQueryAst,\n LowererContext,\n RawSqlLiteral,\n SqlQueryable,\n} from '@prisma-next/sql-relational-core/ast';\nimport { isDdlNode } from '@prisma-next/sql-relational-core/ast';\nimport type { RawCodecInferer } from '@prisma-next/sql-relational-core/expression';\nimport type { PostgresDdlNode } from '@prisma-next/target-postgres/ddl';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { PostgresControlAdapter } from './control-adapter';\nimport { renderLoweredDdl } from './ddl-renderer';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresAdapterOptions, PostgresContract, PostgresLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n postgres: {\n orderBy: true,\n limit: true,\n lateral: true,\n jsonAgg: true,\n returning: true,\n distinctOn: true,\n },\n sql: {\n enums: true,\n returning: true,\n defaultInInsert: true,\n lateral: true,\n },\n});\n\nclass PostgresAdapterImpl\n implements Adapter<AnyQueryAst, PostgresContract, PostgresLoweredStatement>\n{\n // These fields make the adapter instance structurally compatible with RuntimeAdapterInstance<'sql', 'postgres'> without introducing a runtime-plane dependency.\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n readonly profile: AdapterProfile<'postgres'>;\n private readonly codecLookup: CodecLookup;\n\n constructor(options?: PostgresAdapterOptions) {\n this.codecLookup = options?.codecLookup ?? createPostgresBuiltinCodecLookup();\n const controlAdapter = new PostgresControlAdapter(this.codecLookup);\n this.profile = Object.freeze({\n id: options?.profileId ?? 'postgres/default@1',\n target: 'postgres',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) =>\n controlAdapter.readMarkerDiscriminated(\n {\n familyId: 'sql',\n targetId: 'postgres',\n query: async <Row = Record<string, unknown>>(\n sql: string,\n params?: readonly unknown[],\n ) => {\n const result = await queryable.query<Row>(sql, params);\n return { rows: [...result.rows] };\n },\n close: async () => {},\n },\n APP_SPACE_ID,\n ),\n });\n }\n\n lower(\n ast: AnyQueryAst | PostgresDdlNode,\n context: LowererContext<PostgresContract>,\n ): PostgresLoweredStatement {\n if (isDdlNode(ast)) {\n return renderLoweredDdl(ast);\n }\n return renderLoweredSql(ast, context.contract, this.codecLookup);\n }\n}\n\n/** Codec-id lookup for bare-literal interpolations used by `fns.raw` on a postgres client. Contributed as the descriptor's static `rawCodecInferer` slot. */\nexport const postgresRawCodecInferer: RawCodecInferer = {\n inferCodec(value: RawSqlLiteral): string {\n switch (typeof value) {\n case 'number':\n return Number.isSafeInteger(value) && value % 1 === 0 ? 'pg/int4' : 'pg/float8';\n case 'bigint':\n return 'pg/int8';\n case 'string':\n return 'pg/text';\n case 'boolean':\n return 'pg/bool';\n case 'object':\n if (value instanceof Uint8Array) return 'pg/bytea';\n }\n throw new Error(\n 'unsupported JS value type for raw-SQL interpolation: wrap this value in `param(...)` with an explicit codec',\n );\n },\n};\n\nexport function createPostgresAdapter(options?: PostgresAdapterOptions) {\n return Object.freeze(new PostgresAdapterImpl(options));\n}\n"],"mappings":";;;;AAmBA,MAAM,sBAAsB,OAAO,OAAO;CACxC,UAAU;EACR,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,WAAW;EACX,YAAY;CACd;CACA,KAAK;EACH,OAAO;EACP,WAAW;EACX,iBAAiB;EACjB,SAAS;CACX;AACF,CAAC;AAED,IAAM,sBAAN,MAEA;CAEE,WAAoB;CACpB,WAAoB;CAEpB;CACA;CAEA,YAAY,SAAkC;EAC5C,KAAK,cAAc,SAAS,eAAe,iCAAiC;EAC5E,MAAM,iBAAiB,IAAI,uBAAuB,KAAK,WAAW;EAClE,KAAK,UAAU,OAAO,OAAO;GAC3B,IAAI,SAAS,aAAa;GAC1B,QAAQ;GACR,cAAc;GACd,aAAa,cACX,eAAe,wBACb;IACE,UAAU;IACV,UAAU;IACV,OAAO,OACL,KACA,WACG;KAEH,OAAO,EAAE,MAAM,CAAC,IAAG,MADE,UAAU,MAAW,KAAK,MAAM,EAAA,CAC3B,IAAI,EAAE;IAClC;IACA,OAAO,YAAY,CAAC;GACtB,GACA,YACF;EACJ,CAAC;CACH;CAEA,MACE,KACA,SAC0B;EAC1B,IAAI,UAAU,GAAG,GACf,OAAO,iBAAiB,GAAG;EAE7B,OAAO,iBAAiB,KAAK,QAAQ,UAAU,KAAK,WAAW;CACjE;AACF;;AAGA,MAAa,0BAA2C,EACtD,WAAW,OAA8B;CACvC,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO,OAAO,cAAc,KAAK,KAAK,QAAQ,MAAM,IAAI,YAAY;EACtE,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,UACH,IAAI,iBAAiB,YAAY,OAAO;CAC5C;CACA,MAAM,IAAI,MACR,6GACF;AACF,EACF;AAEA,SAAgB,sBAAsB,SAAkC;CACtE,OAAO,OAAO,OAAO,IAAI,oBAAoB,OAAO,CAAC;AACvD"}
|