@dbmason/postgres 0.1.0-alpha.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.
- package/README.md +11 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.js +183 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +793 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +34 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,793 @@
|
|
|
1
|
+
import { internalDefinePolicy as N, internalDefineProcedure as h, internalDefineFunction as g, internalDefineMaterializedView as _, internalDefineView as $, internalDefineCompositeType as T, internalDefineEnum as b, resolveRole as R, resolveTable as y, internalDefineTable as O, resolveColumn as A, internalDefineTrigger as I, internalDefineRole as w, internalDefineGrant as C, internalDefineExtension as D, internalDefineCron as k } from "@dbmason/core";
|
|
2
|
+
import { DbOperation as Le, DbmasonContext as xe, FunctionHandle as Me, ProcedureHandle as Ue, RoleReference as Fe, TableReference as qe, TypeHandle as ve } from "@dbmason/core";
|
|
3
|
+
import { Pool as S } from "pg";
|
|
4
|
+
class L {
|
|
5
|
+
static emit(e, n, a) {
|
|
6
|
+
if (e === "create")
|
|
7
|
+
return this.generateCreateTableSQL(n) + this.generateTableIndexes(n) + `
|
|
8
|
+
`;
|
|
9
|
+
if (e === "alter" && a) {
|
|
10
|
+
const t = a.old;
|
|
11
|
+
return this.generateAlterTableSQL(t, n) + this.diffIndexes(t, n) + `
|
|
12
|
+
`;
|
|
13
|
+
} else if (e === "drop")
|
|
14
|
+
return `DROP TABLE "${n.name}" CASCADE;
|
|
15
|
+
`;
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
static generateCreateTableSQL(e) {
|
|
19
|
+
const n = Object.values(e.columns).map((c) => this.formatColumn(c)).join(`,
|
|
20
|
+
`), a = e.constraints.map((c) => ` CONSTRAINT "${c.name}" ${c.definition}`).join(`,
|
|
21
|
+
`), t = e.module && e.module !== "global", o = t ? `"${e.module}"."${e.name}"` : `"${e.name}"`;
|
|
22
|
+
let i = `-- Table: ${t ? e.module + "." : ""}${e.name}
|
|
23
|
+
`;
|
|
24
|
+
return i += `CREATE TABLE ${o} (
|
|
25
|
+
${n}${a ? `,
|
|
26
|
+
` + a : ""}
|
|
27
|
+
);
|
|
28
|
+
`, e.options?.unlogged && (i = i.replace("CREATE TABLE", "CREATE UNLOGGED TABLE")), i;
|
|
29
|
+
}
|
|
30
|
+
static generateAlterTableSQL(e, n) {
|
|
31
|
+
const a = [];
|
|
32
|
+
for (const [i, c] of Object.entries(n.columns))
|
|
33
|
+
e.columns[i] || a.push(`ADD COLUMN "${i}" ${c.type}${c.notNull ? " NOT NULL" : ""}`);
|
|
34
|
+
return a.length === 0 ? "" : `ALTER TABLE ${n.module && n.module !== "global" ? `"${n.module}"."${n.name}"` : `"${n.name}"`}
|
|
35
|
+
${a.join(`,
|
|
36
|
+
`)};
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
static formatColumn(e) {
|
|
40
|
+
let n = [`"${e.name}" ${e.type}`];
|
|
41
|
+
if (e.primaryKey ? n.push("PRIMARY KEY") : e.notNull && n.push("NOT NULL"), e.unique && n.push("UNIQUE"), e.default && n.push(`DEFAULT ${e.default}`), e.references) {
|
|
42
|
+
const t = e.references.module && e.references.module !== "global" ? `"${e.references.module}"."${e.references.table}"` : `"${e.references.table}"`;
|
|
43
|
+
n.push(`REFERENCES ${t}("${e.references.column}")`), e.references.onDelete && n.push(`ON DELETE ${e.references.onDelete}`);
|
|
44
|
+
}
|
|
45
|
+
return n.join(" ");
|
|
46
|
+
}
|
|
47
|
+
static generateTableIndexes(e) {
|
|
48
|
+
return e.indexes.map((n) => this.emitIndex({ ...n, table: e.name, module: e.module })).join("");
|
|
49
|
+
}
|
|
50
|
+
static emitIndex(e) {
|
|
51
|
+
const n = e.columns.join(", "), a = e.method ? ` USING ${e.method.toUpperCase()}` : "", t = e.unique ? "UNIQUE " : "", o = e.where ? ` WHERE ${e.where}` : "", i = e.expression ? `(${e.expression})` : `(${n})`, l = e.module && e.module !== "global" ? `"${e.module}"."${e.table}"` : `"${e.table}"`;
|
|
52
|
+
return `CREATE ${t}INDEX IF NOT EXISTS "${e.name}" ON ${l}${a} ${i}${o};
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
static diffIndexes(e, n) {
|
|
56
|
+
let a = "";
|
|
57
|
+
const t = new Map(e.indexes.map((o) => [o.name, o]));
|
|
58
|
+
for (const o of n.indexes)
|
|
59
|
+
t.has(o.name) || (a += this.emitIndex({ ...o, table: n.name }));
|
|
60
|
+
return a;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
class x {
|
|
64
|
+
static emit(e) {
|
|
65
|
+
const n = Object.entries(e.args).map(([o, i]) => `"${o}" ${i}`).join(", ");
|
|
66
|
+
return `CREATE OR REPLACE PROCEDURE ${e.module && e.module !== "global" ? `"${e.module}"."${e.name}"` : `"${e.name}"`}(${n})
|
|
67
|
+
AS $$
|
|
68
|
+
${e.body}
|
|
69
|
+
$$ LANGUAGE ${e.language};
|
|
70
|
+
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
class M {
|
|
75
|
+
static emit(e) {
|
|
76
|
+
const n = Object.entries(e.args).map(([o, i]) => `"${o}" ${i}`).join(", ");
|
|
77
|
+
return `CREATE OR REPLACE FUNCTION ${e.module && e.module !== "global" ? `"${e.module}"."${e.name}"` : `"${e.name}"`}(${n})
|
|
78
|
+
RETURNS ${e.returns} AS $$
|
|
79
|
+
${e.body}
|
|
80
|
+
$$ LANGUAGE ${e.language};
|
|
81
|
+
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
class U {
|
|
86
|
+
static emit(e) {
|
|
87
|
+
const a = e.module && e.module !== "global" ? `"${e.module}"."${e.name}"` : `"${e.name}"`;
|
|
88
|
+
return `CREATE OR REPLACE ${e.kind === "MaterializedView" ? "MATERIALIZED VIEW" : "VIEW"} ${a} AS
|
|
89
|
+
${e.query};
|
|
90
|
+
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
class F {
|
|
95
|
+
static emit(e) {
|
|
96
|
+
let n = `CREATE EXTENSION IF NOT EXISTS "${e.name}"`;
|
|
97
|
+
return e.schema && (n += ` SCHEMA "${e.schema}"`), e.version && (n += ` VERSION '${e.version}'`), n + `;
|
|
98
|
+
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
class q {
|
|
103
|
+
static emit(e) {
|
|
104
|
+
return `SELECT cron.schedule('${e.name}', '${e.schedule}', $$ ${e.command} $$);
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
class v {
|
|
109
|
+
static emit(e) {
|
|
110
|
+
let n = "";
|
|
111
|
+
if (e.type === "enum") {
|
|
112
|
+
const a = (e.values || []).map((t) => `'${t}'`).join(", ");
|
|
113
|
+
n = `CREATE TYPE "${e.name}" AS ENUM (${a});`;
|
|
114
|
+
} else {
|
|
115
|
+
const a = Object.entries(e.fields || {}).map(([t, o]) => ` "${t}" ${o}`).join(`,
|
|
116
|
+
`);
|
|
117
|
+
n = `CREATE TYPE "${e.name}" AS (
|
|
118
|
+
${a}
|
|
119
|
+
);`;
|
|
120
|
+
}
|
|
121
|
+
return `DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${e.name}') THEN ${n} END IF; END $$;
|
|
122
|
+
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
class j {
|
|
127
|
+
static emit(e) {
|
|
128
|
+
let n = "";
|
|
129
|
+
if (e.options) {
|
|
130
|
+
const a = e.options;
|
|
131
|
+
a.superuser !== void 0 && (n += a.superuser ? " SUPERUSER" : " NOSUPERUSER"), a.createdb !== void 0 && (n += a.createdb ? " CREATEDB" : " NOCREATEDB"), a.createrole !== void 0 && (n += a.createrole ? " CREATEROLE" : " NOCREATEROLE"), a.inherit !== void 0 && (n += a.inherit ? " INHERIT" : " NOINHERIT"), a.login !== void 0 && (n += a.login ? " LOGIN" : " NOLOGIN"), a.password && (n += ` PASSWORD '${a.password}'`);
|
|
132
|
+
}
|
|
133
|
+
return `DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${e.name}') THEN CREATE ROLE "${e.name}"${n}; END IF; END $$;
|
|
134
|
+
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
class P {
|
|
139
|
+
static emit(e) {
|
|
140
|
+
return `GRANT ${e.privileges.join(", ")} ON ${e.on} "${e.object}" TO "${e.to}";
|
|
141
|
+
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
class H {
|
|
146
|
+
static emit(e) {
|
|
147
|
+
return `CREATE TRIGGER "${e.name}"
|
|
148
|
+
${e.when} ${e.events.join(" OR ")} ON "${e.table}"
|
|
149
|
+
FOR EACH ${e.forEach || "ROW"}
|
|
150
|
+
EXECUTE FUNCTION ${e.functionName}(${(e.functionArgs || []).join(", ")});
|
|
151
|
+
|
|
152
|
+
`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
class G {
|
|
156
|
+
static emit(e) {
|
|
157
|
+
let n = `-- Policy: ${e.name} on ${e.table}
|
|
158
|
+
`;
|
|
159
|
+
if (e.method === "rls")
|
|
160
|
+
n += `ALTER TABLE "${e.table}" ENABLE ROW LEVEL SECURITY;
|
|
161
|
+
`, n += `CREATE POLICY "${e.name}" ON "${e.table}" FOR ALL USING (${e.sql});
|
|
162
|
+
`;
|
|
163
|
+
else if (e.method === "rbac" && e.rbac)
|
|
164
|
+
for (const a of e.rbac)
|
|
165
|
+
n += `GRANT ${a.operations.join(", ")} ON TABLE "${e.table}" TO ${a.roles.map((t) => `"${t}"`).join(", ")};
|
|
166
|
+
`;
|
|
167
|
+
return n + `
|
|
168
|
+
`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
class W {
|
|
172
|
+
static emit(e) {
|
|
173
|
+
let n = `-- Generated by @dbmason/postgres
|
|
174
|
+
|
|
175
|
+
`;
|
|
176
|
+
const a = /* @__PURE__ */ new Set();
|
|
177
|
+
for (const t of e)
|
|
178
|
+
t.node.module && t.node.module !== "global" && a.add(t.node.module);
|
|
179
|
+
for (const t of a)
|
|
180
|
+
n += `CREATE SCHEMA IF NOT EXISTS "${t}";
|
|
181
|
+
`;
|
|
182
|
+
a.size > 0 && (n += `
|
|
183
|
+
`);
|
|
184
|
+
for (const t of e)
|
|
185
|
+
switch (t.node.kind) {
|
|
186
|
+
case "Table":
|
|
187
|
+
n += L.emit(t.action, t.node, t.diff);
|
|
188
|
+
break;
|
|
189
|
+
case "Procedure":
|
|
190
|
+
n += x.emit(t.node);
|
|
191
|
+
break;
|
|
192
|
+
case "Function":
|
|
193
|
+
n += M.emit(t.node);
|
|
194
|
+
break;
|
|
195
|
+
case "Extension":
|
|
196
|
+
n += F.emit(t.node);
|
|
197
|
+
break;
|
|
198
|
+
case "Type":
|
|
199
|
+
n += v.emit(t.node);
|
|
200
|
+
break;
|
|
201
|
+
case "View":
|
|
202
|
+
case "MaterializedView":
|
|
203
|
+
n += U.emit(t.node);
|
|
204
|
+
break;
|
|
205
|
+
case "Cron":
|
|
206
|
+
n += q.emit(t.node);
|
|
207
|
+
break;
|
|
208
|
+
case "Trigger":
|
|
209
|
+
n += H.emit(t.node);
|
|
210
|
+
break;
|
|
211
|
+
case "Policy":
|
|
212
|
+
n += G.emit(t.node);
|
|
213
|
+
break;
|
|
214
|
+
case "Role":
|
|
215
|
+
n += j.emit(t.node);
|
|
216
|
+
break;
|
|
217
|
+
case "Grant":
|
|
218
|
+
n += P.emit(t.node);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
return n;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
class d {
|
|
225
|
+
constructor(e) {
|
|
226
|
+
this.client = null, this.pool = new S({ connectionString: e });
|
|
227
|
+
}
|
|
228
|
+
async connect() {
|
|
229
|
+
this.client = await this.pool.connect();
|
|
230
|
+
}
|
|
231
|
+
async close() {
|
|
232
|
+
this.client && (this.client.release(), this.client = null), await this.pool.end();
|
|
233
|
+
}
|
|
234
|
+
async query(e, n) {
|
|
235
|
+
if (!this.client) throw new Error("Driver not connected");
|
|
236
|
+
return this.client.query(e, n);
|
|
237
|
+
}
|
|
238
|
+
async beginTransaction() {
|
|
239
|
+
await this.query("BEGIN");
|
|
240
|
+
}
|
|
241
|
+
async commitTransaction() {
|
|
242
|
+
await this.query("COMMIT");
|
|
243
|
+
}
|
|
244
|
+
async rollbackTransaction() {
|
|
245
|
+
await this.query("ROLLBACK");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
class V {
|
|
249
|
+
static async introspect(e) {
|
|
250
|
+
const n = {}, a = await e.query(`
|
|
251
|
+
SELECT table_schema, table_name
|
|
252
|
+
FROM information_schema.tables
|
|
253
|
+
WHERE table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
254
|
+
AND table_type = 'BASE TABLE'
|
|
255
|
+
`);
|
|
256
|
+
for (const t of a.rows) {
|
|
257
|
+
const o = t.table_schema, i = t.table_name, c = await this.introspectColumns(e, o, i), l = await this.introspectIndexes(e, o, i), r = await this.introspectConstraints(e, o, i);
|
|
258
|
+
n[i] = {
|
|
259
|
+
kind: "Table",
|
|
260
|
+
name: i,
|
|
261
|
+
module: o === "public" ? "global" : o,
|
|
262
|
+
columns: c,
|
|
263
|
+
indexes: l,
|
|
264
|
+
constraints: r,
|
|
265
|
+
policies: [],
|
|
266
|
+
triggers: []
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return n;
|
|
270
|
+
}
|
|
271
|
+
static async introspectColumns(e, n, a) {
|
|
272
|
+
const t = await e.query(`
|
|
273
|
+
SELECT column_name, data_type, udt_name, is_nullable, column_default, is_identity
|
|
274
|
+
FROM information_schema.columns
|
|
275
|
+
WHERE table_schema = '${n}' AND table_name = '${a}'
|
|
276
|
+
`), o = await e.query(`
|
|
277
|
+
SELECT kcu.column_name
|
|
278
|
+
FROM information_schema.table_constraints tc
|
|
279
|
+
JOIN information_schema.key_column_usage kcu
|
|
280
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
281
|
+
AND tc.table_schema = kcu.table_schema
|
|
282
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
283
|
+
AND tc.table_schema = '${n}' AND tc.table_name = '${a}'
|
|
284
|
+
`), i = new Set(o.rows.map((l) => l.column_name)), c = {};
|
|
285
|
+
for (const l of t.rows) {
|
|
286
|
+
let r = l.data_type === "USER-DEFINED" ? l.udt_name : l.data_type, p = l.column_default || void 0;
|
|
287
|
+
p && p.includes("nextval") && (r.toLowerCase() === "integer" || r.toLowerCase() === "int4" ? (r = "SERIAL", p = void 0) : (r.toLowerCase() === "bigint" || r.toLowerCase() === "int8") && (r = "BIGSERIAL", p = void 0)), c[l.column_name] = {
|
|
288
|
+
kind: "Column",
|
|
289
|
+
name: l.column_name,
|
|
290
|
+
type: r.toUpperCase(),
|
|
291
|
+
notNull: l.is_nullable === "NO",
|
|
292
|
+
default: p,
|
|
293
|
+
primaryKey: i.has(l.column_name),
|
|
294
|
+
// Map is_identity to options or similar if strict mapping exists,
|
|
295
|
+
// but Dbmason defines identity/sequence via options usually.
|
|
296
|
+
// For now, if we want to represent it, we might need to extend ColumnNode to support 'identity'.
|
|
297
|
+
// Checking ColumnNode definition in Table.internal.ts:
|
|
298
|
+
// options?: unknown;
|
|
299
|
+
// We can put it there.
|
|
300
|
+
options: l.is_identity === "YES" ? { identity: !0 } : void 0
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
return c;
|
|
304
|
+
}
|
|
305
|
+
static async introspectIndexes(e, n, a) {
|
|
306
|
+
const t = await e.query(`
|
|
307
|
+
SELECT
|
|
308
|
+
i.relname as index_name,
|
|
309
|
+
a.attname as column_name,
|
|
310
|
+
ix.indisunique as is_unique
|
|
311
|
+
FROM pg_class t, pg_class i, pg_index ix, pg_attribute a, pg_namespace n
|
|
312
|
+
WHERE t.oid = ix.indrelid
|
|
313
|
+
AND i.oid = ix.indexrelid
|
|
314
|
+
AND a.attrelid = t.oid
|
|
315
|
+
AND a.attnum = ANY(ix.indkey)
|
|
316
|
+
AND t.relkind = 'r'
|
|
317
|
+
AND t.relname = '${a}'
|
|
318
|
+
AND n.oid = t.relnamespace
|
|
319
|
+
AND n.nspname = '${n}'
|
|
320
|
+
ORDER BY i.relname
|
|
321
|
+
`), o = /* @__PURE__ */ new Map();
|
|
322
|
+
for (const i of t.rows)
|
|
323
|
+
o.has(i.index_name) || o.set(i.index_name, {
|
|
324
|
+
kind: "Index",
|
|
325
|
+
name: i.index_name,
|
|
326
|
+
table: a,
|
|
327
|
+
columns: [],
|
|
328
|
+
unique: i.is_unique
|
|
329
|
+
}), o.get(i.index_name).columns.push(i.column_name);
|
|
330
|
+
return Array.from(o.values()).filter((i) => !i.name.endsWith("_pkey"));
|
|
331
|
+
}
|
|
332
|
+
static async introspectConstraints(e, n, a) {
|
|
333
|
+
const t = [], o = await e.query(`
|
|
334
|
+
SELECT
|
|
335
|
+
tc.constraint_name,
|
|
336
|
+
kcu.column_name,
|
|
337
|
+
ccu.table_schema AS foreign_schema,
|
|
338
|
+
ccu.table_name AS foreign_table,
|
|
339
|
+
ccu.column_name AS foreign_column
|
|
340
|
+
FROM information_schema.table_constraints AS tc
|
|
341
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
342
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
343
|
+
AND tc.table_schema = kcu.table_schema
|
|
344
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
345
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
346
|
+
AND ccu.table_schema = tc.table_schema
|
|
347
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
348
|
+
AND tc.table_schema = '${n}' AND tc.table_name = '${a}'
|
|
349
|
+
`);
|
|
350
|
+
for (const r of o.rows) {
|
|
351
|
+
const u = r.foreign_schema && r.foreign_schema !== "global" && r.foreign_schema !== "public" ? `"${r.foreign_schema}"."${r.foreign_table}"` : `"${r.foreign_table}"`, f = `FOREIGN KEY ("${r.column_name}") REFERENCES ${u}("${r.foreign_column}")`;
|
|
352
|
+
t.push({
|
|
353
|
+
kind: "Constraint",
|
|
354
|
+
type: "foreign_key",
|
|
355
|
+
definition: f,
|
|
356
|
+
name: r.constraint_name,
|
|
357
|
+
table: a
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
const i = await e.query(`
|
|
361
|
+
SELECT
|
|
362
|
+
tc.constraint_name,
|
|
363
|
+
cc.check_clause
|
|
364
|
+
FROM information_schema.table_constraints tc
|
|
365
|
+
JOIN information_schema.check_constraints cc
|
|
366
|
+
ON tc.constraint_name = cc.constraint_name
|
|
367
|
+
WHERE tc.constraint_type = 'CHECK'
|
|
368
|
+
AND tc.table_schema = '${n}' AND tc.table_name = '${a}'
|
|
369
|
+
AND NOT (tc.constraint_name LIKE '%_not_null') -- Exclude internal NOT NULL checks
|
|
370
|
+
`);
|
|
371
|
+
for (const r of i.rows)
|
|
372
|
+
t.push({
|
|
373
|
+
kind: "Constraint",
|
|
374
|
+
type: "check",
|
|
375
|
+
name: r.constraint_name,
|
|
376
|
+
table: a,
|
|
377
|
+
definition: `CHECK (${r.check_clause})`
|
|
378
|
+
});
|
|
379
|
+
const c = await e.query(`
|
|
380
|
+
SELECT
|
|
381
|
+
tc.constraint_name,
|
|
382
|
+
kcu.column_name
|
|
383
|
+
FROM information_schema.table_constraints AS tc
|
|
384
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
385
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
386
|
+
AND tc.table_schema = kcu.table_schema
|
|
387
|
+
WHERE tc.constraint_type = 'UNIQUE'
|
|
388
|
+
AND tc.table_schema = '${n}' AND tc.table_name = '${a}'
|
|
389
|
+
`), l = /* @__PURE__ */ new Map();
|
|
390
|
+
for (const r of c.rows)
|
|
391
|
+
l.has(r.constraint_name) || l.set(r.constraint_name, []), l.get(r.constraint_name).push(r.column_name);
|
|
392
|
+
for (const [r, p] of l)
|
|
393
|
+
t.push({
|
|
394
|
+
kind: "Constraint",
|
|
395
|
+
type: "unique",
|
|
396
|
+
name: r,
|
|
397
|
+
table: a,
|
|
398
|
+
definition: `UNIQUE (${p.map((u) => `"${u}"`).join(", ")})`
|
|
399
|
+
});
|
|
400
|
+
return t;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
class B {
|
|
404
|
+
static async introspect(e) {
|
|
405
|
+
const n = await e.query(`
|
|
406
|
+
SELECT
|
|
407
|
+
n.nspname as schema,
|
|
408
|
+
c.relname as name,
|
|
409
|
+
pg_get_viewdef(c.oid, true) as definition,
|
|
410
|
+
c.relkind as kind
|
|
411
|
+
FROM pg_class c
|
|
412
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
413
|
+
WHERE c.relkind IN ('v', 'm')
|
|
414
|
+
AND n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
415
|
+
`), a = {}, t = {};
|
|
416
|
+
for (const o of n.rows) {
|
|
417
|
+
const i = o.name, c = o.schema === "public" ? "global" : o.schema, l = o.definition.trim();
|
|
418
|
+
o.kind === "v" ? a[i] = { kind: "View", name: i, module: c, query: l } : t[i] = { kind: "MaterializedView", name: i, module: c, query: l };
|
|
419
|
+
}
|
|
420
|
+
return { views: a, materializedViews: t };
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
class J {
|
|
424
|
+
static async introspect(e) {
|
|
425
|
+
const n = await e.query(`
|
|
426
|
+
SELECT
|
|
427
|
+
n.nspname as schema,
|
|
428
|
+
t.typname as name,
|
|
429
|
+
e.enumlabel as value
|
|
430
|
+
FROM pg_type t
|
|
431
|
+
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
432
|
+
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
433
|
+
WHERE n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
434
|
+
ORDER BY t.typname, e.enumsortorder
|
|
435
|
+
`), a = {};
|
|
436
|
+
for (const t of n.rows) {
|
|
437
|
+
const o = t.name, i = t.schema === "public" ? "global" : t.schema;
|
|
438
|
+
a[o] || (a[o] = {
|
|
439
|
+
kind: "Type",
|
|
440
|
+
name: o,
|
|
441
|
+
module: i,
|
|
442
|
+
type: "enum",
|
|
443
|
+
values: []
|
|
444
|
+
}), a[o].values?.push(t.value);
|
|
445
|
+
}
|
|
446
|
+
return a;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
class Y {
|
|
450
|
+
static async introspect(e) {
|
|
451
|
+
const n = await e.query(`
|
|
452
|
+
SELECT
|
|
453
|
+
n.nspname as schema,
|
|
454
|
+
p.proname as name,
|
|
455
|
+
p.prosrc as body,
|
|
456
|
+
l.lanname as language,
|
|
457
|
+
pg_get_function_arguments(p.oid) as args,
|
|
458
|
+
pg_get_function_result(p.oid) as returns
|
|
459
|
+
FROM pg_proc p
|
|
460
|
+
JOIN pg_namespace n ON n.oid = p.pronamespace
|
|
461
|
+
JOIN pg_language l ON l.oid = p.prolang
|
|
462
|
+
WHERE n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
463
|
+
AND p.prokind = 'f'
|
|
464
|
+
`), a = {};
|
|
465
|
+
for (const t of n.rows) {
|
|
466
|
+
const o = t.name, i = t.schema === "public" ? "global" : t.schema, c = {};
|
|
467
|
+
if (t.args) {
|
|
468
|
+
const r = t.args.split(",").map((p) => p.trim());
|
|
469
|
+
for (const p of r) {
|
|
470
|
+
const u = p.split(" ").map((f) => f.trim()).filter(Boolean);
|
|
471
|
+
u.length >= 2 && (["IN", "OUT", "INOUT", "VARIADIC"].includes(u[0].toUpperCase()) ? u.length >= 3 && (c[u[1]] = u.slice(2).join(" ")) : c[u[0]] = u.slice(1).join(" "));
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const l = t.body;
|
|
475
|
+
a[o] = {
|
|
476
|
+
kind: "Function",
|
|
477
|
+
name: o,
|
|
478
|
+
module: i,
|
|
479
|
+
args: c,
|
|
480
|
+
returns: t.returns,
|
|
481
|
+
language: t.language,
|
|
482
|
+
body: l
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
return a;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
class K {
|
|
489
|
+
static async introspect(e) {
|
|
490
|
+
const n = await e.query(`
|
|
491
|
+
SELECT
|
|
492
|
+
n.nspname as schema,
|
|
493
|
+
p.proname as name,
|
|
494
|
+
p.prosrc as body,
|
|
495
|
+
l.lanname as language,
|
|
496
|
+
pg_get_function_arguments(p.oid) as args,
|
|
497
|
+
pg_get_function_result(p.oid) as returns
|
|
498
|
+
FROM pg_proc p
|
|
499
|
+
JOIN pg_namespace n ON n.oid = p.pronamespace
|
|
500
|
+
JOIN pg_language l ON l.oid = p.prolang
|
|
501
|
+
WHERE n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
502
|
+
AND p.prokind = 'p'
|
|
503
|
+
`), a = {};
|
|
504
|
+
for (const t of n.rows) {
|
|
505
|
+
const o = t.name, i = t.schema === "public" ? "global" : t.schema, c = {};
|
|
506
|
+
if (t.args) {
|
|
507
|
+
const r = t.args.split(",").map((p) => p.trim());
|
|
508
|
+
for (const p of r) {
|
|
509
|
+
const u = p.split(" ").map((f) => f.trim()).filter(Boolean);
|
|
510
|
+
u.length >= 2 && (["IN", "OUT", "INOUT", "VARIADIC"].includes(u[0].toUpperCase()) ? u.length >= 3 && (c[u[1]] = u.slice(2).join(" ")) : c[u[0]] = u.slice(1).join(" "));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
const l = t.body;
|
|
514
|
+
a[o] = {
|
|
515
|
+
kind: "Procedure",
|
|
516
|
+
name: o,
|
|
517
|
+
module: i,
|
|
518
|
+
args: c,
|
|
519
|
+
returns: t.returns,
|
|
520
|
+
language: t.language,
|
|
521
|
+
body: l
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
return a;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
class z {
|
|
528
|
+
static async introspect(e) {
|
|
529
|
+
const n = await e.query(`
|
|
530
|
+
SELECT
|
|
531
|
+
n.nspname as schema,
|
|
532
|
+
t.tgname as name,
|
|
533
|
+
c.relname as table_name,
|
|
534
|
+
p.proname as function_name,
|
|
535
|
+
t.tgtype as type,
|
|
536
|
+
pg_get_triggerdef(t.oid) as definition
|
|
537
|
+
FROM pg_trigger t
|
|
538
|
+
JOIN pg_class c ON c.oid = t.tgrelid
|
|
539
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
540
|
+
JOIN pg_proc p ON p.oid = t.tgfoid
|
|
541
|
+
WHERE n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
542
|
+
AND NOT t.tgisinternal
|
|
543
|
+
`), a = {};
|
|
544
|
+
for (const t of n.rows) {
|
|
545
|
+
const o = t.name, i = t.schema === "public" ? "global" : t.schema, c = t.definition.toUpperCase();
|
|
546
|
+
let l = "BEFORE";
|
|
547
|
+
c.includes("AFTER") ? l = "AFTER" : c.includes("INSTEAD OF") && (l = "INSTEAD OF");
|
|
548
|
+
const r = [];
|
|
549
|
+
c.includes("INSERT") && r.push("INSERT"), c.includes("UPDATE") && r.push("UPDATE"), c.includes("DELETE") && r.push("DELETE"), c.includes("TRUNCATE") && r.push("TRUNCATE");
|
|
550
|
+
const p = c.includes("FOR EACH ROW") ? "ROW" : "STATEMENT";
|
|
551
|
+
a[o] = {
|
|
552
|
+
kind: "Trigger",
|
|
553
|
+
name: o,
|
|
554
|
+
table: t.table_name,
|
|
555
|
+
module: i,
|
|
556
|
+
functionName: t.function_name,
|
|
557
|
+
when: l,
|
|
558
|
+
events: r,
|
|
559
|
+
forEach: p
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
return a;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
class X {
|
|
566
|
+
async introspect(e) {
|
|
567
|
+
const n = new d(e);
|
|
568
|
+
await n.connect();
|
|
569
|
+
try {
|
|
570
|
+
const a = await V.introspect(n), { views: t, materializedViews: o } = await B.introspect(n), i = await J.introspect(n), c = await Y.introspect(n), l = await K.introspect(n), r = await z.introspect(n);
|
|
571
|
+
return {
|
|
572
|
+
tables: a,
|
|
573
|
+
procedures: l,
|
|
574
|
+
functions: c,
|
|
575
|
+
views: t,
|
|
576
|
+
materializedViews: o,
|
|
577
|
+
types: i,
|
|
578
|
+
crons: {},
|
|
579
|
+
extensions: {},
|
|
580
|
+
roles: {},
|
|
581
|
+
grants: {},
|
|
582
|
+
policies: {},
|
|
583
|
+
triggers: r,
|
|
584
|
+
hashes: {}
|
|
585
|
+
};
|
|
586
|
+
} finally {
|
|
587
|
+
await n.close();
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
class te {
|
|
592
|
+
constructor() {
|
|
593
|
+
this.name = "postgres", this.introspector = new X();
|
|
594
|
+
}
|
|
595
|
+
setContext(e) {
|
|
596
|
+
this.ctx = e;
|
|
597
|
+
}
|
|
598
|
+
analyzeTable(e) {
|
|
599
|
+
const n = [];
|
|
600
|
+
for (const i of Object.values(e.columns))
|
|
601
|
+
i.references && n.push(`table:${i.references.table}`), this.ctx && this.ctx.types.has(i.type) && n.push(`type:${i.type}`);
|
|
602
|
+
const a = this.ctx ? Array.from(this.ctx.policies.values()).filter((i) => i.table === e.name || i.module === e.module && i.table === e.name) : [], t = a.length > 0, o = e.indexes.map((i) => ({
|
|
603
|
+
...i,
|
|
604
|
+
name: i.name || `idx_${e.name}_${i.columns.join("_")}`
|
|
605
|
+
}));
|
|
606
|
+
return {
|
|
607
|
+
...e,
|
|
608
|
+
indexes: o,
|
|
609
|
+
dependencies: n,
|
|
610
|
+
rls: {
|
|
611
|
+
enabled: t,
|
|
612
|
+
policies: a
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
emit(e) {
|
|
617
|
+
return W.emit(e);
|
|
618
|
+
}
|
|
619
|
+
getDriver(e) {
|
|
620
|
+
return new d(e);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
function ae(s, e, n) {
|
|
624
|
+
return N(s, e, n);
|
|
625
|
+
}
|
|
626
|
+
function se(s, e, n) {
|
|
627
|
+
return h(s, e, n);
|
|
628
|
+
}
|
|
629
|
+
function ie(s, e, n) {
|
|
630
|
+
return g(s, e, n);
|
|
631
|
+
}
|
|
632
|
+
function oe(s, e, n) {
|
|
633
|
+
$(s, e, n);
|
|
634
|
+
}
|
|
635
|
+
function ce(s, e, n) {
|
|
636
|
+
_(s, e, n);
|
|
637
|
+
}
|
|
638
|
+
function re(s, e, n) {
|
|
639
|
+
return b(s, e, n);
|
|
640
|
+
}
|
|
641
|
+
function le(s, e, n) {
|
|
642
|
+
return T(s, e, n);
|
|
643
|
+
}
|
|
644
|
+
function E(s) {
|
|
645
|
+
return s.map((e) => A(e).column);
|
|
646
|
+
}
|
|
647
|
+
const me = (...s) => ({
|
|
648
|
+
kind: "Index",
|
|
649
|
+
name: "",
|
|
650
|
+
table: "",
|
|
651
|
+
columns: E(s),
|
|
652
|
+
method: "btree"
|
|
653
|
+
}), ue = (...s) => ({
|
|
654
|
+
kind: "Index",
|
|
655
|
+
name: "",
|
|
656
|
+
table: "",
|
|
657
|
+
columns: E(s),
|
|
658
|
+
method: "gin"
|
|
659
|
+
}), pe = (...s) => ({
|
|
660
|
+
kind: "Index",
|
|
661
|
+
name: "",
|
|
662
|
+
table: "",
|
|
663
|
+
columns: E(s),
|
|
664
|
+
method: "gist"
|
|
665
|
+
}), fe = (...s) => ({
|
|
666
|
+
kind: "Index",
|
|
667
|
+
name: "",
|
|
668
|
+
table: "",
|
|
669
|
+
columns: E(s),
|
|
670
|
+
method: "hash"
|
|
671
|
+
});
|
|
672
|
+
class m {
|
|
673
|
+
constructor(e) {
|
|
674
|
+
this.node = e;
|
|
675
|
+
}
|
|
676
|
+
primaryKey() {
|
|
677
|
+
return new m({ ...this.node, primaryKey: !0, notNull: !0 });
|
|
678
|
+
}
|
|
679
|
+
notNull() {
|
|
680
|
+
return new m({ ...this.node, notNull: !0 });
|
|
681
|
+
}
|
|
682
|
+
unique() {
|
|
683
|
+
return new m({ ...this.node, unique: !0 });
|
|
684
|
+
}
|
|
685
|
+
default(e) {
|
|
686
|
+
return new m({ ...this.node, default: e });
|
|
687
|
+
}
|
|
688
|
+
defaultNow() {
|
|
689
|
+
return new m({ ...this.node, default: "NOW()" });
|
|
690
|
+
}
|
|
691
|
+
defaultUuid() {
|
|
692
|
+
return new m({ ...this.node, default: "gen_random_uuid()" });
|
|
693
|
+
}
|
|
694
|
+
check(e) {
|
|
695
|
+
return new m({ ...this.node, check: e });
|
|
696
|
+
}
|
|
697
|
+
references(e, n, a) {
|
|
698
|
+
let t, o, i;
|
|
699
|
+
return typeof e != "string" ? (t = e.tableName, o = e.columnName, i = n) : (t = e, o = n, i = a), new m({
|
|
700
|
+
...this.node,
|
|
701
|
+
references: {
|
|
702
|
+
module: e.moduleName,
|
|
703
|
+
table: t,
|
|
704
|
+
column: o,
|
|
705
|
+
onDelete: i?.onDelete,
|
|
706
|
+
onUpdate: i?.onUpdate
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
build() {
|
|
711
|
+
return this.node;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const Ee = (s = "") => new m({ kind: "Column", name: s, type: "TEXT" }), de = (s = "") => new m({ kind: "Column", name: s, type: "UUID" }), Q = (s = "") => new m({ kind: "Column", name: s, type: "TIMESTAMPTZ" }), Ne = Q, he = (s = "") => new m({ kind: "Column", name: s, type: "JSONB" }), ge = (s = "") => new m({ kind: "Column", name: s, type: "INTEGER" }), _e = (s = "") => new m({ kind: "Column", name: s, type: "BOOLEAN" }), $e = (s = "") => new m({ kind: "Column", name: s, type: "DOUBLE PRECISION" }), Te = (s = "") => new m({ kind: "Column", name: s, type: "DECIMAL" }), be = (s = "") => new m({ kind: "Column", name: s, type: "SERIAL" }), Re = (s = "") => new m({ kind: "Column", name: s, type: "BIGSERIAL" }), Z = (s, e = "") => {
|
|
715
|
+
const n = typeof s == "string" ? s : s.moduleName && s.moduleName !== "global" ? `"${s.moduleName}"."${s.typeName}"` : s.typeName;
|
|
716
|
+
return new m({ kind: "Column", name: e, type: n });
|
|
717
|
+
}, ye = Z;
|
|
718
|
+
function Oe(s, e, n) {
|
|
719
|
+
const a = {
|
|
720
|
+
...n,
|
|
721
|
+
options: n.options ? {
|
|
722
|
+
...n.options,
|
|
723
|
+
inherits: n.options.inherits ? y(n.options.inherits) : void 0,
|
|
724
|
+
realtime: Array.isArray(n.options.realtime) ? n.options.realtime.map((t) => R(t)) : n.options.realtime
|
|
725
|
+
} : void 0
|
|
726
|
+
};
|
|
727
|
+
return O(s, e, a, (t) => {
|
|
728
|
+
const o = {};
|
|
729
|
+
for (const [i, c] of Object.entries(t))
|
|
730
|
+
if (c instanceof m) {
|
|
731
|
+
const l = c.build();
|
|
732
|
+
l.name = i, o[i] = l;
|
|
733
|
+
} else typeof c == "string" ? o[i] = { kind: "Column", name: i, type: c } : o[i] = { ...c, name: i };
|
|
734
|
+
return o;
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
function Ae(s, e, n, a) {
|
|
738
|
+
I(s, e, n, a);
|
|
739
|
+
}
|
|
740
|
+
function Ie(s, e, n) {
|
|
741
|
+
return w(s, e, n);
|
|
742
|
+
}
|
|
743
|
+
function we(s, e, n, a, t) {
|
|
744
|
+
return C(s, e, n, a, t);
|
|
745
|
+
}
|
|
746
|
+
function Ce(s, e, n) {
|
|
747
|
+
return D(s, e, n);
|
|
748
|
+
}
|
|
749
|
+
function De(s, e, n, a) {
|
|
750
|
+
return k(s, e, n, a);
|
|
751
|
+
}
|
|
752
|
+
export {
|
|
753
|
+
Le as DbOperation,
|
|
754
|
+
xe as DbmasonContext,
|
|
755
|
+
Me as FunctionHandle,
|
|
756
|
+
m as PostgresColumnBuilder,
|
|
757
|
+
te as PostgresDialect,
|
|
758
|
+
Ue as ProcedureHandle,
|
|
759
|
+
Fe as RoleReference,
|
|
760
|
+
qe as TableReference,
|
|
761
|
+
ve as TypeHandle,
|
|
762
|
+
Re as bigserial,
|
|
763
|
+
_e as boolean,
|
|
764
|
+
me as btree,
|
|
765
|
+
Z as custom,
|
|
766
|
+
Te as decimal,
|
|
767
|
+
le as defineCompositeType,
|
|
768
|
+
De as defineCron,
|
|
769
|
+
re as defineEnum,
|
|
770
|
+
Ce as defineExtension,
|
|
771
|
+
ie as defineFunction,
|
|
772
|
+
we as defineGrant,
|
|
773
|
+
ce as defineMaterializedView,
|
|
774
|
+
ae as definePolicy,
|
|
775
|
+
se as defineProcedure,
|
|
776
|
+
Ie as defineRole,
|
|
777
|
+
Oe as defineTable,
|
|
778
|
+
Ae as defineTrigger,
|
|
779
|
+
oe as defineView,
|
|
780
|
+
$e as doublePrecision,
|
|
781
|
+
ye as enumType,
|
|
782
|
+
ue as gin,
|
|
783
|
+
pe as gist,
|
|
784
|
+
fe as hash,
|
|
785
|
+
ge as integer,
|
|
786
|
+
he as jsonb,
|
|
787
|
+
be as serial,
|
|
788
|
+
Ee as text,
|
|
789
|
+
Ne as timestamp,
|
|
790
|
+
Q as timestamptz,
|
|
791
|
+
de as uuid
|
|
792
|
+
};
|
|
793
|
+
//# sourceMappingURL=index.mjs.map
|