@adminiumjs/adapter-postgres 0.1.0-rc.1

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.
@@ -0,0 +1,623 @@
1
+ /**
2
+ * Postgres introspection — 05-introspection-engine.md §4.1.
3
+ *
4
+ * Reads `pg_catalog`, not `information_schema` (too slow at 500 tables): a
5
+ * FIXED set of 7 set-based catalog queries regardless of table count, joined
6
+ * in memory. This module is executor-agnostic — `introspectPostgres` takes a
7
+ * `CatalogExecutor` (any `sql → rows` function) so the assembly logic is
8
+ * testable without the `pg` driver; `src/index.ts` wires it to the pool.
9
+ *
10
+ * THE "SCHEMA ONLY" INVARIANT (05 §10): every statement here references
11
+ * `pg_catalog.*` exclusively — no user table is ever touched during setup.
12
+ */
13
+ import { AdapterError, ENGINE_CAPABILITY_MATRIX, } from '@adminium/engine/adapter';
14
+ import { classifyDefault, mapPostgresType } from './type-map.js';
15
+ /**
16
+ * Static dialect capabilities — 05 §2.1 (probe refines per-connection).
17
+ * Canonical values live in the engine's capability matrix (M9-T04) so the
18
+ * wizard's degradation copy and the adapter never disagree.
19
+ */
20
+ export const POSTGRES_CAPABILITIES = {
21
+ ...ENGINE_CAPABILITY_MATRIX.postgres,
22
+ };
23
+ /**
24
+ * Session probe. Read-only detection per the M3 workplan: recovery mode
25
+ * (`pg_is_in_recovery()`), the session default
26
+ * (`default_transaction_read_only`), or the role lacking CREATE on the
27
+ * database (`has_database_privilege`).
28
+ */
29
+ export const PROBE_SQL = `
30
+ SELECT current_setting('server_version') AS server_version,
31
+ current_user AS role_name,
32
+ pg_catalog.current_database() AS database_name,
33
+ pg_catalog.pg_is_in_recovery() AS in_recovery,
34
+ current_setting('default_transaction_read_only') AS default_read_only,
35
+ pg_catalog.has_database_privilege(pg_catalog.current_database(), 'CREATE') AS can_create,
36
+ COALESCE(
37
+ (SELECT s.ssl FROM pg_catalog.pg_stat_ssl s WHERE s.pid = pg_catalog.pg_backend_pid()),
38
+ false
39
+ ) AS ssl`;
40
+ /** Interpret one {@link PROBE_SQL} row (executor-agnostic, pure). */
41
+ export function interpretProbe(row) {
42
+ const inRecovery = row['in_recovery'] === true || row['in_recovery'] === 't';
43
+ const defaultReadOnly = row['default_read_only'] === 'on';
44
+ const canCreate = row['can_create'] === true || row['can_create'] === 't';
45
+ return {
46
+ serverVersion: String(row['server_version'] ?? ''),
47
+ roleName: String(row['role_name'] ?? ''),
48
+ databaseName: String(row['database_name'] ?? ''),
49
+ readOnly: inRecovery || defaultReadOnly || !canCreate,
50
+ canCreate,
51
+ ssl: row['ssl'] === true || row['ssl'] === 't',
52
+ };
53
+ }
54
+ /** Migration/meta tables hidden behind "show system tables" — 05 §8.2. */
55
+ const SYSTEM_TABLE_PATTERN = /^(adminium_|knex_migrations)|^(_prisma_migrations|schema_migrations|ar_internal_metadata|django_migrations|sqlite_sequence)$/;
56
+ /** Enum values are capped at 256 with a warning — 05 §10. */
57
+ const ENUM_VALUE_CAP = 256;
58
+ // ---------------------------------------------------------------------------
59
+ // Catalog SQL (fixed set — CI asserts ≤ 12 statements, 05 §10)
60
+ // ---------------------------------------------------------------------------
61
+ function quoteLiteral(value) {
62
+ return `'${value.replaceAll("'", "''")}'`;
63
+ }
64
+ /** Predicate over `pg_namespace` alias `n` for the included schemas. */
65
+ function schemaPredicate(schemas) {
66
+ if (schemas !== null && schemas.length > 0) {
67
+ return `n.nspname IN (${schemas.map(quoteLiteral).join(', ')})`;
68
+ }
69
+ return `n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_(toast|temp)'`;
70
+ }
71
+ const SCHEMAS_SQL = `
72
+ SELECT n.nspname AS name
73
+ FROM pg_catalog.pg_namespace n
74
+ WHERE ${schemaPredicate(null)}
75
+ ORDER BY n.nspname`;
76
+ function classesSql(pred) {
77
+ return `
78
+ SELECT n.nspname AS schema_name,
79
+ c.relname AS table_name,
80
+ c.oid::int8 AS rel_oid,
81
+ c.relkind::text AS relkind,
82
+ c.relispartition AS is_partition,
83
+ c.reltuples::float8 AS reltuples,
84
+ c.relrowsecurity AS rls_enabled,
85
+ c.relforcerowsecurity AS rls_forced,
86
+ pg_catalog.obj_description(c.oid, 'pg_class') AS comment,
87
+ (SELECT count(*) FROM pg_catalog.pg_policy p WHERE p.polrelid = c.oid)::int AS policy_count,
88
+ s.n_tup_ins::int8 AS n_ins,
89
+ s.n_tup_upd::int8 AS n_upd,
90
+ s.n_tup_del::int8 AS n_del
91
+ FROM pg_catalog.pg_class c
92
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
93
+ LEFT JOIN pg_catalog.pg_stat_user_tables s ON s.relid = c.oid
94
+ WHERE c.relkind IN ('r', 'p', 'v', 'm') AND ${pred}
95
+ ORDER BY n.nspname, c.relname`;
96
+ }
97
+ /** Guarded separately: permission failures degrade to sizeBytes null (05 §4.1). */
98
+ function sizesSql(pred) {
99
+ return `
100
+ SELECT c.oid::int8 AS rel_oid,
101
+ pg_catalog.pg_total_relation_size(c.oid)::int8 AS size_bytes
102
+ FROM pg_catalog.pg_class c
103
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
104
+ WHERE c.relkind IN ('r', 'p', 'm') AND NOT c.relispartition AND ${pred}`;
105
+ }
106
+ function columnsSql(pred) {
107
+ return `
108
+ SELECT a.attrelid::int8 AS rel_oid,
109
+ a.attname AS column_name,
110
+ a.attnum::int AS ordinal,
111
+ pg_catalog.format_type(a.atttypid, a.atttypmod) AS db_type,
112
+ a.attnotnull AS not_null,
113
+ a.attidentity::text AS identity,
114
+ a.attgenerated::text AS generated,
115
+ pg_catalog.pg_get_expr(ad.adbin, ad.adrelid) AS default_expr,
116
+ pg_catalog.col_description(a.attrelid, a.attnum) AS comment,
117
+ t.typtype::text AS typtype,
118
+ t.typcategory::text AS typcategory,
119
+ tn.nspname AS type_schema,
120
+ t.typname AS type_name,
121
+ CASE WHEN t.typcategory = 'A'
122
+ THEN pg_catalog.format_type(t.typelem, a.atttypmod) END AS elem_db_type,
123
+ et.typtype::text AS elem_typtype,
124
+ etn.nspname AS elem_type_schema,
125
+ et.typname AS elem_type_name,
126
+ CASE WHEN t.typtype = 'd'
127
+ THEN pg_catalog.format_type(t.typbasetype, t.typtypmod) END AS base_db_type,
128
+ bt.typtype::text AS base_typtype,
129
+ btn.nspname AS base_type_schema,
130
+ bt.typname AS base_type_name
131
+ FROM pg_catalog.pg_attribute a
132
+ JOIN pg_catalog.pg_class c ON c.oid = a.attrelid
133
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
134
+ JOIN pg_catalog.pg_type t ON t.oid = a.atttypid
135
+ JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace
136
+ LEFT JOIN pg_catalog.pg_type et ON t.typcategory = 'A' AND et.oid = t.typelem
137
+ LEFT JOIN pg_catalog.pg_namespace etn ON etn.oid = et.typnamespace
138
+ LEFT JOIN pg_catalog.pg_type bt ON t.typtype = 'd' AND bt.oid = t.typbasetype
139
+ LEFT JOIN pg_catalog.pg_namespace btn ON btn.oid = bt.typnamespace
140
+ LEFT JOIN pg_catalog.pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
141
+ WHERE a.attnum > 0 AND NOT a.attisdropped
142
+ AND c.relkind IN ('r', 'p', 'v', 'm') AND ${pred}
143
+ ORDER BY a.attrelid, a.attnum`;
144
+ }
145
+ function constraintsSql(pred) {
146
+ return `
147
+ SELECT con.conname AS name,
148
+ con.contype::text AS contype,
149
+ con.conrelid::int8 AS rel_oid,
150
+ rn.nspname AS ref_schema,
151
+ rc.relname AS ref_table,
152
+ (SELECT pg_catalog.array_agg(a.attname ORDER BY k.ord)
153
+ FROM pg_catalog.unnest(con.conkey) WITH ORDINALITY AS k(attnum, ord)
154
+ JOIN pg_catalog.pg_attribute a
155
+ ON a.attrelid = con.conrelid AND a.attnum = k.attnum) AS columns,
156
+ (SELECT pg_catalog.array_agg(a.attname ORDER BY k.ord)
157
+ FROM pg_catalog.unnest(con.confkey) WITH ORDINALITY AS k(attnum, ord)
158
+ JOIN pg_catalog.pg_attribute a
159
+ ON a.attrelid = con.confrelid AND a.attnum = k.attnum) AS ref_columns,
160
+ con.confupdtype::text AS on_update,
161
+ con.confdeltype::text AS on_delete,
162
+ pg_catalog.pg_get_constraintdef(con.oid) AS definition
163
+ FROM pg_catalog.pg_constraint con
164
+ JOIN pg_catalog.pg_class c ON c.oid = con.conrelid
165
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
166
+ LEFT JOIN pg_catalog.pg_class rc ON rc.oid = con.confrelid
167
+ LEFT JOIN pg_catalog.pg_namespace rn ON rn.oid = rc.relnamespace
168
+ WHERE con.contype IN ('p', 'u', 'f', 'c') AND ${pred}
169
+ ORDER BY con.conname`;
170
+ }
171
+ function indexesSql(pred) {
172
+ return `
173
+ SELECT i.indrelid::int8 AS rel_oid,
174
+ ic.relname AS index_name,
175
+ i.indisunique AS is_unique,
176
+ i.indisprimary AS is_primary,
177
+ am.amname AS method,
178
+ (i.indpred IS NOT NULL) AS is_partial,
179
+ (SELECT pg_catalog.array_agg(a.attname ORDER BY k.ord)
180
+ FROM pg_catalog.unnest(i.indkey::int2[]) WITH ORDINALITY AS k(attnum, ord)
181
+ JOIN pg_catalog.pg_attribute a
182
+ ON a.attrelid = i.indrelid AND a.attnum = k.attnum
183
+ WHERE k.attnum > 0) AS columns,
184
+ pg_catalog.pg_get_expr(i.indexprs, i.indrelid) AS expression
185
+ FROM pg_catalog.pg_index i
186
+ JOIN pg_catalog.pg_class ic ON ic.oid = i.indexrelid
187
+ JOIN pg_catalog.pg_class c ON c.oid = i.indrelid
188
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
189
+ JOIN pg_catalog.pg_am am ON am.oid = ic.relam
190
+ WHERE c.relkind IN ('r', 'p', 'm') AND ${pred}
191
+ ORDER BY ic.relname`;
192
+ }
193
+ /** All non-system enums (cross-schema column references must resolve). */
194
+ const ENUMS_SQL = `
195
+ SELECT n.nspname AS schema_name,
196
+ t.typname AS enum_name,
197
+ (SELECT pg_catalog.array_agg(e.enumlabel ORDER BY e.enumsortorder)
198
+ FROM pg_catalog.pg_enum e
199
+ WHERE e.enumtypid = t.oid) AS labels
200
+ FROM pg_catalog.pg_type t
201
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
202
+ WHERE t.typtype = 'e' AND ${schemaPredicate(null)}
203
+ ORDER BY n.nspname, t.typname`;
204
+ // ---------------------------------------------------------------------------
205
+ // Row coercion (pg returns int8 as string, the json harness returns numbers)
206
+ // ---------------------------------------------------------------------------
207
+ function num(value) {
208
+ if (value === null || value === undefined)
209
+ return null;
210
+ const n = Number(value);
211
+ return Number.isFinite(n) ? n : null;
212
+ }
213
+ function str(value) {
214
+ return typeof value === 'string' && value.length > 0 ? value : null;
215
+ }
216
+ function bool(value) {
217
+ return value === true || value === 't' || value === 'true';
218
+ }
219
+ function strArray(value) {
220
+ if (Array.isArray(value))
221
+ return value.map(String);
222
+ // The pg driver returns `name[]` (OID 1003) as the raw `{a,b}` literal unless a
223
+ // type parser is registered; the psql/json_agg harness returns real JSON arrays.
224
+ // Accept both so introspection is executor-agnostic for real.
225
+ if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) {
226
+ const inner = value.slice(1, -1);
227
+ if (inner === '')
228
+ return [];
229
+ // Identifiers needing quotes ("a,b") are split naively here; catalog column
230
+ // names with embedded commas/quotes are out of scope for v1 (noted 05 §4.1).
231
+ return inner.split(',').map((s) => s.replace(/^"(.*)"$/, '$1'));
232
+ }
233
+ return [];
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // CHECK (col IN (...)) → EnumDef synthesis — 05 §4.1
237
+ // ---------------------------------------------------------------------------
238
+ const CHECK_ANY_PATTERN = /\(?"?([a-zA-Z_][\w$]*)"?\)?(?:::[\w "]+(?:\(\d+(?:,\s*\d+)?\))?)?\s*=\s*ANY\s*\(\(?\s*ARRAY\[([^\]]+)\]/;
239
+ const CHECK_IN_PATTERN = /"?([a-zA-Z_][\w$]*)"?\s+IN\s+\(([^)]+)\)/i;
240
+ /** Parse `col = ANY (ARRAY['a', 'b'])` / `col IN ('a','b')` check shapes. */
241
+ export function parseCheckEnum(definition) {
242
+ const match = CHECK_ANY_PATTERN.exec(definition) ?? CHECK_IN_PATTERN.exec(definition);
243
+ if (match?.[1] === undefined || match[2] === undefined)
244
+ return null;
245
+ const values = [];
246
+ for (const literal of match[2].matchAll(/'((?:[^']|'')*)'/g)) {
247
+ values.push((literal[1] ?? '').replaceAll("''", "'"));
248
+ }
249
+ return values.length > 0 ? { column: match[1], values } : null;
250
+ }
251
+ /** `CHECK ((expr))` → `expr` (strip prefix + one balanced outer paren pair). */
252
+ function checkExpression(definition) {
253
+ let text = definition.replace(/^CHECK\s*/i, '').trim();
254
+ while (text.startsWith('(') && text.endsWith(')')) {
255
+ let depth = 0;
256
+ let wraps = true;
257
+ for (let i = 0; i < text.length; i += 1) {
258
+ if (text[i] === '(')
259
+ depth += 1;
260
+ else if (text[i] === ')')
261
+ depth -= 1;
262
+ if (depth === 0 && i < text.length - 1) {
263
+ wraps = false;
264
+ break;
265
+ }
266
+ }
267
+ if (!wraps)
268
+ break;
269
+ text = text.slice(1, -1).trim();
270
+ }
271
+ return text;
272
+ }
273
+ // ---------------------------------------------------------------------------
274
+ // Assembly
275
+ // ---------------------------------------------------------------------------
276
+ const FK_ACTION_MAP = {
277
+ a: 'no-action',
278
+ r: 'restrict',
279
+ c: 'cascade',
280
+ n: 'set-null',
281
+ d: 'set-default',
282
+ };
283
+ function compareBy(key) {
284
+ return (a, b) => {
285
+ const ka = key(a);
286
+ const kb = key(b);
287
+ return ka < kb ? -1 : ka > kb ? 1 : 0;
288
+ };
289
+ }
290
+ /**
291
+ * Run the fixed catalog query set through `exec` and assemble the
292
+ * `DatabaseModel`. Schema only — never touches user rows.
293
+ */
294
+ export async function introspectPostgres(exec, ctx, opts = {}) {
295
+ const startedAt = Date.now();
296
+ const timeoutMs = opts.timeoutMs ?? 30_000;
297
+ const collectRowEstimates = opts.collectRowEstimates ?? true;
298
+ const collectActivityStats = opts.collectActivityStats ?? true;
299
+ const warnings = [];
300
+ const guarded = async (sql) => {
301
+ if (Date.now() - startedAt > timeoutMs) {
302
+ throw new AdapterError('TIMEOUT', 'introspection exceeded the total time budget', {
303
+ detail: `timeoutMs=${timeoutMs}`,
304
+ hint: 'raise IntrospectOptions.timeoutMs or narrow the schema selection',
305
+ });
306
+ }
307
+ return exec(sql);
308
+ };
309
+ // 1. Schemas ---------------------------------------------------------------
310
+ const allSchemas = (await guarded(SCHEMAS_SQL))
311
+ .map((row) => str(row['name']))
312
+ .filter((name) => name !== null);
313
+ const requested = opts.schemas ?? null;
314
+ const schemas = requested === null ? allSchemas : requested.filter((name) => allSchemas.includes(name));
315
+ const pred = schemaPredicate(requested === null ? null : schemas);
316
+ // 2. Classes ---------------------------------------------------------------
317
+ const classRows = await guarded(classesSql(pred));
318
+ // 3. Sizes (guarded: permission failures degrade to sizeBytes null) --------
319
+ let sizeByOid = new Map();
320
+ try {
321
+ const sizeRows = await guarded(sizesSql(pred));
322
+ sizeByOid = new Map(sizeRows.map((row) => [num(row['rel_oid']) ?? -1, num(row['size_bytes']) ?? 0]));
323
+ }
324
+ catch (error) {
325
+ if (error instanceof AdapterError && error.code === 'TIMEOUT')
326
+ throw error;
327
+ warnings.push({
328
+ code: 'size-unavailable',
329
+ message: 'pg_total_relation_size failed (insufficient privileges?) — sizeBytes omitted',
330
+ tableId: null,
331
+ });
332
+ }
333
+ // 4–6. Columns, constraints, indexes ---------------------------------------
334
+ const columnRows = await guarded(columnsSql(pred));
335
+ const constraintRows = await guarded(constraintsSql(pred));
336
+ const indexRows = await guarded(indexesSql(pred));
337
+ // 7. Enums (all non-system so cross-schema references resolve) -------------
338
+ const enumRows = await guarded(ENUMS_SQL);
339
+ // -- native enum defs -------------------------------------------------------
340
+ const nativeEnums = new Map();
341
+ for (const row of enumRows) {
342
+ const schema = str(row['schema_name']) ?? '';
343
+ const name = str(row['enum_name']) ?? '';
344
+ const id = `${schema}.${name}`;
345
+ let values = strArray(row['labels']);
346
+ if (values.length > ENUM_VALUE_CAP) {
347
+ warnings.push({
348
+ code: 'enum-capped',
349
+ message: `enum "${id}" has ${values.length} values; capped at ${ENUM_VALUE_CAP}`,
350
+ tableId: null,
351
+ });
352
+ values = values.slice(0, ENUM_VALUE_CAP);
353
+ }
354
+ nativeEnums.set(id, { id, name, values, source: 'native' });
355
+ }
356
+ // -- tables -----------------------------------------------------------------
357
+ const tablesByOid = new Map();
358
+ let hiddenPartitions = 0;
359
+ for (const row of classRows) {
360
+ const schema = str(row['schema_name']) ?? '';
361
+ const name = str(row['table_name']) ?? '';
362
+ if (bool(row['is_partition'])) {
363
+ hiddenPartitions += 1;
364
+ continue;
365
+ }
366
+ if (opts.tableFilter !== undefined && !opts.tableFilter({ schema, name }))
367
+ continue;
368
+ const oid = num(row['rel_oid']) ?? -1;
369
+ const relkind = str(row['relkind']) ?? 'r';
370
+ const kind = relkind === 'v' ? 'view' : relkind === 'm' ? 'materialized-view' : 'table';
371
+ const reltuples = num(row['reltuples']);
372
+ const inserts = num(row['n_ins']);
373
+ tablesByOid.set(oid, {
374
+ id: `${schema}.${name}`,
375
+ schema,
376
+ name,
377
+ kind,
378
+ comment: str(row['comment']),
379
+ columns: [],
380
+ primaryKey: [],
381
+ uniques: [],
382
+ checks: [],
383
+ indexes: [],
384
+ rowCountEstimate: collectRowEstimates && kind !== 'view' && reltuples !== null && reltuples >= 0
385
+ ? Math.round(reltuples)
386
+ : null,
387
+ rowCountExact: false,
388
+ sizeBytes: sizeByOid.get(oid) ?? null,
389
+ activity: collectActivityStats && kind === 'table' && inserts !== null
390
+ ? {
391
+ inserts,
392
+ updates: num(row['n_upd']) ?? 0,
393
+ deletes: num(row['n_del']) ?? 0,
394
+ }
395
+ : null,
396
+ rls: {
397
+ enabled: bool(row['rls_enabled']),
398
+ forced: bool(row['rls_forced']),
399
+ policyCount: num(row['policy_count']) ?? 0,
400
+ },
401
+ system: SYSTEM_TABLE_PATTERN.test(name),
402
+ semantics: null,
403
+ });
404
+ }
405
+ if (hiddenPartitions > 0) {
406
+ warnings.push({
407
+ code: 'partitions-hidden',
408
+ message: `${hiddenPartitions} partition(s) hidden — partitioned parents are listed once`,
409
+ tableId: null,
410
+ });
411
+ }
412
+ // -- columns ----------------------------------------------------------------
413
+ const referencedEnumIds = new Set();
414
+ for (const row of columnRows) {
415
+ const table = tablesByOid.get(num(row['rel_oid']) ?? -1);
416
+ if (table === undefined)
417
+ continue;
418
+ const dbType = str(row['db_type']) ?? 'unknown';
419
+ const typtype = str(row['typtype']);
420
+ const isArray = str(row['typcategory']) === 'A';
421
+ const generated = str(row['generated']) === 's';
422
+ let mapped = mapPostgresType(dbType);
423
+ let enumRef = null;
424
+ if (typtype === 'e') {
425
+ mapped = { logicalType: 'enum', maxLength: null, numericPrecision: null, numericScale: null };
426
+ enumRef = `${str(row['type_schema']) ?? ''}.${str(row['type_name']) ?? ''}`;
427
+ }
428
+ else if (typtype === 'd') {
429
+ // Domain: logical type from the base, domain name kept in dbType (05 §4.1).
430
+ mapped = mapPostgresType(str(row['base_db_type']) ?? dbType);
431
+ if (str(row['base_typtype']) === 'e') {
432
+ mapped = { ...mapped, logicalType: 'enum' };
433
+ enumRef = `${str(row['base_type_schema']) ?? ''}.${str(row['base_type_name']) ?? ''}`;
434
+ }
435
+ }
436
+ else if (isArray) {
437
+ // Array: isArray set, element logicalType (05 §4.1); dbType stays 'type[]'.
438
+ if (str(row['elem_typtype']) === 'e') {
439
+ mapped = {
440
+ logicalType: 'enum',
441
+ maxLength: null,
442
+ numericPrecision: null,
443
+ numericScale: null,
444
+ };
445
+ enumRef = `${str(row['elem_type_schema']) ?? ''}.${str(row['elem_type_name']) ?? ''}`;
446
+ }
447
+ else {
448
+ mapped = mapPostgresType(str(row['elem_db_type']) ?? dbType);
449
+ }
450
+ }
451
+ if (enumRef !== null)
452
+ referencedEnumIds.add(enumRef);
453
+ table.columns.push({
454
+ name: str(row['column_name']) ?? '',
455
+ ordinal: num(row['ordinal']) ?? 0,
456
+ dbType,
457
+ logicalType: mapped.logicalType,
458
+ nullable: !bool(row['not_null']),
459
+ default: generated
460
+ ? null
461
+ : classifyDefault(str(row['default_expr']), str(row['identity']) ?? ''),
462
+ isPrimaryKey: false,
463
+ isUnique: false,
464
+ isGenerated: generated,
465
+ enumRef,
466
+ maxLength: mapped.maxLength,
467
+ numericPrecision: mapped.numericPrecision,
468
+ numericScale: mapped.numericScale,
469
+ isArray,
470
+ comment: str(row['comment']),
471
+ references: null,
472
+ semantics: null,
473
+ });
474
+ }
475
+ // -- constraints ------------------------------------------------------------
476
+ const relations = [];
477
+ const checkEnums = new Map();
478
+ const tableIds = new Set([...tablesByOid.values()].map((t) => t.id));
479
+ for (const row of constraintRows) {
480
+ const table = tablesByOid.get(num(row['rel_oid']) ?? -1);
481
+ if (table === undefined)
482
+ continue;
483
+ const contype = str(row['contype']);
484
+ const name = str(row['name']);
485
+ const columns = strArray(row['columns']);
486
+ if (contype === 'p') {
487
+ table.primaryKey = columns;
488
+ for (const column of table.columns) {
489
+ if (columns.includes(column.name))
490
+ column.isPrimaryKey = true;
491
+ }
492
+ }
493
+ else if (contype === 'u') {
494
+ table.uniques.push({ name, columns });
495
+ }
496
+ else if (contype === 'c') {
497
+ const definition = str(row['definition']) ?? '';
498
+ table.checks.push({ name, expression: checkExpression(definition) });
499
+ const parsed = parseCheckEnum(definition);
500
+ if (parsed !== null && table.columns.some((c) => c.name === parsed.column)) {
501
+ const id = `${table.id}.${parsed.column}`;
502
+ checkEnums.set(id, {
503
+ id,
504
+ name: parsed.column,
505
+ values: parsed.values.slice(0, ENUM_VALUE_CAP),
506
+ source: 'check',
507
+ });
508
+ const column = table.columns.find((c) => c.name === parsed.column);
509
+ if (column !== undefined && column.enumRef === null)
510
+ column.enumRef = id;
511
+ }
512
+ }
513
+ else if (contype === 'f') {
514
+ const refSchema = str(row['ref_schema']) ?? '';
515
+ const refTable = str(row['ref_table']) ?? '';
516
+ const toTableId = `${refSchema}.${refTable}`;
517
+ const refColumns = strArray(row['ref_columns']);
518
+ if (!tableIds.has(toTableId)) {
519
+ warnings.push({
520
+ code: 'fk-target-excluded',
521
+ message: `foreign key "${name ?? ''}" references "${toTableId}" which is outside the introspected set`,
522
+ tableId: table.id,
523
+ });
524
+ continue;
525
+ }
526
+ relations.push({
527
+ id: `fk:${table.id}(${columns.join(',')})->${toTableId}(${refColumns.join(',')})`,
528
+ kind: 'declared-fk',
529
+ cardinality: 'one-to-many', // refined below once uniques/indexes are known
530
+ from: { tableId: table.id, columns },
531
+ to: { tableId: toTableId, columns: refColumns },
532
+ through: null,
533
+ onDelete: FK_ACTION_MAP[str(row['on_delete']) ?? ''] ?? null,
534
+ onUpdate: FK_ACTION_MAP[str(row['on_update']) ?? ''] ?? null,
535
+ selfReferential: table.id === toTableId,
536
+ confidence: 1,
537
+ });
538
+ // Convenience per-column mirror of the declared FK (05 §2.1).
539
+ columns.forEach((columnName, position) => {
540
+ const column = table.columns.find((c) => c.name === columnName);
541
+ const refColumn = refColumns[position];
542
+ if (column !== undefined && column.references === null && refColumn !== undefined) {
543
+ column.references = { tableId: toTableId, column: refColumn };
544
+ }
545
+ });
546
+ }
547
+ }
548
+ // -- indexes + isUnique -----------------------------------------------------
549
+ for (const row of indexRows) {
550
+ const table = tablesByOid.get(num(row['rel_oid']) ?? -1);
551
+ if (table === undefined)
552
+ continue;
553
+ const index = {
554
+ name: str(row['index_name']) ?? '',
555
+ columns: strArray(row['columns']),
556
+ expression: str(row['expression']),
557
+ unique: bool(row['is_unique']),
558
+ primary: bool(row['is_primary']),
559
+ method: str(row['method']),
560
+ partial: bool(row['is_partial']),
561
+ };
562
+ table.indexes.push(index);
563
+ // Covered by a single-column unique constraint/index (05 §2.1).
564
+ if (index.unique && !index.partial && index.expression === null && index.columns.length === 1) {
565
+ const column = table.columns.find((c) => c.name === index.columns[0]);
566
+ if (column !== undefined)
567
+ column.isUnique = true;
568
+ }
569
+ }
570
+ // -- one-to-one refinement: FK column set covered by a unique key -----------
571
+ for (const relation of relations) {
572
+ const table = [...tablesByOid.values()].find((t) => t.id === relation.from.tableId);
573
+ if (table === undefined)
574
+ continue;
575
+ const key = [...relation.from.columns].sort().join('\x00');
576
+ const uniqueSets = [
577
+ table.primaryKey,
578
+ ...table.uniques.map((u) => u.columns),
579
+ ...table.indexes
580
+ .filter((i) => i.unique && !i.partial && i.expression === null)
581
+ .map((i) => i.columns),
582
+ ];
583
+ if (uniqueSets.some((set) => set.length > 0 && [...set].sort().join('\x00') === key)) {
584
+ relation.cardinality = 'one-to-one';
585
+ }
586
+ }
587
+ // -- final assembly ----------------------------------------------------------
588
+ const includedSchemaSet = new Set(schemas);
589
+ const enums = [
590
+ ...[...nativeEnums.values()].filter((def) => referencedEnumIds.has(def.id) || includedSchemaSet.has(def.id.split('.')[0] ?? '')),
591
+ ...checkEnums.values(),
592
+ ].sort(compareBy((def) => def.id));
593
+ const tables = [...tablesByOid.values()].sort(compareBy((t) => t.id));
594
+ for (const table of tables) {
595
+ table.columns.sort((a, b) => a.ordinal - b.ordinal);
596
+ table.indexes.sort(compareBy((i) => i.name));
597
+ table.uniques.sort(compareBy((u) => u.name ?? ''));
598
+ table.checks.sort(compareBy((c) => c.name ?? ''));
599
+ }
600
+ relations.sort(compareBy((r) => r.id));
601
+ const columnCount = tables.reduce((total, table) => total + table.columns.length, 0);
602
+ return {
603
+ irVersion: 1,
604
+ dialect: 'postgres',
605
+ source: { kind: 'live', connectionId: ctx.connectionId },
606
+ name: ctx.databaseName,
607
+ defaultSchema: 'public',
608
+ schemas,
609
+ tables,
610
+ enums,
611
+ relations,
612
+ capabilities: { ...POSTGRES_CAPABILITIES },
613
+ introspectedAt: new Date().toISOString(),
614
+ stats: {
615
+ tableCount: tables.length,
616
+ columnCount,
617
+ relationCount: relations.length,
618
+ durationMs: Date.now() - startedAt,
619
+ },
620
+ warnings,
621
+ };
622
+ }
623
+ //# sourceMappingURL=introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.js","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type DataConnectionConfig, type QueryEngine } from '@adminium/engine/adapter';
2
+ /**
3
+ * Build the CRUD query port for a data-role connection. Accepts a DSN string
4
+ * or the role-branded config (which must carry a `dsn`). The pool is lazy —
5
+ * no connection is opened until the first query — and `destroy()` tears it
6
+ * down idempotently.
7
+ */
8
+ export declare function createQueryEngine(config: DataConnectionConfig | string): QueryEngine;
9
+ //# sourceMappingURL=query-engine.d.ts.map