neon 8.4.5 → 8.5.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 +7 -7
- package/dist/_chunks/{env-4WGRW2nw.js → env-BNm69Qh8.js} +2 -5
- package/dist/commands/config.js +11 -28
- package/dist/commands/dev.js +1 -1
- package/dist/commands/env.js +2 -3
- package/dist/commands/init.js +1 -2
- 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/index.js +1 -1
- package/dist/init/run.js +1 -2
- 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 +13 -6
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { TRIGGERS_SQL } from "./sql/triggers.sql.js";
|
|
4
|
+
import { ident, literal } from "pg-format";
|
|
5
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaTriggers.ts
|
|
6
|
+
var PostgresMetaTriggers = 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
|
+
let sql = TRIGGERS_SQL({
|
|
13
|
+
schemaFilter,
|
|
14
|
+
limit,
|
|
15
|
+
offset
|
|
16
|
+
});
|
|
17
|
+
return await this.query(sql);
|
|
18
|
+
}
|
|
19
|
+
async retrieve({ id, name, schema = "public", table }) {
|
|
20
|
+
const schemaFilter = schema ? filterByList([schema], []) : void 0;
|
|
21
|
+
if (id) {
|
|
22
|
+
const idsFilter = filterByValue([id]);
|
|
23
|
+
const sql = TRIGGERS_SQL({ idsFilter });
|
|
24
|
+
const { data, error } = await this.query(sql);
|
|
25
|
+
if (error) return {
|
|
26
|
+
data: null,
|
|
27
|
+
error
|
|
28
|
+
};
|
|
29
|
+
const triggerRecord = data && data[0];
|
|
30
|
+
if (triggerRecord) return {
|
|
31
|
+
data: triggerRecord,
|
|
32
|
+
error: null
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
data: null,
|
|
36
|
+
error: { message: `Cannot find a trigger with ID ${id}` }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (name && schema && table) {
|
|
40
|
+
const nameFilter = filterByValue([name]);
|
|
41
|
+
const tableNameFilter = filterByValue([table]);
|
|
42
|
+
const sql = TRIGGERS_SQL({
|
|
43
|
+
schemaFilter,
|
|
44
|
+
nameFilter,
|
|
45
|
+
tableNameFilter
|
|
46
|
+
});
|
|
47
|
+
const { data, error } = await this.query(sql);
|
|
48
|
+
if (error) return {
|
|
49
|
+
data: null,
|
|
50
|
+
error
|
|
51
|
+
};
|
|
52
|
+
const triggerRecord = data && data[0];
|
|
53
|
+
if (triggerRecord) return {
|
|
54
|
+
data: triggerRecord,
|
|
55
|
+
error: null
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
data: null,
|
|
59
|
+
error: { message: `Cannot find a trigger with name ${name} on table "${schema}"."${table}"` }
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
data: null,
|
|
64
|
+
error: { message: "Invalid parameters on trigger retrieve" }
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates trigger
|
|
69
|
+
*
|
|
70
|
+
* @param {Object} obj - An object.
|
|
71
|
+
* @param {string} obj.name - Trigger name.
|
|
72
|
+
* @param {string} obj.schema - Name of schema that trigger is for.
|
|
73
|
+
* @param {string} obj.table - Unqualified table, view, or foreign table name that trigger is for.
|
|
74
|
+
* @param {string} obj.function_schema - Name of schema that function is for.
|
|
75
|
+
* @param {string} obj.function_name - Unqualified name of the function to execute.
|
|
76
|
+
* @param {('BEFORE'|'AFTER'|'INSTEAD OF')} obj.activation - Determines when function is called
|
|
77
|
+
* during event occurrence.
|
|
78
|
+
* @param {Array<string>} obj.events - Event(s) that will fire the trigger. Array of the following options: 'INSERT' | 'UPDATE' | 'UPDATE
|
|
79
|
+
* OF column_name1,column_name2' | 'DELETE' | 'TRUNCATE'.
|
|
80
|
+
* @param {('ROW'|'STATEMENT')} obj.orientation - Trigger function for every row affected by event or
|
|
81
|
+
* once per statement. Defaults to 'STATEMENT'.
|
|
82
|
+
* @param {string} obj.condition - Boolean expression that will trigger function.
|
|
83
|
+
* For example: 'old.* IS DISTINCT FROM new.*'
|
|
84
|
+
* @param {Array<string>} obj.function_args - array of arguments to be passed to function when trigger is fired.
|
|
85
|
+
* For example: ['arg1', 'arg2']
|
|
86
|
+
*/
|
|
87
|
+
async create({ name, schema = "public", table, function_schema = "public", function_name, function_args, activation, events, orientation, condition }) {
|
|
88
|
+
const qualifiedTableName = `${ident(schema)}.${ident(table)}`;
|
|
89
|
+
const qualifiedFunctionName = `${ident(function_schema)}.${ident(function_name)}`;
|
|
90
|
+
const triggerEvents = events.join(" OR ");
|
|
91
|
+
const triggerOrientation = orientation ? `FOR EACH ${orientation}` : "";
|
|
92
|
+
const triggerCondition = condition ? `WHEN (${condition})` : "";
|
|
93
|
+
const functionArgs = `${function_args?.map(literal).join(",") ?? ""}`;
|
|
94
|
+
const sql = `CREATE TRIGGER ${ident(name)} ${activation} ${triggerEvents} ON ${qualifiedTableName} ${triggerOrientation} ${triggerCondition} EXECUTE FUNCTION ${qualifiedFunctionName}(${functionArgs});`;
|
|
95
|
+
const { error } = await this.query(sql);
|
|
96
|
+
if (error) return {
|
|
97
|
+
data: null,
|
|
98
|
+
error
|
|
99
|
+
};
|
|
100
|
+
return await this.retrieve({
|
|
101
|
+
name,
|
|
102
|
+
table,
|
|
103
|
+
schema
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async update(id, { name, enabled_mode }) {
|
|
107
|
+
const { data: old, error } = await this.retrieve({ id });
|
|
108
|
+
if (error) return {
|
|
109
|
+
data: null,
|
|
110
|
+
error
|
|
111
|
+
};
|
|
112
|
+
let enabledModeSql = "";
|
|
113
|
+
switch (enabled_mode) {
|
|
114
|
+
case "ORIGIN":
|
|
115
|
+
enabledModeSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ENABLE TRIGGER ${ident(old.name)};`;
|
|
116
|
+
break;
|
|
117
|
+
case "DISABLED":
|
|
118
|
+
enabledModeSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} DISABLE TRIGGER ${ident(old.name)};`;
|
|
119
|
+
break;
|
|
120
|
+
case "REPLICA":
|
|
121
|
+
case "ALWAYS": enabledModeSql = `ALTER TABLE ${ident(old.schema)}.${ident(old.table)} ENABLE ${enabled_mode} TRIGGER ${ident(old.name)};`;
|
|
122
|
+
}
|
|
123
|
+
const nameSql = name && name !== old.name ? `ALTER TRIGGER ${ident(old.name)} ON ${ident(old.schema)}.${ident(old.table)} RENAME TO ${ident(name)};` : "";
|
|
124
|
+
const sql = `BEGIN; ${enabledModeSql}; ${nameSql}; COMMIT;`;
|
|
125
|
+
{
|
|
126
|
+
const { error } = await this.query(sql);
|
|
127
|
+
if (error) return {
|
|
128
|
+
data: null,
|
|
129
|
+
error
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return await this.retrieve({ id });
|
|
133
|
+
}
|
|
134
|
+
async remove(id, { cascade = false } = {}) {
|
|
135
|
+
const { data: triggerRecord, error } = await this.retrieve({ id });
|
|
136
|
+
if (error) return {
|
|
137
|
+
data: null,
|
|
138
|
+
error
|
|
139
|
+
};
|
|
140
|
+
const { name, schema, table } = triggerRecord;
|
|
141
|
+
const sql = `DROP TRIGGER ${ident(name)} ON ${ident(schema)}.${ident(table)} ${cascade ? "CASCADE" : ""};`;
|
|
142
|
+
{
|
|
143
|
+
const { error } = await this.query(sql);
|
|
144
|
+
if (error) return {
|
|
145
|
+
data: null,
|
|
146
|
+
error
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
data: triggerRecord,
|
|
151
|
+
error: null
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
//#endregion
|
|
156
|
+
export { PostgresMetaTriggers as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList } from "./helpers.js";
|
|
3
|
+
import { TYPES_SQL } from "./sql/types.sql.js";
|
|
4
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaTypes.ts
|
|
5
|
+
var PostgresMetaTypes = class {
|
|
6
|
+
constructor(query) {
|
|
7
|
+
this.query = query;
|
|
8
|
+
}
|
|
9
|
+
async list({ includeTableTypes = false, includeArrayTypes = false, includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset } = {}) {
|
|
10
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
11
|
+
const sql = TYPES_SQL({
|
|
12
|
+
schemaFilter,
|
|
13
|
+
limit,
|
|
14
|
+
offset,
|
|
15
|
+
includeTableTypes,
|
|
16
|
+
includeArrayTypes
|
|
17
|
+
});
|
|
18
|
+
return await this.query(sql);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { PostgresMetaTypes as default };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { VERSION_SQL } from "./sql/version.sql.js";
|
|
2
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaVersion.ts
|
|
3
|
+
var PostgresMetaVersion = class {
|
|
4
|
+
constructor(query) {
|
|
5
|
+
this.query = query;
|
|
6
|
+
}
|
|
7
|
+
async retrieve() {
|
|
8
|
+
const { data, error } = await this.query(VERSION_SQL());
|
|
9
|
+
if (error) return {
|
|
10
|
+
data,
|
|
11
|
+
error
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
data: data[0],
|
|
15
|
+
error
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { PostgresMetaVersion as default };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { coalesceRowsToArray, filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { COLUMNS_SQL } from "./sql/columns.sql.js";
|
|
4
|
+
import { VIEWS_SQL } from "./sql/views.sql.js";
|
|
5
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaViews.ts
|
|
6
|
+
var PostgresMetaViews = class {
|
|
7
|
+
constructor(query) {
|
|
8
|
+
this.query = query;
|
|
9
|
+
}
|
|
10
|
+
async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset, includeColumns = true } = {}) {
|
|
11
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
12
|
+
const sql = generateEnrichedViewsSql({
|
|
13
|
+
includeColumns,
|
|
14
|
+
schemaFilter,
|
|
15
|
+
limit,
|
|
16
|
+
offset
|
|
17
|
+
});
|
|
18
|
+
return await this.query(sql);
|
|
19
|
+
}
|
|
20
|
+
async retrieve({ id, name, schema = "public" }) {
|
|
21
|
+
if (id) {
|
|
22
|
+
const idsFilter = filterByValue([id]);
|
|
23
|
+
const sql = generateEnrichedViewsSql({
|
|
24
|
+
includeColumns: true,
|
|
25
|
+
idsFilter
|
|
26
|
+
});
|
|
27
|
+
const { data, error } = await this.query(sql);
|
|
28
|
+
if (error) return {
|
|
29
|
+
data,
|
|
30
|
+
error
|
|
31
|
+
};
|
|
32
|
+
else if (data.length === 0) return {
|
|
33
|
+
data: null,
|
|
34
|
+
error: { message: `Cannot find a view with ID ${id}` }
|
|
35
|
+
};
|
|
36
|
+
else return {
|
|
37
|
+
data: data[0],
|
|
38
|
+
error
|
|
39
|
+
};
|
|
40
|
+
} else if (name) {
|
|
41
|
+
const viewIdentifierFilter = filterByValue([`${schema}.${name}`]);
|
|
42
|
+
const sql = generateEnrichedViewsSql({
|
|
43
|
+
includeColumns: true,
|
|
44
|
+
viewIdentifierFilter
|
|
45
|
+
});
|
|
46
|
+
const { data, error } = await this.query(sql);
|
|
47
|
+
if (error) return {
|
|
48
|
+
data,
|
|
49
|
+
error
|
|
50
|
+
};
|
|
51
|
+
else if (data.length === 0) return {
|
|
52
|
+
data: null,
|
|
53
|
+
error: { message: `Cannot find a view named ${name} in schema ${schema}` }
|
|
54
|
+
};
|
|
55
|
+
else return {
|
|
56
|
+
data: data[0],
|
|
57
|
+
error
|
|
58
|
+
};
|
|
59
|
+
} else return {
|
|
60
|
+
data: null,
|
|
61
|
+
error: { message: "Invalid parameters on view retrieve" }
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const generateEnrichedViewsSql = ({ includeColumns, schemaFilter, idsFilter, viewIdentifierFilter, limit, offset }) => `
|
|
66
|
+
with views as (${VIEWS_SQL({
|
|
67
|
+
schemaFilter,
|
|
68
|
+
limit,
|
|
69
|
+
offset,
|
|
70
|
+
viewIdentifierFilter,
|
|
71
|
+
idsFilter
|
|
72
|
+
})})
|
|
73
|
+
${includeColumns ? `, columns as (${COLUMNS_SQL({
|
|
74
|
+
schemaFilter,
|
|
75
|
+
tableIdentifierFilter: viewIdentifierFilter,
|
|
76
|
+
tableIdFilter: idsFilter
|
|
77
|
+
})})` : ""}
|
|
78
|
+
select
|
|
79
|
+
*
|
|
80
|
+
${includeColumns ? `, ${coalesceRowsToArray("columns", "columns.table_id = views.id")}` : ""}
|
|
81
|
+
from views`;
|
|
82
|
+
//#endregion
|
|
83
|
+
export { PostgresMetaViews as default };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import { parse } from "postgres-array";
|
|
3
|
+
//#region src/vendor/postgres-meta/lib/db.ts
|
|
4
|
+
pg.types.setTypeParser(pg.types.builtins.INT8, (x) => {
|
|
5
|
+
const asNumber = Number(x);
|
|
6
|
+
if (Number.isSafeInteger(asNumber)) return asNumber;
|
|
7
|
+
else return x;
|
|
8
|
+
});
|
|
9
|
+
pg.types.setTypeParser(pg.types.builtins.DATE, (x) => x);
|
|
10
|
+
pg.types.setTypeParser(pg.types.builtins.INTERVAL, (x) => x);
|
|
11
|
+
pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, (x) => x);
|
|
12
|
+
pg.types.setTypeParser(pg.types.builtins.TIMESTAMPTZ, (x) => x);
|
|
13
|
+
pg.types.setTypeParser(1115, parse);
|
|
14
|
+
pg.types.setTypeParser(1182, parse);
|
|
15
|
+
pg.types.setTypeParser(1185, parse);
|
|
16
|
+
pg.types.setTypeParser(600, (x) => x);
|
|
17
|
+
pg.types.setTypeParser(1017, (x) => x);
|
|
18
|
+
const poolerQueryHandleError = (pgpool, sql, parameters) => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
let rejected = false;
|
|
21
|
+
const connectionErrorHandler = (err) => {
|
|
22
|
+
if (!rejected) setTimeout(() => {
|
|
23
|
+
rejected = true;
|
|
24
|
+
return reject(err);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
pgpool.once("error", connectionErrorHandler);
|
|
28
|
+
pgpool.query(sql, parameters).then((results) => {
|
|
29
|
+
if (!rejected) return resolve(results);
|
|
30
|
+
}).catch((err) => {
|
|
31
|
+
if (!rejected) {
|
|
32
|
+
rejected = true;
|
|
33
|
+
return reject(err);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
const init = (config) => {
|
|
39
|
+
if (config.connectionString) {
|
|
40
|
+
const u = new URL(config.connectionString);
|
|
41
|
+
const sslmode = u.searchParams.get("sslmode");
|
|
42
|
+
u.searchParams.delete("sslmode");
|
|
43
|
+
u.searchParams.delete("sslca");
|
|
44
|
+
u.searchParams.delete("sslkey");
|
|
45
|
+
u.searchParams.delete("sslcert");
|
|
46
|
+
u.searchParams.delete("sslrootcert");
|
|
47
|
+
config.connectionString = u.toString();
|
|
48
|
+
if (sslmode === null) {} else if (sslmode === "disable") config.ssl = false;
|
|
49
|
+
else {
|
|
50
|
+
if (typeof config.ssl !== "object") config.ssl = {};
|
|
51
|
+
config.ssl.rejectUnauthorized = sslmode === "verify-full";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let pool = new pg.Pool(config);
|
|
55
|
+
return {
|
|
56
|
+
async query(sql, { statementQueryTimeout, parameters } = {}) {
|
|
57
|
+
const statementTimeoutQueryPrefix = statementQueryTimeout ? `SET statement_timeout='${statementQueryTimeout}s'; SET idle_session_timeout='${statementQueryTimeout}s';` : "";
|
|
58
|
+
const sqlWithStatementTimeout = `${statementTimeoutQueryPrefix}${sql}`;
|
|
59
|
+
try {
|
|
60
|
+
if (!pool) {
|
|
61
|
+
const transientPool = new pg.Pool(config);
|
|
62
|
+
let res = await poolerQueryHandleError(transientPool, sqlWithStatementTimeout, parameters);
|
|
63
|
+
if (Array.isArray(res)) res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] };
|
|
64
|
+
await transientPool.end();
|
|
65
|
+
return {
|
|
66
|
+
data: res.rows,
|
|
67
|
+
error: null
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
let res = await poolerQueryHandleError(pool, sqlWithStatementTimeout, parameters);
|
|
71
|
+
if (Array.isArray(res)) res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] };
|
|
72
|
+
return {
|
|
73
|
+
data: res.rows,
|
|
74
|
+
error: null
|
|
75
|
+
};
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error.constructor.name === "DatabaseError") {
|
|
78
|
+
let formattedError = "";
|
|
79
|
+
if (error.severity) formattedError += `${error.severity}: `;
|
|
80
|
+
if (error.code) formattedError += `${error.code}: `;
|
|
81
|
+
if (error.message) formattedError += error.message;
|
|
82
|
+
formattedError += "\n";
|
|
83
|
+
if (error.position) {
|
|
84
|
+
const position = Number(error.position) - 1 - statementTimeoutQueryPrefix.length;
|
|
85
|
+
error.position = `${position + 1}`;
|
|
86
|
+
let line = "";
|
|
87
|
+
let lineNumber = 0;
|
|
88
|
+
let lineOffset = 0;
|
|
89
|
+
const lines = sql.split("\n");
|
|
90
|
+
let currentOffset = 0;
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
if (currentOffset + lines[i].length > position) {
|
|
93
|
+
line = lines[i];
|
|
94
|
+
lineNumber = i + 1;
|
|
95
|
+
lineOffset = position - currentOffset;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
currentOffset += lines[i].length + 1;
|
|
99
|
+
}
|
|
100
|
+
formattedError += `LINE ${lineNumber}: ${line}\n${" ".repeat(5 + lineNumber.toString().length + 2 + lineOffset)}^\n`;
|
|
101
|
+
}
|
|
102
|
+
if (error.detail) formattedError += `DETAIL: ${error.detail}\n`;
|
|
103
|
+
if (error.hint) formattedError += `HINT: ${error.hint}\n`;
|
|
104
|
+
if (error.internalQuery) formattedError += `QUERY: ${error.internalQuery}\n`;
|
|
105
|
+
if (error.where) formattedError += `CONTEXT: ${error.where}\n`;
|
|
106
|
+
return {
|
|
107
|
+
data: null,
|
|
108
|
+
error: {
|
|
109
|
+
...error,
|
|
110
|
+
message: error.message,
|
|
111
|
+
formattedError
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
return {
|
|
117
|
+
data: null,
|
|
118
|
+
error: {
|
|
119
|
+
code: error.code,
|
|
120
|
+
message: error.message
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
} finally {
|
|
124
|
+
try {
|
|
125
|
+
await this.end.bind(this);
|
|
126
|
+
} catch (_endError) {
|
|
127
|
+
console.error("Failed to end the connection on error: ", {
|
|
128
|
+
this: this,
|
|
129
|
+
end: this.end
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
async end() {
|
|
136
|
+
try {
|
|
137
|
+
const _pool = pool;
|
|
138
|
+
pool = null;
|
|
139
|
+
if (_pool) await _pool.end();
|
|
140
|
+
} catch (endError) {
|
|
141
|
+
console.error("Failed ending connection pool", endError);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
//#endregion
|
|
147
|
+
export { init };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
//#region src/vendor/postgres-meta/lib/generators.ts
|
|
2
|
+
async function getGeneratorMetadata(pgMeta, filters = {
|
|
3
|
+
includedSchemas: [],
|
|
4
|
+
excludedSchemas: []
|
|
5
|
+
}) {
|
|
6
|
+
const includedSchemas = filters.includedSchemas ?? [];
|
|
7
|
+
const excludedSchemas = filters.excludedSchemas ?? [];
|
|
8
|
+
const { data: schemas, error: schemasError } = await pgMeta.schemas.list({
|
|
9
|
+
includeSystemSchemas: false,
|
|
10
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
11
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0
|
|
12
|
+
});
|
|
13
|
+
if (schemasError) return {
|
|
14
|
+
data: null,
|
|
15
|
+
error: schemasError
|
|
16
|
+
};
|
|
17
|
+
const { data: tables, error: tablesError } = await pgMeta.tables.list({
|
|
18
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
19
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
20
|
+
includeColumns: false
|
|
21
|
+
});
|
|
22
|
+
if (tablesError) return {
|
|
23
|
+
data: null,
|
|
24
|
+
error: tablesError
|
|
25
|
+
};
|
|
26
|
+
const { data: foreignTables, error: foreignTablesError } = await pgMeta.foreignTables.list({
|
|
27
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
28
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
29
|
+
includeColumns: false
|
|
30
|
+
});
|
|
31
|
+
if (foreignTablesError) return {
|
|
32
|
+
data: null,
|
|
33
|
+
error: foreignTablesError
|
|
34
|
+
};
|
|
35
|
+
const { data: views, error: viewsError } = await pgMeta.views.list({
|
|
36
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
37
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
38
|
+
includeColumns: false
|
|
39
|
+
});
|
|
40
|
+
if (viewsError) return {
|
|
41
|
+
data: null,
|
|
42
|
+
error: viewsError
|
|
43
|
+
};
|
|
44
|
+
const { data: materializedViews, error: materializedViewsError } = await pgMeta.materializedViews.list({
|
|
45
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
46
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
47
|
+
includeColumns: false
|
|
48
|
+
});
|
|
49
|
+
if (materializedViewsError) return {
|
|
50
|
+
data: null,
|
|
51
|
+
error: materializedViewsError
|
|
52
|
+
};
|
|
53
|
+
const { data: columns, error: columnsError } = await pgMeta.columns.list({
|
|
54
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
55
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
56
|
+
includeSystemSchemas: false
|
|
57
|
+
});
|
|
58
|
+
if (columnsError) return {
|
|
59
|
+
data: null,
|
|
60
|
+
error: columnsError
|
|
61
|
+
};
|
|
62
|
+
const { data: relationships, error: relationshipsError } = await pgMeta.relationships.list({
|
|
63
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
64
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
65
|
+
includeSystemSchemas: false
|
|
66
|
+
});
|
|
67
|
+
if (relationshipsError) return {
|
|
68
|
+
data: null,
|
|
69
|
+
error: relationshipsError
|
|
70
|
+
};
|
|
71
|
+
const { data: functions, error: functionsError } = await pgMeta.functions.list({
|
|
72
|
+
includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
|
|
73
|
+
excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
|
|
74
|
+
includeSystemSchemas: false
|
|
75
|
+
});
|
|
76
|
+
if (functionsError) return {
|
|
77
|
+
data: null,
|
|
78
|
+
error: functionsError
|
|
79
|
+
};
|
|
80
|
+
const { data: types, error: typesError } = await pgMeta.types.list({
|
|
81
|
+
includeTableTypes: true,
|
|
82
|
+
includeArrayTypes: true,
|
|
83
|
+
includeSystemSchemas: true
|
|
84
|
+
});
|
|
85
|
+
if (typesError) return {
|
|
86
|
+
data: null,
|
|
87
|
+
error: typesError
|
|
88
|
+
};
|
|
89
|
+
await pgMeta.end();
|
|
90
|
+
return {
|
|
91
|
+
data: {
|
|
92
|
+
schemas: schemas.filter(({ name }) => !excludedSchemas.includes(name) && (includedSchemas.length === 0 || includedSchemas.includes(name))),
|
|
93
|
+
tables,
|
|
94
|
+
foreignTables,
|
|
95
|
+
views,
|
|
96
|
+
materializedViews,
|
|
97
|
+
columns,
|
|
98
|
+
relationships,
|
|
99
|
+
functions: functions.filter(({ return_type }) => !["trigger", "event_trigger"].includes(return_type)),
|
|
100
|
+
types
|
|
101
|
+
},
|
|
102
|
+
error: null
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { getGeneratorMetadata };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { literal } from "pg-format";
|
|
2
|
+
//#region src/vendor/postgres-meta/lib/helpers.ts
|
|
3
|
+
const coalesceRowsToArray = (source, filter) => {
|
|
4
|
+
return `
|
|
5
|
+
COALESCE(
|
|
6
|
+
(
|
|
7
|
+
SELECT
|
|
8
|
+
array_agg(row_to_json(${source})) FILTER (WHERE ${filter})
|
|
9
|
+
FROM
|
|
10
|
+
${source}
|
|
11
|
+
),
|
|
12
|
+
'{}'
|
|
13
|
+
) AS ${source}`;
|
|
14
|
+
};
|
|
15
|
+
const filterByList = (include, exclude, defaultExclude) => {
|
|
16
|
+
if (defaultExclude) exclude = defaultExclude.concat(exclude ?? []);
|
|
17
|
+
if (include?.length) return `IN (${include.map(literal).join(",")})`;
|
|
18
|
+
else if (exclude?.length) return `NOT IN (${exclude.map(literal).join(",")})`;
|
|
19
|
+
return "";
|
|
20
|
+
};
|
|
21
|
+
const filterByValue = (ids) => {
|
|
22
|
+
if (ids?.length) return `IN (${ids.map(literal).join(",")})`;
|
|
23
|
+
return "";
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { coalesceRowsToArray, filterByList, filterByValue };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PostgresMeta } from "./PostgresMeta.js";
|