okmodel 0.2.1 → 0.3.0
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 +710 -36
- package/dist/contracts/catalog/enum.d.ts +31 -4
- package/dist/contracts/catalog/extension.d.ts +61 -0
- package/dist/contracts/catalog/privilege.d.ts +64 -0
- package/dist/contracts/catalog/routine.d.ts +56 -0
- package/dist/contracts/catalog/types.d.ts +164 -10
- package/dist/contracts/catalog/view.d.ts +73 -0
- package/dist/dialects/pg/column.d.ts +3 -1
- package/dist/dialects/pg/ddl.d.ts +65 -1
- package/dist/dialects/pg/enum.d.ts +10 -8
- package/dist/dialects/pg/ext/citext.d.ts +14 -0
- package/dist/dialects/pg/ext/citext.js +11 -0
- package/dist/dialects/pg/ext/index.d.ts +52 -0
- package/dist/dialects/pg/ext/index.js +6 -0
- package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
- package/dist/dialects/pg/ext/pg-trgm.js +42 -0
- package/dist/dialects/pg/fn/index.d.ts +107 -0
- package/dist/dialects/pg/fn/index.js +175 -0
- package/dist/dialects/pg/fn/touch.d.ts +14 -0
- package/dist/dialects/pg/index.js +104 -19
- package/dist/dialects/pg/introspect.d.ts +10 -1
- package/dist/dialects/pg/operators.d.ts +8 -1
- package/dist/dialects/pg/role/check.d.ts +45 -0
- package/dist/dialects/pg/role/index.d.ts +50 -0
- package/dist/dialects/pg/role/sql.d.ts +44 -0
- package/dist/dialects/pg/table.d.ts +7 -0
- package/dist/dialects/pg/tenancy.d.ts +9 -0
- package/dist/dialects/pg/view/client.d.ts +30 -0
- package/dist/dialects/pg/view/depend.d.ts +35 -0
- package/dist/dialects/pg/view/index.d.ts +114 -0
- package/dist/dialects/pg/view/index.js +289 -0
- package/dist/dialects/pg/view/scratch.d.ts +21 -0
- package/dist/dialects/pg/where.d.ts +2 -2
- package/dist/runtime/pg/bun.js +3 -3
- package/dist/runtime/pg/pg.js +3 -3
- package/dist/runtime/pg/pglite.js +3 -3
- package/dist/runtime/pg/postgresjs.js +3 -3
- package/dist/runtime/tenancy/index.js +6 -3
- package/dist/runtime/traits/index.d.ts +7 -2
- package/dist/runtime/traits/index.js +149 -12
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{ytg3xf9p.js → 01yr20s5.js} +3 -3
- package/dist/shared/{cstgkzdx.js → 0jc3ffzf.js} +1 -1
- package/dist/shared/{xkz8g6by.js → 1g0drakv.js} +2 -2
- package/dist/shared/{eaxwrgby.js → 1tfdfvhh.js} +4 -3
- package/dist/shared/2ssqrv66.js +1576 -0
- package/dist/shared/{10tjenmd.js → 3ekj9x92.js} +1 -1
- package/dist/shared/49ypnfwt.js +1122 -0
- package/dist/shared/{sacqha1y.js → 4m9fn52z.js} +2 -2
- package/dist/shared/5nmdenb6.js +1229 -0
- package/dist/shared/{qa5dsc7z.js → 6bazvqwm.js} +3 -3
- package/dist/shared/{x9v1qgeb.js → 6w5j844a.js} +1 -1
- package/dist/shared/{0qkxbm1f.js → 75xkjv0t.js} +1 -1
- package/dist/shared/7fvtrkwr.js +84 -0
- package/dist/shared/94ez8kzh.js +19 -0
- package/dist/shared/{1dp5knt7.js → 999ade2q.js} +2 -2
- package/dist/shared/{3a5ne750.js → 9m80mkac.js} +2 -2
- package/dist/shared/9x25fxhc.js +150 -0
- package/dist/shared/{4b9da9d7.js → axhk06q1.js} +19 -1
- package/dist/shared/{38crxbgn.js → bqha5cg6.js} +3 -3
- package/dist/shared/{zd93g3rq.js → bryqk9k9.js} +1 -1
- package/dist/shared/{n47rd821.js → c8aghh05.js} +1 -1
- package/dist/shared/{dd4f8mnx.js → c9z5g0fm.js} +4 -2
- package/dist/shared/{eqmtn1bj.js → dbjej1tw.js} +71 -14
- package/dist/shared/{ps43134h.js → dyj86cmj.js} +4 -4
- package/dist/shared/{sfh4pk75.js → fptpmvxp.js} +3 -3
- package/dist/shared/{97g2jnrw.js → fs0ex00p.js} +3 -3
- package/dist/shared/{rtnaqre0.js → g4f5kcx9.js} +2 -2
- package/dist/shared/{yw5c610b.js → gjthds9j.js} +2 -2
- package/dist/shared/hcmdtwgh.js +102 -0
- package/dist/shared/{qxa0yb9j.js → jkc6ws1p.js} +2 -54
- package/dist/shared/{mxmcdsh5.js → k34e0xf2.js} +9 -9
- package/dist/shared/{py3nh7jy.js → kgnc8grt.js} +2 -2
- package/dist/shared/{g9f0zqce.js → m78s7898.js} +1 -1
- package/dist/shared/meck53jv.js +99 -0
- package/dist/shared/{v18jva5b.js → mt5wswjz.js} +1 -1
- package/dist/shared/{g1b5zzj9.js → n0dgs0pb.js} +1 -1
- package/dist/shared/{zt8y0wzb.js → n7mcc1gk.js} +1 -1
- package/dist/shared/ne02ng5c.js +68 -0
- package/dist/shared/{e7a268fy.js → p24x2334.js} +1 -1
- package/dist/shared/qbxzvwwc.js +88 -0
- package/dist/shared/{a1gdp7j9.js → qybh48nd.js} +1 -1
- package/dist/shared/{d04j53v8.js → scwxrpx2.js} +5 -4
- package/dist/shared/{d2whjz4k.js → t616ynfn.js} +530 -24
- package/dist/shared/th14ygv2.js +69 -0
- package/dist/shared/{xatfg0gn.js → tmbdywx0.js} +4 -19
- package/dist/shared/{ge03bfca.js → ty3v3hfk.js} +2 -2
- package/dist/shared/wekze34d.js +246 -0
- package/dist/shared/{7mht49yd.js → x6wysh83.js} +59 -18
- package/dist/shared/{4jzzghr6.js → xva8v7qk.js} +8 -8
- package/dist/shared/{ecdzej21.js → xw1d69vd.js} +7 -7
- package/dist/shared/y005b761.js +112 -0
- package/dist/shared/{mrq77sgw.js → ydaz1sv3.js} +1 -1
- package/dist/tooling/cli.js +32 -8
- package/dist/tooling/migrate/apply.d.ts +16 -0
- package/dist/tooling/migrate/commands.d.ts +2 -1
- package/dist/tooling/migrate/config.d.ts +8 -0
- package/dist/tooling/migrate/doctor.d.ts +25 -0
- package/dist/tooling/migrate/drift.d.ts +19 -0
- package/dist/tooling/migrate/ext.d.ts +17 -0
- package/dist/tooling/migrate/extensions.d.ts +51 -0
- package/dist/tooling/migrate/managed.d.ts +17 -0
- package/dist/tooling/migrate/plan.d.ts +14 -1
- package/dist/tooling/migrate/project.d.ts +25 -1
- package/dist/tooling/migrate/type-name.d.ts +19 -0
- package/package.json +22 -2
- package/dist/shared/5z4q2zda.js +0 -2073
- /package/dist/shared/{9k6vetvf.js → rrstp3kb.js} +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
send,
|
|
3
3
|
connectClient
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./bqha5cg6.js";
|
|
5
5
|
import {
|
|
6
6
|
isConnectionLost
|
|
7
7
|
} from "./tbszx8mz.js";
|
|
8
8
|
import {
|
|
9
9
|
WireSession
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./0jc3ffzf.js";
|
|
11
11
|
import {
|
|
12
12
|
rejectClosed,
|
|
13
13
|
runCall
|
|
14
|
-
} from "./
|
|
14
|
+
} from "./rrstp3kb.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/pg/nodepostgres-extra.ts
|
|
17
17
|
var RESET_ALL = "RESET ALL";
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extensionObject
|
|
3
|
+
} from "./th14ygv2.js";
|
|
4
|
+
import {
|
|
5
|
+
OkmError2
|
|
6
|
+
} from "./52szzakm.js";
|
|
7
|
+
|
|
8
|
+
// src/dialects/pg/ext/index.ts
|
|
9
|
+
function extension2(name, options = {}) {
|
|
10
|
+
const schema = options.schema ?? "public";
|
|
11
|
+
const relocatable = options.relocatable ?? true;
|
|
12
|
+
const version = options.version;
|
|
13
|
+
const record = extensionObject({
|
|
14
|
+
name,
|
|
15
|
+
schema,
|
|
16
|
+
relocatable,
|
|
17
|
+
...version !== undefined ? { version } : {},
|
|
18
|
+
provenance: { origin: "extension", name }
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
schema,
|
|
23
|
+
relocatable,
|
|
24
|
+
...version !== undefined ? { version } : {},
|
|
25
|
+
contribute(peers, built) {
|
|
26
|
+
const names = peerNames(peers);
|
|
27
|
+
assertDeclared(names, built);
|
|
28
|
+
return [record];
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function peerNames(peers) {
|
|
33
|
+
if (!Array.isArray(peers)) {
|
|
34
|
+
extensionError("OKM1810", "schema({ extensions }) must be a list of extensions.");
|
|
35
|
+
}
|
|
36
|
+
const counts = new Map;
|
|
37
|
+
for (const peer of peers) {
|
|
38
|
+
if (!isPeer(peer)) {
|
|
39
|
+
extensionError("OKM1810", "schema({ extensions }) must be a list of extensions.");
|
|
40
|
+
}
|
|
41
|
+
counts.set(peer.name, (counts.get(peer.name) ?? 0) + 1);
|
|
42
|
+
}
|
|
43
|
+
for (const [name, count] of counts) {
|
|
44
|
+
if (count > 1)
|
|
45
|
+
extensionError("OKM1813", `Extension ${name} is defined twice.`);
|
|
46
|
+
}
|
|
47
|
+
return counts;
|
|
48
|
+
}
|
|
49
|
+
function assertDeclared(names, built) {
|
|
50
|
+
if (!Array.isArray(built))
|
|
51
|
+
return;
|
|
52
|
+
for (const object of built) {
|
|
53
|
+
if (typeof object !== "object" || object === null || !("dependencies" in object))
|
|
54
|
+
continue;
|
|
55
|
+
const dependencies = object.dependencies;
|
|
56
|
+
if (!Array.isArray(dependencies))
|
|
57
|
+
continue;
|
|
58
|
+
for (const edge of dependencies) {
|
|
59
|
+
if (typeof edge !== "object" || edge === null || !("target" in edge))
|
|
60
|
+
continue;
|
|
61
|
+
const target = edge.target;
|
|
62
|
+
if (typeof target !== "object" || target === null)
|
|
63
|
+
continue;
|
|
64
|
+
if (!("kind" in target) || !("name" in target))
|
|
65
|
+
continue;
|
|
66
|
+
if (target.kind === "extension" && typeof target.name === "string" && !names.has(target.name)) {
|
|
67
|
+
extensionError("OKM1810", `Extension ${target.name} is used but not declared.`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function isPeer(value) {
|
|
73
|
+
if (typeof value !== "object" || value === null)
|
|
74
|
+
return false;
|
|
75
|
+
if (!("name" in value) || !("contribute" in value))
|
|
76
|
+
return false;
|
|
77
|
+
return typeof value.name === "string" && value.name.length > 0 && typeof value.contribute === "function";
|
|
78
|
+
}
|
|
79
|
+
function extensionError(code, message) {
|
|
80
|
+
const summary = code === "OKM1813" ? "Keep one definition. A second copy fails at build." : "Declare the extension next to the schema that uses it.";
|
|
81
|
+
throw new OkmError2(code, message, { fix: { summary } });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { extension2 };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/dialects/pg/quote.ts
|
|
2
|
+
function quoteLiteral(value) {
|
|
3
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
4
|
+
}
|
|
5
|
+
function arrayElement(encoded, raw) {
|
|
6
|
+
if (raw && (encoded === "true" || encoded === "false" || isBareNumber(encoded))) {
|
|
7
|
+
return encoded;
|
|
8
|
+
}
|
|
9
|
+
return `"${encoded.replaceAll("\\", "\\\\").replaceAll('"', "\\\"")}"`;
|
|
10
|
+
}
|
|
11
|
+
function isBareNumber(encoded) {
|
|
12
|
+
let pattern = bareNumber;
|
|
13
|
+
pattern ??= /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
14
|
+
bareNumber = pattern;
|
|
15
|
+
return pattern.test(encoded);
|
|
16
|
+
}
|
|
17
|
+
var bareNumber;
|
|
18
|
+
|
|
19
|
+
export { quoteLiteral, arrayElement };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PgSession
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./xw1d69vd.js";
|
|
4
4
|
import {
|
|
5
5
|
isConnectionLost
|
|
6
6
|
} from "./tbszx8mz.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
runCall,
|
|
12
12
|
rowsFrom,
|
|
13
13
|
resultFrom
|
|
14
|
-
} from "./
|
|
14
|
+
} from "./rrstp3kb.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/pg/postgres-extra.ts
|
|
17
17
|
var RESET_ALL = "RESET ALL";
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
staticNamespace2,
|
|
3
|
+
assertNamespace2,
|
|
4
|
+
normaliseEdges,
|
|
5
|
+
assertProvenance
|
|
6
|
+
} from "./t4tbsy9h.js";
|
|
7
|
+
import {
|
|
8
|
+
assertIdentifier2
|
|
9
|
+
} from "./nfzc5z0w.js";
|
|
10
|
+
import {
|
|
11
|
+
catalogError2
|
|
12
|
+
} from "./52szzakm.js";
|
|
13
|
+
|
|
14
|
+
// src/contracts/catalog/routine.ts
|
|
15
|
+
var VOLATILITY = new Set(["volatile", "stable", "immutable"]);
|
|
16
|
+
var SECURITY = new Set(["invoker", "definer"]);
|
|
17
|
+
var TIMING = new Set(["before", "after", "instead"]);
|
|
18
|
+
var LEVEL = new Set(["row", "statement"]);
|
|
19
|
+
var EVENT_ORDER = ["insert", "update", "delete", "truncate"];
|
|
20
|
+
var TYPE_TEXT = /^[A-Za-z][A-Za-z0-9_ ]*(\(\d+(,\s*\d+)?\))?(\[\])*$/;
|
|
21
|
+
function functionObject(input) {
|
|
22
|
+
assertIdentifier2(input.name, "function");
|
|
23
|
+
const namespace = input.namespace ?? staticNamespace2("public");
|
|
24
|
+
assertNamespace2(namespace);
|
|
25
|
+
assertProvenance(input.provenance);
|
|
26
|
+
if (input.language !== "sql" && input.language !== "plpgsql") {
|
|
27
|
+
catalogError2("OKM1020", `Function ${input.name} language must be sql or plpgsql.`);
|
|
28
|
+
}
|
|
29
|
+
const volatility = input.volatility ?? "volatile";
|
|
30
|
+
if (!VOLATILITY.has(volatility)) {
|
|
31
|
+
catalogError2("OKM1020", `Function ${input.name} volatility ${volatility} is not supported.`);
|
|
32
|
+
}
|
|
33
|
+
const security = input.security ?? "invoker";
|
|
34
|
+
if (!SECURITY.has(security)) {
|
|
35
|
+
catalogError2("OKM1020", `Function ${input.name} security ${security} is not supported.`);
|
|
36
|
+
}
|
|
37
|
+
assertTypeName(input.returns, `function ${input.name} return type`);
|
|
38
|
+
const args = (input.arguments ?? []).map((argument) => readArgument(input.name, argument));
|
|
39
|
+
if (input.body.length === 0) {
|
|
40
|
+
catalogError2("OKM1020", `Function ${input.name} needs a body.`);
|
|
41
|
+
}
|
|
42
|
+
const atomic = input.atomic === true;
|
|
43
|
+
if (atomic && input.language !== "sql") {
|
|
44
|
+
catalogError2("OKM1020", `Function ${input.name} BEGIN ATOMIC needs language sql.`);
|
|
45
|
+
}
|
|
46
|
+
if (input.searchPath !== undefined && input.searchPath.trim().length === 0) {
|
|
47
|
+
catalogError2("OKM1020", `Function ${input.name} search_path is empty.`);
|
|
48
|
+
}
|
|
49
|
+
const definition = {
|
|
50
|
+
arguments: args,
|
|
51
|
+
returns: input.returns,
|
|
52
|
+
language: input.language,
|
|
53
|
+
volatility,
|
|
54
|
+
security,
|
|
55
|
+
body: input.body,
|
|
56
|
+
...input.searchPath !== undefined ? { searchPath: input.searchPath } : {},
|
|
57
|
+
...atomic ? { atomic: true } : {}
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
kind: "function",
|
|
61
|
+
identity: {
|
|
62
|
+
kind: "function",
|
|
63
|
+
namespace,
|
|
64
|
+
name: input.name,
|
|
65
|
+
argTypes: args.map((arg) => arg.type)
|
|
66
|
+
},
|
|
67
|
+
owner: input.owner ?? "managed",
|
|
68
|
+
definition,
|
|
69
|
+
dependencies: normaliseEdges(input.dependencies ?? []),
|
|
70
|
+
provenance: input.provenance
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function triggerObject(input) {
|
|
74
|
+
assertIdentifier2(input.name, "trigger");
|
|
75
|
+
assertNamespace2(input.parent.namespace);
|
|
76
|
+
assertIdentifier2(input.parent.name, "trigger table");
|
|
77
|
+
assertProvenance(input.provenance);
|
|
78
|
+
if (!TIMING.has(input.timing)) {
|
|
79
|
+
catalogError2("OKM1020", `Trigger ${input.name} timing ${input.timing} is not supported.`);
|
|
80
|
+
}
|
|
81
|
+
if (!LEVEL.has(input.level)) {
|
|
82
|
+
catalogError2("OKM1020", `Trigger ${input.name} level ${input.level} is not supported.`);
|
|
83
|
+
}
|
|
84
|
+
const events = EVENT_ORDER.filter((event) => input.events.includes(event));
|
|
85
|
+
if (events.length === 0) {
|
|
86
|
+
catalogError2("OKM1020", `Trigger ${input.name} needs an event.`);
|
|
87
|
+
}
|
|
88
|
+
const updateOf = input.updateOf === undefined ? undefined : [...input.updateOf];
|
|
89
|
+
if (updateOf !== undefined) {
|
|
90
|
+
if (!events.includes("update")) {
|
|
91
|
+
catalogError2("OKM1020", `Trigger ${input.name} lists UPDATE OF columns without an update event.`);
|
|
92
|
+
}
|
|
93
|
+
if (input.level !== "row") {
|
|
94
|
+
catalogError2("OKM1020", `Trigger ${input.name} UPDATE OF columns need level row.`);
|
|
95
|
+
}
|
|
96
|
+
for (const column of updateOf)
|
|
97
|
+
assertIdentifier2(column, "trigger column");
|
|
98
|
+
}
|
|
99
|
+
assertIdentifier2(input.calls.name, "trigger function");
|
|
100
|
+
assertNamespace2(input.calls.namespace);
|
|
101
|
+
for (const typeName of input.calls.argTypes)
|
|
102
|
+
assertTypeName(typeName, `trigger ${input.name}`);
|
|
103
|
+
const edges = [
|
|
104
|
+
{ kind: "table", namespace: input.parent.namespace, name: input.parent.name },
|
|
105
|
+
{
|
|
106
|
+
kind: "function",
|
|
107
|
+
namespace: input.calls.namespace,
|
|
108
|
+
name: input.calls.name,
|
|
109
|
+
argTypes: input.calls.argTypes
|
|
110
|
+
},
|
|
111
|
+
...(updateOf ?? []).map((column) => ({
|
|
112
|
+
kind: "column",
|
|
113
|
+
parent: input.parent,
|
|
114
|
+
name: column
|
|
115
|
+
})),
|
|
116
|
+
...input.dependencies ?? []
|
|
117
|
+
];
|
|
118
|
+
const definition = {
|
|
119
|
+
timing: input.timing,
|
|
120
|
+
events,
|
|
121
|
+
level: input.level,
|
|
122
|
+
calls: {
|
|
123
|
+
namespace: input.calls.namespace,
|
|
124
|
+
name: input.calls.name,
|
|
125
|
+
argTypes: [...input.calls.argTypes]
|
|
126
|
+
},
|
|
127
|
+
...updateOf !== undefined && updateOf.length > 0 ? { updateOf } : {},
|
|
128
|
+
...input.when !== undefined && input.when.length > 0 ? { when: input.when } : {}
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
kind: "trigger",
|
|
132
|
+
identity: { kind: "trigger", parent: input.parent, name: input.name },
|
|
133
|
+
owner: input.owner ?? "managed",
|
|
134
|
+
definition,
|
|
135
|
+
dependencies: normaliseEdges(edges),
|
|
136
|
+
provenance: input.provenance
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function readArgument(fn, argument) {
|
|
140
|
+
assertIdentifier2(argument.name, `function ${fn} argument`);
|
|
141
|
+
assertTypeName(argument.type, `function ${fn} argument ${argument.name}`);
|
|
142
|
+
return { name: argument.name, type: argument.type };
|
|
143
|
+
}
|
|
144
|
+
function assertTypeName(typeName, role) {
|
|
145
|
+
if (!TYPE_TEXT.test(typeName)) {
|
|
146
|
+
catalogError2("OKM1020", `${role} ${typeName} is not a type name.`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { functionObject, triggerObject };
|
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
assertBoundText,
|
|
6
6
|
assertRegconfig,
|
|
7
7
|
textArray
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./n7mcc1gk.js";
|
|
9
9
|
import {
|
|
10
10
|
installOperatorSql,
|
|
11
|
+
quote,
|
|
11
12
|
isRecord,
|
|
12
13
|
fail
|
|
13
14
|
} from "./xrfnq5k8.js";
|
|
@@ -35,6 +36,10 @@ function emitStructured(column, ref, name, value, sink) {
|
|
|
35
36
|
emitMatches(column, ref, value, sink);
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
39
|
+
if (name === "similar" || name === "wordSimilar") {
|
|
40
|
+
emitTrigram(column, ref, name, value, sink);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
38
43
|
assertOperatorFits(column, name);
|
|
39
44
|
fail("OKM1121", `${name} is not a value operator on ${column.field}. Use has, none, or every on a relation.`);
|
|
40
45
|
}
|
|
@@ -135,4 +140,17 @@ function emitMatches(column, ref, value, sink) {
|
|
|
135
140
|
sink.param(value.query);
|
|
136
141
|
sink.text(")");
|
|
137
142
|
}
|
|
143
|
+
function emitTrigram(column, ref, name, value, sink) {
|
|
144
|
+
if (!isRecord(value) || typeof value.query !== "string" || typeof value.schema !== "string") {
|
|
145
|
+
fail("OKM1121", `${name} on ${column.field} needs query text.`);
|
|
146
|
+
}
|
|
147
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.schema)) {
|
|
148
|
+
fail("OKM1121", `${name} on ${column.field} needs an extension schema name.`);
|
|
149
|
+
}
|
|
150
|
+
sink.text(ref);
|
|
151
|
+
sink.text(" operator(");
|
|
152
|
+
sink.text(quote(value.schema));
|
|
153
|
+
sink.text(name === "similar" ? ".%) " : ".<%) ");
|
|
154
|
+
sink.param(value.query);
|
|
155
|
+
}
|
|
138
156
|
installOperatorSql(emitStructured);
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
noticeBuffer,
|
|
4
4
|
WireSession,
|
|
5
5
|
cursorStream
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./0jc3ffzf.js";
|
|
7
7
|
import {
|
|
8
8
|
NODE_POSTGRES_CAPABILITIES,
|
|
9
9
|
driverErrors,
|
|
10
10
|
rejectClosed,
|
|
11
11
|
mapFailure,
|
|
12
12
|
runCall
|
|
13
|
-
} from "./
|
|
13
|
+
} from "./rrstp3kb.js";
|
|
14
14
|
|
|
15
15
|
// src/adapters/pg/nodepostgres.ts
|
|
16
16
|
import net from "node:net";
|
|
@@ -53,7 +53,7 @@ function open4(config) {
|
|
|
53
53
|
counters.busy = Math.max(0, counters.busy - 1);
|
|
54
54
|
}, inflight);
|
|
55
55
|
const held = { pool, acquireMs, counters, notices, named, isClosed };
|
|
56
|
-
const checkout = () => closed ? rejectClosed() : import("./
|
|
56
|
+
const checkout = () => closed ? rejectClosed() : import("./6bazvqwm.js").then((mod) => mod.checkout(held));
|
|
57
57
|
return {
|
|
58
58
|
capabilities: NODE_POSTGRES_CAPABILITIES,
|
|
59
59
|
execute(text, params, options) {
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./xw1d69vd.js";
|
|
4
4
|
import {
|
|
5
5
|
catalogHash2
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./t616ynfn.js";
|
|
7
7
|
import"./n442h54c.js";
|
|
8
8
|
import {
|
|
9
9
|
loadMigrations
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./g4f5kcx9.js";
|
|
11
|
+
import {
|
|
12
|
+
assertCreateRole,
|
|
13
|
+
currentUser,
|
|
14
|
+
roleExists
|
|
15
|
+
} from "./hcmdtwgh.js";
|
|
11
16
|
import {
|
|
12
|
-
quoteIdent,
|
|
13
|
-
planMigration,
|
|
14
17
|
assertTargetPolicy,
|
|
15
18
|
assertDirectConnection,
|
|
16
19
|
selectTarget,
|
|
17
20
|
projectHead,
|
|
18
21
|
loadConfig
|
|
19
|
-
} from "./
|
|
22
|
+
} from "./5nmdenb6.js";
|
|
23
|
+
import {
|
|
24
|
+
createdRoleName,
|
|
25
|
+
changesRole,
|
|
26
|
+
assertExtensionsAvailable,
|
|
27
|
+
planMigration
|
|
28
|
+
} from "./2ssqrv66.js";
|
|
29
|
+
import {
|
|
30
|
+
quoteIdent
|
|
31
|
+
} from "./wekze34d.js";
|
|
20
32
|
import {
|
|
21
33
|
OkmError2
|
|
22
34
|
} from "./52szzakm.js";
|
|
@@ -151,6 +163,9 @@ async function applyTarget(request) {
|
|
|
151
163
|
await lockTarget(connection, request.target);
|
|
152
164
|
locked = true;
|
|
153
165
|
request.onLocked?.();
|
|
166
|
+
const session = {};
|
|
167
|
+
await prepareMigrationRole(connection, request, session);
|
|
168
|
+
await assertExtensionsAvailable(connection, request.migrations);
|
|
154
169
|
await assertUuidV7Available(connection, request.migrations);
|
|
155
170
|
await connection.execute(META);
|
|
156
171
|
await connection.execute(HISTORY);
|
|
@@ -162,13 +177,17 @@ async function applyTarget(request) {
|
|
|
162
177
|
continue;
|
|
163
178
|
for (const unit of units) {
|
|
164
179
|
assertUnitPolicy(request, unit);
|
|
165
|
-
await runUnit(connection, unit, request);
|
|
180
|
+
await runUnit(connection, unit, request, session);
|
|
166
181
|
for (const item of unit.steps)
|
|
167
182
|
done.add(`${unit.migrationId}:${String(item.index)}`);
|
|
168
183
|
}
|
|
169
184
|
applied.push(migration.id);
|
|
170
185
|
}
|
|
171
|
-
return {
|
|
186
|
+
return {
|
|
187
|
+
target: request.target,
|
|
188
|
+
applied,
|
|
189
|
+
...session.setRole !== undefined ? { setRole: session.setRole } : {}
|
|
190
|
+
};
|
|
172
191
|
} finally {
|
|
173
192
|
if (locked)
|
|
174
193
|
await connection.execute("select pg_advisory_unlock(hashtext($1))", [
|
|
@@ -194,7 +213,8 @@ nothing to apply
|
|
|
194
213
|
allowPooler: flags.allowPooler || config.allowPooler === true,
|
|
195
214
|
...flags.lockTimeoutMs !== undefined ? { lockTimeoutMs: flags.lockTimeoutMs } : config.timeouts?.lock !== undefined ? { lockTimeoutMs: config.timeouts.lock } : {},
|
|
196
215
|
...flags.statementTimeoutMs !== undefined ? { statementTimeoutMs: flags.statementTimeoutMs } : config.timeouts?.statement !== undefined ? { statementTimeoutMs: config.timeouts.statement } : {},
|
|
197
|
-
migrations
|
|
216
|
+
migrations,
|
|
217
|
+
...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
|
|
198
218
|
});
|
|
199
219
|
return formatReport(report);
|
|
200
220
|
}
|
|
@@ -225,17 +245,20 @@ no changes
|
|
|
225
245
|
catalogHash: catalogHash2(head.catalog),
|
|
226
246
|
steps: plan.steps
|
|
227
247
|
}
|
|
228
|
-
]
|
|
248
|
+
],
|
|
249
|
+
...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
|
|
229
250
|
});
|
|
230
251
|
return formatReport(report);
|
|
231
252
|
}
|
|
232
253
|
function formatReport(report) {
|
|
254
|
+
const role = report.setRole !== undefined ? `set role ${report.setRole}
|
|
255
|
+
` : "";
|
|
233
256
|
if (report.applied.length === 0)
|
|
234
257
|
return `target ${report.target}
|
|
235
|
-
nothing to apply
|
|
258
|
+
${role}nothing to apply
|
|
236
259
|
`;
|
|
237
260
|
return `target ${report.target}
|
|
238
|
-
${report.applied.map((id) => `applied ${id}`).join(`
|
|
261
|
+
${role}${report.applied.map((id) => `applied ${id}`).join(`
|
|
239
262
|
`)}
|
|
240
263
|
`;
|
|
241
264
|
}
|
|
@@ -289,7 +312,31 @@ async function readDone(connection) {
|
|
|
289
312
|
}
|
|
290
313
|
return done;
|
|
291
314
|
}
|
|
292
|
-
async function
|
|
315
|
+
async function prepareMigrationRole(connection, request, session) {
|
|
316
|
+
const role = request.migrationRole;
|
|
317
|
+
const changes = request.migrations.some((migration) => migration.steps.some((step) => changesRole(step.sql)));
|
|
318
|
+
if (role === undefined) {
|
|
319
|
+
if (changes)
|
|
320
|
+
await assertCreateRole(connection, await currentUser(connection));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const current = await currentUser(connection);
|
|
324
|
+
const exists = await roleExists(connection, role);
|
|
325
|
+
if (changes)
|
|
326
|
+
await assertCreateRole(connection, exists && current !== role ? role : current);
|
|
327
|
+
if (exists && current !== role)
|
|
328
|
+
await assumeRole(connection, role, session);
|
|
329
|
+
}
|
|
330
|
+
async function grantSchema(connection, schema, role) {
|
|
331
|
+
await connection.execute(`grant usage, create on schema ${quoteIdent(schema)} to ${quoteIdent(role)}`);
|
|
332
|
+
}
|
|
333
|
+
async function assumeRole(connection, role, session) {
|
|
334
|
+
if (session.setRole === role)
|
|
335
|
+
return;
|
|
336
|
+
await connection.execute(`set role ${quoteIdent(role)}`);
|
|
337
|
+
session.setRole = role;
|
|
338
|
+
}
|
|
339
|
+
async function runUnit(connection, unit, request, session) {
|
|
293
340
|
const retries = request.retries ?? DEFAULT_RETRIES;
|
|
294
341
|
for (let attempt = 0;attempt <= retries; attempt += 1) {
|
|
295
342
|
let began = false;
|
|
@@ -302,7 +349,17 @@ async function runUnit(connection, unit, request) {
|
|
|
302
349
|
for (const item of unit.steps) {
|
|
303
350
|
current = item.index;
|
|
304
351
|
await rebuildInvalidIndex(connection, item.step.sql);
|
|
305
|
-
|
|
352
|
+
const created = createdRoleName(item.step.sql);
|
|
353
|
+
const existed = created !== undefined && await roleExists(connection, created);
|
|
354
|
+
if (created === undefined || !existed)
|
|
355
|
+
await connection.execute(item.step.sql);
|
|
356
|
+
if (created !== undefined && created === request.migrationRole) {
|
|
357
|
+
if (!existed) {
|
|
358
|
+
await grantSchema(connection, request.schema ?? "public", created);
|
|
359
|
+
await connection.execute(`grant select, insert, update on okm_meta, okm_history to ${quoteIdent(created)}`);
|
|
360
|
+
}
|
|
361
|
+
await assumeRole(connection, created, session);
|
|
362
|
+
}
|
|
306
363
|
if (!unit.transactional) {
|
|
307
364
|
await connection.execute("begin");
|
|
308
365
|
began = true;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeText,
|
|
3
3
|
decodeText
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./4m9fn52z.js";
|
|
5
5
|
import {
|
|
6
6
|
required,
|
|
7
7
|
openColumn
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./c9z5g0fm.js";
|
|
9
9
|
import {
|
|
10
10
|
definition,
|
|
11
11
|
rejected
|
|
12
|
-
} from "./
|
|
12
|
+
} from "./tmbdywx0.js";
|
|
13
13
|
import {
|
|
14
14
|
readClientGenerator
|
|
15
15
|
} from "./rwmrejjz.js";
|
|
@@ -66,4 +66,4 @@ function uuidText() {
|
|
|
66
66
|
}
|
|
67
67
|
var uuidPattern;
|
|
68
68
|
|
|
69
|
-
export { id2, uuid2 };
|
|
69
|
+
export { id2, uuid2, encodeUuid, decodeUuid };
|
|
@@ -8,12 +8,12 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
|
8
8
|
if (code.hash === recordedHash)
|
|
9
9
|
return;
|
|
10
10
|
if (code.artifact !== undefined) {
|
|
11
|
-
const { loadTrustedCatalog } = await import("./
|
|
11
|
+
const { loadTrustedCatalog } = await import("./qybh48nd.js");
|
|
12
12
|
loadTrustedCatalog(code.artifact.text, code.artifact.hash);
|
|
13
13
|
} else {
|
|
14
14
|
const artifact = await readCatalogFile(source.catalogDir);
|
|
15
15
|
if (artifact !== undefined) {
|
|
16
|
-
const { loadTrustedCatalog } = await import("./
|
|
16
|
+
const { loadTrustedCatalog } = await import("./qybh48nd.js");
|
|
17
17
|
loadTrustedCatalog(artifact.text, artifact.hash);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -26,7 +26,7 @@ async function codeHash(schema, source) {
|
|
|
26
26
|
const listed = await readHashFile(source.catalogDir);
|
|
27
27
|
if (listed !== undefined)
|
|
28
28
|
return { hash: listed };
|
|
29
|
-
const { catalogHash } = await import("./
|
|
29
|
+
const { catalogHash } = await import("./qybh48nd.js");
|
|
30
30
|
return { hash: catalogHash(schemaCatalog(schema)) };
|
|
31
31
|
}
|
|
32
32
|
function schemaCatalog(schema) {
|
|
@@ -2,17 +2,17 @@ import {
|
|
|
2
2
|
send2,
|
|
3
3
|
reserve,
|
|
4
4
|
park
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./01yr20s5.js";
|
|
6
6
|
import {
|
|
7
7
|
isConnectionLost
|
|
8
8
|
} from "./tbszx8mz.js";
|
|
9
9
|
import {
|
|
10
10
|
WireSession
|
|
11
|
-
} from "./
|
|
11
|
+
} from "./0jc3ffzf.js";
|
|
12
12
|
import {
|
|
13
13
|
rejectClosed,
|
|
14
14
|
runCall
|
|
15
|
-
} from "./
|
|
15
|
+
} from "./rrstp3kb.js";
|
|
16
16
|
|
|
17
17
|
// src/adapters/pg/bunsql-extra.ts
|
|
18
18
|
async function checkout(held) {
|