neon 8.4.5 → 8.6.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 +18 -9
- package/dist/_chunks/{env-4WGRW2nw.js → env-BNm69Qh8.js} +2 -5
- package/dist/commands/config.js +11 -28
- package/dist/commands/dev.js +93 -27
- package/dist/commands/env.js +2 -3
- package/dist/commands/init.js +1 -2
- package/dist/commands/link.js +1 -1
- package/dist/commands/manifest.js +1 -3
- package/dist/commands/subscribe.js +16 -16
- package/dist/credential_io.js +1 -2
- package/dist/dev/env.js +1 -2
- package/dist/dev/runtime.js +8 -0
- package/dist/env_file.js +9 -1
- package/dist/index.js +1 -1
- package/dist/init/auth.js +1 -4
- package/dist/init/choices.js +21 -7
- package/dist/init/copy.js +21 -7
- package/dist/init/run.js +25 -16
- package/dist/plugins/run.js +2 -1
- package/dist/psql/command/cmd_io.js +1 -2
- package/dist/psql/command/cmd_pipeline.js +1 -2
- package/dist/psql/core/common.js +1 -2
- package/dist/psql/core/startup.js +1 -2
- package/dist/psql/index.js +1 -2
- package/dist/psql/types/index.js +1 -2
- package/dist/skills/catalog.js +5 -0
- package/dist/utils/hooks.js +0 -2
- package/dist/utils/staging.js +1 -14
- package/{LICENSE → dist/vendor/postgres-meta/LICENSE} +0 -1
- package/dist/vendor/postgres-meta/constants.js +14 -0
- package/dist/vendor/postgres-meta/lib/PostgresMeta.js +49 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaColumnPrivileges.js +85 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaColumns.js +235 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaConfig.js +16 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaExtensions.js +79 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaForeignTables.js +81 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaFunctions.js +173 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaIndexes.js +42 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaMaterializedViews.js +84 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaPolicies.js +120 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaPublications.js +193 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaRelationships.js +87 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaRoles.js +203 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaSchemas.js +105 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTablePrivileges.js +91 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTables.js +183 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTriggers.js +156 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTypes.js +22 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaVersion.js +20 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaViews.js +83 -0
- package/dist/vendor/postgres-meta/lib/constants.js +8 -0
- package/dist/vendor/postgres-meta/lib/db.js +147 -0
- package/dist/vendor/postgres-meta/lib/generators.js +106 -0
- package/dist/vendor/postgres-meta/lib/helpers.js +26 -0
- package/dist/vendor/postgres-meta/lib/index.js +1 -0
- package/dist/vendor/postgres-meta/lib/sql/column_privileges.sql.js +154 -0
- package/dist/vendor/postgres-meta/lib/sql/columns.sql.js +123 -0
- package/dist/vendor/postgres-meta/lib/sql/common.js +1 -0
- package/dist/vendor/postgres-meta/lib/sql/config.sql.js +32 -0
- package/dist/vendor/postgres-meta/lib/sql/extensions.sql.js +20 -0
- package/dist/vendor/postgres-meta/lib/sql/foreign_tables.sql.js +20 -0
- package/dist/vendor/postgres-meta/lib/sql/functions.sql.js +141 -0
- package/dist/vendor/postgres-meta/lib/sql/indexes.sql.js +51 -0
- package/dist/vendor/postgres-meta/lib/sql/materialized_views.sql.js +21 -0
- package/dist/vendor/postgres-meta/lib/sql/policies.sql.js +53 -0
- package/dist/vendor/postgres-meta/lib/sql/publications.sql.js +46 -0
- package/dist/vendor/postgres-meta/lib/sql/roles.sql.js +40 -0
- package/dist/vendor/postgres-meta/lib/sql/schemas.sql.js +26 -0
- package/dist/vendor/postgres-meta/lib/sql/table.sql.js +109 -0
- package/dist/vendor/postgres-meta/lib/sql/table_privileges.sql.js +85 -0
- package/dist/vendor/postgres-meta/lib/sql/table_relationships.sql.js +52 -0
- package/dist/vendor/postgres-meta/lib/sql/triggers.sql.js +64 -0
- package/dist/vendor/postgres-meta/lib/sql/types.sql.js +65 -0
- package/dist/vendor/postgres-meta/lib/sql/version.sql.js +15 -0
- package/dist/vendor/postgres-meta/lib/sql/views.sql.js +22 -0
- package/dist/vendor/postgres-meta/lib/sql/views_key_dependencies.sql.js +198 -0
- package/dist/vendor/postgres-meta/lib/types.js +1 -0
- package/dist/vendor/postgres-meta/templates/typescript.js +608 -0
- package/package.json +12 -5
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { COLUMNS_SQL } from "./sql/columns.sql.js";
|
|
4
|
+
import PostgresMetaTables from "./PostgresMetaTables.js";
|
|
5
|
+
import { ident, literal } from "pg-format";
|
|
6
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaColumns.ts
|
|
7
|
+
var PostgresMetaColumns = class {
|
|
8
|
+
constructor(query) {
|
|
9
|
+
this.query = query;
|
|
10
|
+
this.metaTables = new PostgresMetaTables(query);
|
|
11
|
+
}
|
|
12
|
+
async list({ tableId, includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset } = {}) {
|
|
13
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
14
|
+
const tableIdFilter = tableId ? filterByValue([`${tableId}`]) : void 0;
|
|
15
|
+
const sql = COLUMNS_SQL({
|
|
16
|
+
schemaFilter,
|
|
17
|
+
tableIdFilter,
|
|
18
|
+
limit,
|
|
19
|
+
offset
|
|
20
|
+
});
|
|
21
|
+
return await this.query(sql);
|
|
22
|
+
}
|
|
23
|
+
async retrieve({ id, name, table, schema = "public" }) {
|
|
24
|
+
const schemaFilter = schema ? filterByList([schema], []) : void 0;
|
|
25
|
+
if (id) {
|
|
26
|
+
const regexp = /^(\d+)\.(\d+)$/;
|
|
27
|
+
if (!regexp.test(id)) return {
|
|
28
|
+
data: null,
|
|
29
|
+
error: { message: "Invalid format for column ID" }
|
|
30
|
+
};
|
|
31
|
+
const [tableId, ordinalPos] = id.match(regexp).slice(1).map(Number);
|
|
32
|
+
const idsFilter = filterByValue([`${tableId}.${ordinalPos}`]);
|
|
33
|
+
const sql = COLUMNS_SQL({ idsFilter });
|
|
34
|
+
const { data, error } = await this.query(sql);
|
|
35
|
+
if (error) return {
|
|
36
|
+
data,
|
|
37
|
+
error
|
|
38
|
+
};
|
|
39
|
+
else if (data.length === 0) return {
|
|
40
|
+
data: null,
|
|
41
|
+
error: { message: `Cannot find a column with ID ${id}` }
|
|
42
|
+
};
|
|
43
|
+
else return {
|
|
44
|
+
data: data[0],
|
|
45
|
+
error
|
|
46
|
+
};
|
|
47
|
+
} else if (name && table) {
|
|
48
|
+
const columnNameFilter = filterByValue([`${table}.${name}`]);
|
|
49
|
+
const sql = `${COLUMNS_SQL({
|
|
50
|
+
schemaFilter,
|
|
51
|
+
columnNameFilter
|
|
52
|
+
})};`;
|
|
53
|
+
const { data, error } = await this.query(sql);
|
|
54
|
+
if (error) return {
|
|
55
|
+
data,
|
|
56
|
+
error
|
|
57
|
+
};
|
|
58
|
+
else if (data.length === 0) return {
|
|
59
|
+
data: null,
|
|
60
|
+
error: { message: `Cannot find a column named ${name} in table ${schema}.${table}` }
|
|
61
|
+
};
|
|
62
|
+
else return {
|
|
63
|
+
data: data[0],
|
|
64
|
+
error
|
|
65
|
+
};
|
|
66
|
+
} else return {
|
|
67
|
+
data: null,
|
|
68
|
+
error: { message: "Invalid parameters on column retrieve" }
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async create({ table_id, name, type, default_value, default_value_format = "literal", is_identity = false, identity_generation = "BY DEFAULT", is_nullable, is_primary_key = false, is_unique = false, comment, check }) {
|
|
72
|
+
const { data, error } = await this.metaTables.retrieve({ id: table_id });
|
|
73
|
+
if (error) return {
|
|
74
|
+
data: null,
|
|
75
|
+
error
|
|
76
|
+
};
|
|
77
|
+
const { name: table, schema } = data;
|
|
78
|
+
let defaultValueClause = "";
|
|
79
|
+
if (is_identity) {
|
|
80
|
+
if (default_value !== void 0) return {
|
|
81
|
+
data: null,
|
|
82
|
+
error: { message: "Columns cannot both be identity and have a default value" }
|
|
83
|
+
};
|
|
84
|
+
defaultValueClause = `GENERATED ${identity_generation} AS IDENTITY`;
|
|
85
|
+
} else if (default_value === void 0) {} else if (default_value_format === "expression") defaultValueClause = `DEFAULT ${default_value}`;
|
|
86
|
+
else defaultValueClause = `DEFAULT ${literal(default_value)}`;
|
|
87
|
+
let isNullableClause = "";
|
|
88
|
+
if (is_nullable !== void 0) isNullableClause = is_nullable ? "NULL" : "NOT NULL";
|
|
89
|
+
const isPrimaryKeyClause = is_primary_key ? "PRIMARY KEY" : "";
|
|
90
|
+
const isUniqueClause = is_unique ? "UNIQUE" : "";
|
|
91
|
+
const checkSql = check === void 0 ? "" : `CHECK (${check})`;
|
|
92
|
+
const commentSql = comment === void 0 ? "" : `COMMENT ON COLUMN ${ident(schema)}.${ident(table)}.${ident(name)} IS ${literal(comment)}`;
|
|
93
|
+
const sql = `
|
|
94
|
+
BEGIN;
|
|
95
|
+
ALTER TABLE ${ident(schema)}.${ident(table)} ADD COLUMN ${ident(name)} ${typeIdent(type)}
|
|
96
|
+
${defaultValueClause}
|
|
97
|
+
${isNullableClause}
|
|
98
|
+
${isPrimaryKeyClause}
|
|
99
|
+
${isUniqueClause}
|
|
100
|
+
${checkSql};
|
|
101
|
+
${commentSql};
|
|
102
|
+
COMMIT;`;
|
|
103
|
+
{
|
|
104
|
+
const { error } = await this.query(sql);
|
|
105
|
+
if (error) return {
|
|
106
|
+
data: null,
|
|
107
|
+
error
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return await this.retrieve({
|
|
111
|
+
name,
|
|
112
|
+
table,
|
|
113
|
+
schema
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async update(id, { name, type, drop_default = false, default_value, default_value_format = "literal", is_identity, identity_generation = "BY DEFAULT", is_nullable, is_unique, comment, check }) {
|
|
117
|
+
const { data: old, error } = await this.retrieve({ id });
|
|
118
|
+
if (error) return {
|
|
119
|
+
data: null,
|
|
120
|
+
error
|
|
121
|
+
};
|
|
122
|
+
const nameSql = name === void 0 || name === old.name ? "" : `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} RENAME COLUMN ${ident(old.name)} TO ${ident(name)};`;
|
|
123
|
+
const typeSql = type === void 0 ? "" : `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)} SET DATA TYPE ${typeIdent(type)} USING ${ident(old.name)}::${typeIdent(type)};`;
|
|
124
|
+
let defaultValueSql;
|
|
125
|
+
if (drop_default) defaultValueSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)} DROP DEFAULT;`;
|
|
126
|
+
else if (default_value === void 0) defaultValueSql = "";
|
|
127
|
+
else {
|
|
128
|
+
const defaultValue = default_value_format === "expression" ? default_value : literal(default_value);
|
|
129
|
+
defaultValueSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)} SET DEFAULT ${defaultValue};`;
|
|
130
|
+
}
|
|
131
|
+
let identitySql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)}`;
|
|
132
|
+
if (is_identity === false) identitySql += " DROP IDENTITY IF EXISTS;";
|
|
133
|
+
else if (old.is_identity === true) {
|
|
134
|
+
if (identity_generation === void 0) identitySql = "";
|
|
135
|
+
else identitySql += ` SET GENERATED ${identity_generation};`;
|
|
136
|
+
} else if (is_identity === void 0) identitySql = "";
|
|
137
|
+
else identitySql += ` ADD GENERATED ${identity_generation} AS IDENTITY;`;
|
|
138
|
+
let isNullableSql;
|
|
139
|
+
if (is_nullable === void 0) isNullableSql = "";
|
|
140
|
+
else isNullableSql = is_nullable ? `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)} DROP NOT NULL;` : `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ALTER COLUMN ${ident(old.name)} SET NOT NULL;`;
|
|
141
|
+
let isUniqueSql = "";
|
|
142
|
+
if (old.is_unique === true && is_unique === false) isUniqueSql = `
|
|
143
|
+
DO $$
|
|
144
|
+
DECLARE
|
|
145
|
+
r record;
|
|
146
|
+
BEGIN
|
|
147
|
+
FOR r IN
|
|
148
|
+
SELECT conname FROM pg_constraint WHERE
|
|
149
|
+
contype = 'u'
|
|
150
|
+
AND cardinality(conkey) = 1
|
|
151
|
+
AND conrelid = ${literal(old.table_id)}
|
|
152
|
+
AND conkey[1] = ${literal(old.ordinal_position)}
|
|
153
|
+
LOOP
|
|
154
|
+
EXECUTE ${literal(`ALTER TABLE ${ident(old.schema)}.${ident(old.table)} DROP CONSTRAINT `)} || quote_ident(r.conname);
|
|
155
|
+
END LOOP;
|
|
156
|
+
END
|
|
157
|
+
$$;
|
|
158
|
+
`;
|
|
159
|
+
else if (old.is_unique === false && is_unique === true) isUniqueSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ADD UNIQUE (${ident(old.name)});`;
|
|
160
|
+
const commentSql = comment === void 0 ? "" : `COMMENT ON COLUMN ${ident(old.schema)}.${ident(old.table)}.${ident(old.name)} IS ${literal(comment)};`;
|
|
161
|
+
const checkSql = check === void 0 ? "" : `
|
|
162
|
+
DO $$
|
|
163
|
+
DECLARE
|
|
164
|
+
v_conname name;
|
|
165
|
+
v_conkey int2[];
|
|
166
|
+
BEGIN
|
|
167
|
+
SELECT conname into v_conname FROM pg_constraint WHERE
|
|
168
|
+
contype = 'c'
|
|
169
|
+
AND cardinality(conkey) = 1
|
|
170
|
+
AND conrelid = ${literal(old.table_id)}
|
|
171
|
+
AND conkey[1] = ${literal(old.ordinal_position)}
|
|
172
|
+
ORDER BY oid asc
|
|
173
|
+
LIMIT 1;
|
|
174
|
+
|
|
175
|
+
IF v_conname IS NOT NULL THEN
|
|
176
|
+
EXECUTE format('ALTER TABLE ${ident(old.schema)}.${ident(old.table)} DROP CONSTRAINT %s', v_conname);
|
|
177
|
+
END IF;
|
|
178
|
+
|
|
179
|
+
${check !== null ? `
|
|
180
|
+
ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ADD CONSTRAINT ${ident(`${old.table}_${old.name}_check`)} CHECK (${check});
|
|
181
|
+
|
|
182
|
+
SELECT conkey into v_conkey FROM pg_constraint WHERE conname = ${literal(`${old.table}_${old.name}_check`)};
|
|
183
|
+
|
|
184
|
+
ASSERT v_conkey IS NOT NULL, 'error creating column constraint: check condition must refer to this column';
|
|
185
|
+
ASSERT cardinality(v_conkey) = 1, 'error creating column constraint: check condition cannot refer to multiple columns';
|
|
186
|
+
ASSERT v_conkey[1] = ${literal(old.ordinal_position)}, 'error creating column constraint: check condition cannot refer to other columns';
|
|
187
|
+
` : ""}
|
|
188
|
+
END
|
|
189
|
+
$$;
|
|
190
|
+
`;
|
|
191
|
+
const sql = `
|
|
192
|
+
BEGIN;
|
|
193
|
+
${isNullableSql}
|
|
194
|
+
${typeSql}
|
|
195
|
+
${defaultValueSql}
|
|
196
|
+
${identitySql}
|
|
197
|
+
${isUniqueSql}
|
|
198
|
+
${commentSql}
|
|
199
|
+
${checkSql}
|
|
200
|
+
${nameSql}
|
|
201
|
+
COMMIT;`;
|
|
202
|
+
{
|
|
203
|
+
const { error } = await this.query(sql);
|
|
204
|
+
if (error) return {
|
|
205
|
+
data: null,
|
|
206
|
+
error
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return await this.retrieve({ id });
|
|
210
|
+
}
|
|
211
|
+
async remove(id, { cascade = false } = {}) {
|
|
212
|
+
const { data: column, error } = await this.retrieve({ id });
|
|
213
|
+
if (error) return {
|
|
214
|
+
data: null,
|
|
215
|
+
error
|
|
216
|
+
};
|
|
217
|
+
const sql = `ALTER TABLE ${ident(column.schema)}.${ident(column.table)} DROP COLUMN ${ident(column.name)} ${cascade ? "CASCADE" : "RESTRICT"};`;
|
|
218
|
+
{
|
|
219
|
+
const { error } = await this.query(sql);
|
|
220
|
+
if (error) return {
|
|
221
|
+
data: null,
|
|
222
|
+
error
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
data: column,
|
|
227
|
+
error: null
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const typeIdent = (type) => {
|
|
232
|
+
return type.endsWith("[]") ? `${ident(type.slice(0, -2))}[]` : type.includes(".") ? type : ident(type);
|
|
233
|
+
};
|
|
234
|
+
//#endregion
|
|
235
|
+
export { PostgresMetaColumns as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CONFIG_SQL } from "./sql/config.sql.js";
|
|
2
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaConfig.ts
|
|
3
|
+
var PostgresMetaConfig = class {
|
|
4
|
+
constructor(query) {
|
|
5
|
+
this.query = query;
|
|
6
|
+
}
|
|
7
|
+
async list({ limit, offset } = {}) {
|
|
8
|
+
const sql = CONFIG_SQL({
|
|
9
|
+
limit,
|
|
10
|
+
offset
|
|
11
|
+
});
|
|
12
|
+
return await this.query(sql);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { PostgresMetaConfig as default };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { filterByValue } from "./helpers.js";
|
|
2
|
+
import { EXTENSIONS_SQL } from "./sql/extensions.sql.js";
|
|
3
|
+
import { ident, literal } from "pg-format";
|
|
4
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaExtensions.ts
|
|
5
|
+
var PostgresMetaExtensions = class {
|
|
6
|
+
constructor(query) {
|
|
7
|
+
this.query = query;
|
|
8
|
+
}
|
|
9
|
+
async list({ limit, offset } = {}) {
|
|
10
|
+
const sql = EXTENSIONS_SQL({
|
|
11
|
+
limit,
|
|
12
|
+
offset
|
|
13
|
+
});
|
|
14
|
+
return await this.query(sql);
|
|
15
|
+
}
|
|
16
|
+
async retrieve({ name }) {
|
|
17
|
+
const nameFilter = filterByValue([name]);
|
|
18
|
+
const sql = EXTENSIONS_SQL({ nameFilter });
|
|
19
|
+
const { data, error } = await this.query(sql);
|
|
20
|
+
if (error) return {
|
|
21
|
+
data,
|
|
22
|
+
error
|
|
23
|
+
};
|
|
24
|
+
else if (data.length === 0) return {
|
|
25
|
+
data: null,
|
|
26
|
+
error: { message: `Cannot find an extension named ${name}` }
|
|
27
|
+
};
|
|
28
|
+
else return {
|
|
29
|
+
data: data[0],
|
|
30
|
+
error
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async create({ name, schema, version, cascade = false }) {
|
|
34
|
+
const sql = `
|
|
35
|
+
CREATE EXTENSION ${ident(name)}
|
|
36
|
+
${schema === void 0 ? "" : `SCHEMA ${ident(schema)}`}
|
|
37
|
+
${version === void 0 ? "" : `VERSION ${literal(version)}`}
|
|
38
|
+
${cascade ? "CASCADE" : ""};`;
|
|
39
|
+
const { error } = await this.query(sql);
|
|
40
|
+
if (error) return {
|
|
41
|
+
data: null,
|
|
42
|
+
error
|
|
43
|
+
};
|
|
44
|
+
return await this.retrieve({ name });
|
|
45
|
+
}
|
|
46
|
+
async update(name, { update = false, version, schema }) {
|
|
47
|
+
let updateSql = "";
|
|
48
|
+
if (update) updateSql = `ALTER EXTENSION ${ident(name)} UPDATE ${version === void 0 ? "" : `TO ${literal(version)}`};`;
|
|
49
|
+
const schemaSql = schema === void 0 ? "" : `ALTER EXTENSION ${ident(name)} SET SCHEMA ${ident(schema)};`;
|
|
50
|
+
const sql = `BEGIN; ${updateSql} ${schemaSql} COMMIT;`;
|
|
51
|
+
const { error } = await this.query(sql);
|
|
52
|
+
if (error) return {
|
|
53
|
+
data: null,
|
|
54
|
+
error
|
|
55
|
+
};
|
|
56
|
+
return await this.retrieve({ name });
|
|
57
|
+
}
|
|
58
|
+
async remove(name, { cascade = false } = {}) {
|
|
59
|
+
const { data: extension, error } = await this.retrieve({ name });
|
|
60
|
+
if (error) return {
|
|
61
|
+
data: null,
|
|
62
|
+
error
|
|
63
|
+
};
|
|
64
|
+
const sql = `DROP EXTENSION ${ident(name)} ${cascade ? "CASCADE" : "RESTRICT"};`;
|
|
65
|
+
{
|
|
66
|
+
const { error } = await this.query(sql);
|
|
67
|
+
if (error) return {
|
|
68
|
+
data: null,
|
|
69
|
+
error
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
data: extension,
|
|
74
|
+
error: null
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
export { PostgresMetaExtensions as default };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { coalesceRowsToArray, filterByList, filterByValue } from "./helpers.js";
|
|
2
|
+
import { COLUMNS_SQL } from "./sql/columns.sql.js";
|
|
3
|
+
import { FOREIGN_TABLES_SQL } from "./sql/foreign_tables.sql.js";
|
|
4
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaForeignTables.ts
|
|
5
|
+
var PostgresMetaForeignTables = class {
|
|
6
|
+
constructor(query) {
|
|
7
|
+
this.query = query;
|
|
8
|
+
}
|
|
9
|
+
async list({ includedSchemas, excludedSchemas, limit, offset, includeColumns = true } = {}) {
|
|
10
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas);
|
|
11
|
+
const sql = generateEnrichedForeignTablesSql({
|
|
12
|
+
includeColumns,
|
|
13
|
+
schemaFilter,
|
|
14
|
+
limit,
|
|
15
|
+
offset
|
|
16
|
+
});
|
|
17
|
+
return await this.query(sql);
|
|
18
|
+
}
|
|
19
|
+
async retrieve({ id, name, schema = "public" }) {
|
|
20
|
+
if (id) {
|
|
21
|
+
const idsFilter = filterByValue([`${id}`]);
|
|
22
|
+
const sql = generateEnrichedForeignTablesSql({
|
|
23
|
+
includeColumns: true,
|
|
24
|
+
idsFilter
|
|
25
|
+
});
|
|
26
|
+
const { data, error } = await this.query(sql);
|
|
27
|
+
if (error) return {
|
|
28
|
+
data,
|
|
29
|
+
error
|
|
30
|
+
};
|
|
31
|
+
else if (data.length === 0) return {
|
|
32
|
+
data: null,
|
|
33
|
+
error: { message: `Cannot find a foreign table with ID ${id}` }
|
|
34
|
+
};
|
|
35
|
+
else return {
|
|
36
|
+
data: data[0],
|
|
37
|
+
error
|
|
38
|
+
};
|
|
39
|
+
} else if (name) {
|
|
40
|
+
const nameFilter = filterByValue([`${schema}.${name}`]);
|
|
41
|
+
const sql = generateEnrichedForeignTablesSql({
|
|
42
|
+
includeColumns: true,
|
|
43
|
+
tableIdentifierFilter: nameFilter
|
|
44
|
+
});
|
|
45
|
+
const { data, error } = await this.query(sql);
|
|
46
|
+
if (error) return {
|
|
47
|
+
data,
|
|
48
|
+
error
|
|
49
|
+
};
|
|
50
|
+
else if (data.length === 0) return {
|
|
51
|
+
data: null,
|
|
52
|
+
error: { message: `Cannot find a foreign table named ${name} in schema ${schema}` }
|
|
53
|
+
};
|
|
54
|
+
else return {
|
|
55
|
+
data: data[0],
|
|
56
|
+
error
|
|
57
|
+
};
|
|
58
|
+
} else return {
|
|
59
|
+
data: null,
|
|
60
|
+
error: { message: "Invalid parameters on foreign table retrieve" }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const generateEnrichedForeignTablesSql = ({ includeColumns, schemaFilter, idsFilter, tableIdentifierFilter, limit, offset }) => `
|
|
65
|
+
with foreign_tables as (${FOREIGN_TABLES_SQL({
|
|
66
|
+
schemaFilter,
|
|
67
|
+
tableIdentifierFilter,
|
|
68
|
+
limit,
|
|
69
|
+
offset
|
|
70
|
+
})})
|
|
71
|
+
${includeColumns ? `, columns as (${COLUMNS_SQL({
|
|
72
|
+
schemaFilter,
|
|
73
|
+
tableIdentifierFilter,
|
|
74
|
+
tableIdFilter: idsFilter
|
|
75
|
+
})})` : ""}
|
|
76
|
+
select
|
|
77
|
+
*
|
|
78
|
+
${includeColumns ? `, ${coalesceRowsToArray("columns", "columns.table_id = foreign_tables.id")}` : ""}
|
|
79
|
+
from foreign_tables`;
|
|
80
|
+
//#endregion
|
|
81
|
+
export { PostgresMetaForeignTables as default };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { FUNCTIONS_SQL } from "./sql/functions.sql.js";
|
|
4
|
+
import { ident, literal } from "pg-format";
|
|
5
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaFunctions.ts
|
|
6
|
+
var PostgresMetaFunctions = class {
|
|
7
|
+
constructor(query) {
|
|
8
|
+
this.query = query;
|
|
9
|
+
}
|
|
10
|
+
async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset } = {}) {
|
|
11
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
12
|
+
const sql = FUNCTIONS_SQL({
|
|
13
|
+
schemaFilter,
|
|
14
|
+
limit,
|
|
15
|
+
offset
|
|
16
|
+
});
|
|
17
|
+
return await this.query(sql);
|
|
18
|
+
}
|
|
19
|
+
async retrieve({ id, name, schema = "public", args = [] }) {
|
|
20
|
+
const schemaFilter = schema ? filterByList([schema], []) : void 0;
|
|
21
|
+
if (id) {
|
|
22
|
+
const idsFilter = filterByValue([id]);
|
|
23
|
+
const sql = FUNCTIONS_SQL({ idsFilter });
|
|
24
|
+
const { data, error } = await this.query(sql);
|
|
25
|
+
if (error) return {
|
|
26
|
+
data,
|
|
27
|
+
error
|
|
28
|
+
};
|
|
29
|
+
else if (data.length === 0) return {
|
|
30
|
+
data: null,
|
|
31
|
+
error: { message: `Cannot find a function with ID ${id}` }
|
|
32
|
+
};
|
|
33
|
+
else return {
|
|
34
|
+
data: data[0],
|
|
35
|
+
error
|
|
36
|
+
};
|
|
37
|
+
} else if (name && schema && args) {
|
|
38
|
+
const nameFilter = filterByValue([name]);
|
|
39
|
+
const sql = FUNCTIONS_SQL({
|
|
40
|
+
schemaFilter,
|
|
41
|
+
nameFilter,
|
|
42
|
+
args: args.map(literal)
|
|
43
|
+
});
|
|
44
|
+
const { data, error } = await this.query(sql);
|
|
45
|
+
if (error) return {
|
|
46
|
+
data,
|
|
47
|
+
error
|
|
48
|
+
};
|
|
49
|
+
else if (data.length === 0) return {
|
|
50
|
+
data: null,
|
|
51
|
+
error: { message: `Cannot find function "${schema}"."${name}"(${args.join(", ")})` }
|
|
52
|
+
};
|
|
53
|
+
else return {
|
|
54
|
+
data: data[0],
|
|
55
|
+
error
|
|
56
|
+
};
|
|
57
|
+
} else return {
|
|
58
|
+
data: null,
|
|
59
|
+
error: { message: "Invalid parameters on function retrieve" }
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async create({ name, schema = "public", args = [], definition, return_type = "void", language = "sql", behavior = "VOLATILE", security_definer = false, config_params = {} }) {
|
|
63
|
+
const sql = this.generateCreateFunctionSql({
|
|
64
|
+
name,
|
|
65
|
+
schema,
|
|
66
|
+
args,
|
|
67
|
+
definition,
|
|
68
|
+
return_type,
|
|
69
|
+
language,
|
|
70
|
+
behavior,
|
|
71
|
+
security_definer,
|
|
72
|
+
config_params
|
|
73
|
+
});
|
|
74
|
+
const { error } = await this.query(sql);
|
|
75
|
+
if (error) return {
|
|
76
|
+
data: null,
|
|
77
|
+
error
|
|
78
|
+
};
|
|
79
|
+
return await this.retrieve({
|
|
80
|
+
name,
|
|
81
|
+
schema,
|
|
82
|
+
args
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async update(id, { name, schema, definition }) {
|
|
86
|
+
const { data: currentFunc, error } = await this.retrieve({ id });
|
|
87
|
+
if (error) return {
|
|
88
|
+
data: null,
|
|
89
|
+
error
|
|
90
|
+
};
|
|
91
|
+
const args = currentFunc.argument_types.split(", ");
|
|
92
|
+
const identityArgs = currentFunc.identity_argument_types;
|
|
93
|
+
const updateDefinitionSql = typeof definition === "string" ? this.generateCreateFunctionSql({
|
|
94
|
+
...currentFunc,
|
|
95
|
+
definition,
|
|
96
|
+
args,
|
|
97
|
+
config_params: currentFunc.config_params ?? {}
|
|
98
|
+
}, { replace: true }) : "";
|
|
99
|
+
const updateNameSql = name && name !== currentFunc.name ? `ALTER FUNCTION ${ident(currentFunc.schema)}.${ident(currentFunc.name)}(${identityArgs}) RENAME TO ${ident(name)};` : "";
|
|
100
|
+
const updateSchemaSql = schema && schema !== currentFunc.schema ? `ALTER FUNCTION ${ident(currentFunc.schema)}.${ident(name || currentFunc.name)}(${identityArgs}) SET SCHEMA ${ident(schema)};` : "";
|
|
101
|
+
const currentSchemaFilter = currentFunc.schema ? filterByList([currentFunc.schema], []) : void 0;
|
|
102
|
+
const currentNameFilter = currentFunc.name ? filterByValue([currentFunc.name]) : void 0;
|
|
103
|
+
const sql = `
|
|
104
|
+
DO LANGUAGE plpgsql $$
|
|
105
|
+
BEGIN
|
|
106
|
+
IF ${typeof definition === "string" ? "TRUE" : "FALSE"} THEN
|
|
107
|
+
${updateDefinitionSql}
|
|
108
|
+
|
|
109
|
+
IF (
|
|
110
|
+
SELECT id
|
|
111
|
+
FROM (${FUNCTIONS_SQL({
|
|
112
|
+
schemaFilter: currentSchemaFilter,
|
|
113
|
+
nameFilter: currentNameFilter
|
|
114
|
+
})}) AS f
|
|
115
|
+
WHERE f.schema = ${literal(currentFunc.schema)}
|
|
116
|
+
AND f.name = ${literal(currentFunc.name)}
|
|
117
|
+
AND f.identity_argument_types = ${literal(identityArgs)}
|
|
118
|
+
) != ${id} THEN
|
|
119
|
+
RAISE EXCEPTION 'Cannot find function "${currentFunc.schema}"."${currentFunc.name}"(${identityArgs})';
|
|
120
|
+
END IF;
|
|
121
|
+
END IF;
|
|
122
|
+
|
|
123
|
+
${updateNameSql}
|
|
124
|
+
|
|
125
|
+
${updateSchemaSql}
|
|
126
|
+
END;
|
|
127
|
+
$$;
|
|
128
|
+
`;
|
|
129
|
+
{
|
|
130
|
+
const { error } = await this.query(sql);
|
|
131
|
+
if (error) return {
|
|
132
|
+
data: null,
|
|
133
|
+
error
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return await this.retrieve({ id });
|
|
137
|
+
}
|
|
138
|
+
async remove(id, { cascade = false } = {}) {
|
|
139
|
+
const { data: func, error } = await this.retrieve({ id });
|
|
140
|
+
if (error) return {
|
|
141
|
+
data: null,
|
|
142
|
+
error
|
|
143
|
+
};
|
|
144
|
+
const sql = `DROP FUNCTION ${ident(func.schema)}.${ident(func.name)}
|
|
145
|
+
(${func.identity_argument_types})
|
|
146
|
+
${cascade ? "CASCADE" : "RESTRICT"};`;
|
|
147
|
+
{
|
|
148
|
+
const { error } = await this.query(sql);
|
|
149
|
+
if (error) return {
|
|
150
|
+
data: null,
|
|
151
|
+
error
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
data: func,
|
|
156
|
+
error: null
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
generateCreateFunctionSql({ name, schema, args, definition, return_type, language, behavior, security_definer, config_params }, { replace = false } = {}) {
|
|
160
|
+
return `
|
|
161
|
+
CREATE ${replace ? "OR REPLACE" : ""} FUNCTION ${ident(schema)}.${ident(name)}(${args?.join(", ") || ""})
|
|
162
|
+
RETURNS ${return_type}
|
|
163
|
+
AS ${literal(definition)}
|
|
164
|
+
LANGUAGE ${language}
|
|
165
|
+
${behavior}
|
|
166
|
+
CALLED ON NULL INPUT
|
|
167
|
+
${security_definer ? "SECURITY DEFINER" : "SECURITY INVOKER"}
|
|
168
|
+
${config_params ? Object.entries(config_params).map(([param, value]) => `SET ${param} ${value[0] === "FROM CURRENT" ? "FROM CURRENT" : "TO " + value}`).join("\n") : ""};
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
//#endregion
|
|
173
|
+
export { PostgresMetaFunctions as default };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { INDEXES_SQL } from "./sql/indexes.sql.js";
|
|
4
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaIndexes.ts
|
|
5
|
+
var PostgresMetaIndexes = class {
|
|
6
|
+
constructor(query) {
|
|
7
|
+
this.query = query;
|
|
8
|
+
}
|
|
9
|
+
async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset } = {}) {
|
|
10
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
11
|
+
const sql = INDEXES_SQL({
|
|
12
|
+
schemaFilter,
|
|
13
|
+
limit,
|
|
14
|
+
offset
|
|
15
|
+
});
|
|
16
|
+
return await this.query(sql);
|
|
17
|
+
}
|
|
18
|
+
async retrieve({ id }) {
|
|
19
|
+
if (id) {
|
|
20
|
+
const idsFilter = filterByValue([id]);
|
|
21
|
+
const sql = INDEXES_SQL({ idsFilter });
|
|
22
|
+
const { data, error } = await this.query(sql);
|
|
23
|
+
if (error) return {
|
|
24
|
+
data,
|
|
25
|
+
error
|
|
26
|
+
};
|
|
27
|
+
else if (data.length === 0) return {
|
|
28
|
+
data: null,
|
|
29
|
+
error: { message: `Cannot find a index with ID ${id}` }
|
|
30
|
+
};
|
|
31
|
+
else return {
|
|
32
|
+
data: data[0],
|
|
33
|
+
error
|
|
34
|
+
};
|
|
35
|
+
} else return {
|
|
36
|
+
data: null,
|
|
37
|
+
error: { message: "Invalid parameters on function retrieve" }
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { PostgresMetaIndexes as default };
|