prostgles-server 3.0.131 → 3.0.133
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/dist/Prostgles.d.ts +6 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +6 -2
- package/dist/Prostgles.js.map +1 -1
- package/dist/TableConfig/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig/TableConfig.js +81 -147
- package/dist/TableConfig/TableConfig.js.map +1 -1
- package/dist/TableConfig/getColumnDefinitionQuery.d.ts +3 -19
- package/dist/TableConfig/getColumnDefinitionQuery.d.ts.map +1 -1
- package/dist/TableConfig/getColumnDefinitionQuery.js +5 -38
- package/dist/TableConfig/getColumnDefinitionQuery.js.map +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.d.ts +27 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.d.ts.map +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.js +40 -6
- package/dist/TableConfig/getConstraintDefinitionQueries.js.map +1 -1
- package/dist/TableConfig/getFutureTableSchema.d.ts +15 -0
- package/dist/TableConfig/getFutureTableSchema.d.ts.map +1 -0
- package/dist/TableConfig/getFutureTableSchema.js +51 -0
- package/dist/TableConfig/getFutureTableSchema.js.map +1 -0
- package/dist/TableConfig/getTableColumnQueries.d.ts +16 -0
- package/dist/TableConfig/getTableColumnQueries.d.ts.map +1 -0
- package/dist/TableConfig/getTableColumnQueries.js +108 -0
- package/dist/TableConfig/getTableColumnQueries.js.map +1 -0
- package/lib/Prostgles.d.ts +6 -1
- package/lib/Prostgles.d.ts.map +1 -1
- package/lib/Prostgles.js +6 -2
- package/lib/Prostgles.ts +12 -3
- package/lib/TableConfig/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig/TableConfig.js +81 -147
- package/lib/TableConfig/TableConfig.ts +94 -154
- package/lib/TableConfig/getColumnDefinitionQuery.d.ts +3 -19
- package/lib/TableConfig/getColumnDefinitionQuery.d.ts.map +1 -1
- package/lib/TableConfig/getColumnDefinitionQuery.js +5 -38
- package/lib/TableConfig/getColumnDefinitionQuery.ts +4 -46
- package/lib/TableConfig/getConstraintDefinitionQueries.d.ts +27 -1
- package/lib/TableConfig/getConstraintDefinitionQueries.d.ts.map +1 -1
- package/lib/TableConfig/getConstraintDefinitionQueries.js +40 -6
- package/lib/TableConfig/getConstraintDefinitionQueries.ts +64 -6
- package/lib/TableConfig/getFutureTableSchema.d.ts +15 -0
- package/lib/TableConfig/getFutureTableSchema.d.ts.map +1 -0
- package/lib/TableConfig/getFutureTableSchema.js +50 -0
- package/lib/TableConfig/getFutureTableSchema.ts +73 -0
- package/lib/TableConfig/getTableColumnQueries.d.ts +16 -0
- package/lib/TableConfig/getTableColumnQueries.d.ts.map +1 -0
- package/lib/TableConfig/getTableColumnQueries.js +107 -0
- package/lib/TableConfig/getTableColumnQueries.ts +130 -0
- package/package.json +1 -1
- package/tests/client/PID.txt +1 -1
- package/tests/config_test/index.ts +1 -2
- package/tests/config_test/init.sql +1 -8
- package/tests/server/DBoGenerated.d.ts +12 -2
- package/tests/server/index.js +5 -1
- package/tests/server/index.ts +5 -1
- package/tests/server/init.sql +1 -7
- package/tests/server/package-lock.json +1 -1
- package/tests/server/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTableColumns = exports.
|
|
3
|
+
exports.getTableColumns = exports.getColumnDefinitionQuery = void 0;
|
|
4
4
|
const prostgles_types_1 = require("prostgles-types");
|
|
5
5
|
const PubSubManager_1 = require("../PubSubManager/PubSubManager");
|
|
6
6
|
const validate_jsonb_schema_sql_1 = require("../JSONBValidation/validate_jsonb_schema_sql");
|
|
7
|
+
const getConstraintDefinitionQueries_1 = require("./getConstraintDefinitionQueries");
|
|
7
8
|
/**
|
|
8
9
|
* Column create statement for a given config
|
|
9
10
|
*/
|
|
@@ -62,7 +63,7 @@ const getColumnDefinitionQuery = async ({ colConf: colConfRaw, column, db, table
|
|
|
62
63
|
const namePreffix = 'prostgles_jsonb_';
|
|
63
64
|
const { val: nameEnding } = await db.one("SELECT MD5( ${table} || ${column} || ${schema}) as val", { table: table, column, schema: jsonbSchemaStr });
|
|
64
65
|
const constraintName = namePreffix + nameEnding;
|
|
65
|
-
const colConstraints = await (0,
|
|
66
|
+
const colConstraints = await (0, getConstraintDefinitionQueries_1.getColConstraints)({ db, table, column });
|
|
66
67
|
const existingNonMatchingConstraints = colConstraints.filter(c => c.name.startsWith(namePreffix) && c.name !== constraintName);
|
|
67
68
|
for await (const oldCons of existingNonMatchingConstraints) {
|
|
68
69
|
await db.any(`ALTER TABLE ${(0, prostgles_types_1.asName)(table)} DROP CONSTRAINT ${(0, prostgles_types_1.asName)(oldCons.name)};`);
|
|
@@ -82,41 +83,7 @@ const getColumnDefinitionQuery = async ({ colConf: colConfRaw, column, db, table
|
|
|
82
83
|
}
|
|
83
84
|
};
|
|
84
85
|
exports.getColumnDefinitionQuery = getColumnDefinitionQuery;
|
|
85
|
-
const
|
|
86
|
-
let query = `
|
|
87
|
-
SELECT *
|
|
88
|
-
FROM (
|
|
89
|
-
SELECT distinct c.conname as name, c.contype as type,
|
|
90
|
-
pg_get_constraintdef(c.oid) as definition,
|
|
91
|
-
nsp.nspname as schema,
|
|
92
|
-
(SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
|
|
93
|
-
(SELECT array_agg(attname::text) from pg_attribute
|
|
94
|
-
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
|
|
95
|
-
-- (SELECT array_agg(attname::text) from pg_attribute
|
|
96
|
-
-- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
|
|
97
|
-
-- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
|
|
98
|
-
FROM pg_catalog.pg_constraint c
|
|
99
|
-
INNER JOIN pg_catalog.pg_class rel
|
|
100
|
-
ON rel.oid = c.conrelid
|
|
101
|
-
INNER JOIN pg_catalog.pg_namespace nsp
|
|
102
|
-
ON nsp.oid = connamespace
|
|
103
|
-
) t
|
|
104
|
-
WHERE TRUE
|
|
105
|
-
`;
|
|
106
|
-
if (table)
|
|
107
|
-
query += `\nAND "table" = ${(0, PubSubManager_1.asValue)(table)}`;
|
|
108
|
-
if (column)
|
|
109
|
-
query += `\nAND cols @> ARRAY[${(0, PubSubManager_1.asValue)(column)}]`;
|
|
110
|
-
if (types?.length)
|
|
111
|
-
query += `\nAND type IN (${types.map(v => (0, PubSubManager_1.asValue)(v)).join(", ")})`;
|
|
112
|
-
return query;
|
|
113
|
-
};
|
|
114
|
-
exports.getColConstraintsQuery = getColConstraintsQuery;
|
|
115
|
-
const getColConstraints = ({ db, column, table, types }) => {
|
|
116
|
-
return db.manyOrNone((0, exports.getColConstraintsQuery)({ column, table, types }));
|
|
117
|
-
};
|
|
118
|
-
exports.getColConstraints = getColConstraints;
|
|
119
|
-
const getTableColumns = ({ db, tableName }) => {
|
|
86
|
+
const getTableColumns = ({ db, table }) => {
|
|
120
87
|
return db.manyOrNone(`
|
|
121
88
|
SELECT table_name,
|
|
122
89
|
table_schema, column_name,
|
|
@@ -124,6 +91,6 @@ const getTableColumns = ({ db, tableName }) => {
|
|
|
124
91
|
is_nullable = 'YES' as nullable
|
|
125
92
|
FROM information_schema.columns
|
|
126
93
|
WHERE table_name = $1
|
|
127
|
-
`, [
|
|
94
|
+
`, [table]);
|
|
128
95
|
};
|
|
129
96
|
exports.getTableColumns = getTableColumns;
|
|
@@ -4,6 +4,7 @@ import { asValue } from "../PubSubManager/PubSubManager";
|
|
|
4
4
|
import { VALIDATE_SCHEMA_FUNCNAME } from "../JSONBValidation/validate_jsonb_schema_sql";
|
|
5
5
|
import { BaseColumnTypes, ColumnConfig } from "./TableConfig";
|
|
6
6
|
import pgPromise from "pg-promise";
|
|
7
|
+
import { getColConstraints } from "./getConstraintDefinitionQueries";
|
|
7
8
|
|
|
8
9
|
type Args = {
|
|
9
10
|
column: string;
|
|
@@ -98,50 +99,7 @@ export const getColumnDefinitionQuery = async ({ colConf: colConfRaw, column, db
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
name: string;
|
|
103
|
-
table: string;
|
|
104
|
-
type: "c" | "p" | "u" | "f";
|
|
105
|
-
cols: Array<string>;
|
|
106
|
-
definition: string;
|
|
107
|
-
schema: string;
|
|
108
|
-
}
|
|
109
|
-
type ColConstraintsArgs = {
|
|
110
|
-
db: DB | pgPromise.ITask<{}>;
|
|
111
|
-
table?: string;
|
|
112
|
-
column?: string;
|
|
113
|
-
types?: ColConstraint["type"][];
|
|
114
|
-
}
|
|
115
|
-
export const getColConstraintsQuery = ({ column, table, types }: Omit<ColConstraintsArgs, "db">) => {
|
|
116
|
-
let query = `
|
|
117
|
-
SELECT *
|
|
118
|
-
FROM (
|
|
119
|
-
SELECT distinct c.conname as name, c.contype as type,
|
|
120
|
-
pg_get_constraintdef(c.oid) as definition,
|
|
121
|
-
nsp.nspname as schema,
|
|
122
|
-
(SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
|
|
123
|
-
(SELECT array_agg(attname::text) from pg_attribute
|
|
124
|
-
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
|
|
125
|
-
-- (SELECT array_agg(attname::text) from pg_attribute
|
|
126
|
-
-- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
|
|
127
|
-
-- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
|
|
128
|
-
FROM pg_catalog.pg_constraint c
|
|
129
|
-
INNER JOIN pg_catalog.pg_class rel
|
|
130
|
-
ON rel.oid = c.conrelid
|
|
131
|
-
INNER JOIN pg_catalog.pg_namespace nsp
|
|
132
|
-
ON nsp.oid = connamespace
|
|
133
|
-
) t
|
|
134
|
-
WHERE TRUE
|
|
135
|
-
`;
|
|
136
|
-
if (table) query += `\nAND "table" = ${asValue(table)}`;
|
|
137
|
-
if (column) query += `\nAND cols @> ARRAY[${asValue(column)}]`;
|
|
138
|
-
if (types?.length) query += `\nAND type IN (${types.map(v => asValue(v)).join(", ")})`;
|
|
139
|
-
return query;
|
|
140
|
-
}
|
|
141
|
-
export const getColConstraints = ({ db, column, table, types }: ColConstraintsArgs ): Promise<ColConstraint[]> => {
|
|
142
|
-
|
|
143
|
-
return db.manyOrNone(getColConstraintsQuery({ column, table, types }));
|
|
144
|
-
}
|
|
102
|
+
|
|
145
103
|
export type ColumnMinimalInfo = {
|
|
146
104
|
table_name: string;
|
|
147
105
|
table_schema: string;
|
|
@@ -150,7 +108,7 @@ export type ColumnMinimalInfo = {
|
|
|
150
108
|
udt_name: string;
|
|
151
109
|
nullable: boolean;
|
|
152
110
|
};
|
|
153
|
-
export const getTableColumns = ({ db,
|
|
111
|
+
export const getTableColumns = ({ db, table }: { db: DB | pgPromise.ITask<{}>; table: string;}): Promise<ColumnMinimalInfo[]> => {
|
|
154
112
|
return db.manyOrNone(`
|
|
155
113
|
SELECT table_name,
|
|
156
114
|
table_schema, column_name,
|
|
@@ -158,5 +116,5 @@ export const getTableColumns = ({ db, tableName }: { db: DB; tableName: string;}
|
|
|
158
116
|
is_nullable = 'YES' as nullable
|
|
159
117
|
FROM information_schema.columns
|
|
160
118
|
WHERE table_name = $1
|
|
161
|
-
`, [
|
|
119
|
+
`, [table]);
|
|
162
120
|
}
|
|
@@ -1,8 +1,34 @@
|
|
|
1
|
+
import pgPromise from "pg-promise";
|
|
2
|
+
import { DB } from "../Prostgles";
|
|
1
3
|
import { TableConfig } from "./TableConfig";
|
|
2
4
|
type Args = {
|
|
3
5
|
tableName: string;
|
|
4
6
|
tableConf: TableConfig[string];
|
|
5
7
|
};
|
|
6
|
-
export
|
|
8
|
+
export type ConstraintDef = {
|
|
9
|
+
/**
|
|
10
|
+
* Named constraints are used to show a relevant error message
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
content: string;
|
|
14
|
+
alterQuery: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const getConstraintDefinitionQueries: ({ tableConf, tableName }: Args) => ConstraintDef[] | undefined;
|
|
17
|
+
export type ColConstraint = {
|
|
18
|
+
name: string;
|
|
19
|
+
table: string;
|
|
20
|
+
type: "c" | "p" | "u" | "f";
|
|
21
|
+
cols: Array<string>;
|
|
22
|
+
definition: string;
|
|
23
|
+
schema: string;
|
|
24
|
+
};
|
|
25
|
+
type ColConstraintsArgs = {
|
|
26
|
+
db: DB | pgPromise.ITask<{}>;
|
|
27
|
+
table?: string;
|
|
28
|
+
column?: string;
|
|
29
|
+
types?: ColConstraint["type"][];
|
|
30
|
+
};
|
|
31
|
+
export declare const getColConstraintsQuery: ({ column, table, types }: Omit<ColConstraintsArgs, "db">) => string;
|
|
32
|
+
export declare const getColConstraints: ({ db, column, table, types }: ColConstraintsArgs) => Promise<ColConstraint[]>;
|
|
7
33
|
export {};
|
|
8
34
|
//# sourceMappingURL=getConstraintDefinitionQueries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getConstraintDefinitionQueries.d.ts","sourceRoot":"","sources":["getConstraintDefinitionQueries.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getConstraintDefinitionQueries.d.ts","sourceRoot":"","sources":["getConstraintDefinitionQueries.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAE/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,8BAA8B,6BAA8B,IAAI,KAAG,aAAa,EAAE,GAAG,SA6BjG,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC5B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAA;AACD,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;CACjC,CAAA;AACD,eAAO,MAAM,sBAAsB,6BAA8B,KAAK,kBAAkB,EAAE,IAAI,CAAC,WAyB9F,CAAA;AACD,eAAO,MAAM,iBAAiB,iCAAkC,kBAAkB,KAAI,QAAQ,aAAa,EAAE,CAG5G,CAAA"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getConstraintDefinitionQueries = void 0;
|
|
3
|
+
exports.getColConstraints = exports.getColConstraintsQuery = exports.getConstraintDefinitionQueries = void 0;
|
|
4
4
|
const prostgles_types_1 = require("prostgles-types");
|
|
5
|
+
const PubSubManager_1 = require("../PubSubManager/PubSubManager");
|
|
5
6
|
const getConstraintDefinitionQueries = ({ tableConf, tableName }) => {
|
|
6
7
|
if ("constraints" in tableConf && tableConf.constraints) {
|
|
7
8
|
const { constraints } = tableConf;
|
|
8
9
|
if (!constraints) {
|
|
9
10
|
return undefined;
|
|
10
11
|
}
|
|
11
|
-
const queries = [];
|
|
12
12
|
if (Array.isArray(constraints)) {
|
|
13
|
-
return constraints.map(c => `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)} ADD ${c}`);
|
|
13
|
+
return constraints.map(c => ({ content: c, alterQuery: `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)} ADD ${c}` }));
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
16
16
|
const constraintNames = (0, prostgles_types_1.getKeys)(tableConf.constraints);
|
|
17
|
-
constraintNames.map(constraintName => {
|
|
17
|
+
return constraintNames.map(constraintName => {
|
|
18
18
|
const _cnstr = constraints[constraintName];
|
|
19
19
|
const constraintDef = typeof _cnstr === "string" ? _cnstr : `${_cnstr.type} (${_cnstr.content})`;
|
|
20
20
|
/** Drop constraints with the same name */
|
|
@@ -22,10 +22,44 @@ const getConstraintDefinitionQueries = ({ tableConf, tableName }) => {
|
|
|
22
22
|
// if(existingConstraint){
|
|
23
23
|
// if(canDrop) queries.push(`ALTER TABLE ${asName(tableName)} DROP CONSTRAINT ${asName(constraintName)};`);
|
|
24
24
|
// }
|
|
25
|
-
|
|
25
|
+
const alterQuery = `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)} ADD CONSTRAINT ${(0, prostgles_types_1.asName)(constraintName)} ${constraintDef};`;
|
|
26
|
+
return { name: constraintName, alterQuery, content: constraintDef };
|
|
26
27
|
});
|
|
27
|
-
return queries;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
exports.getConstraintDefinitionQueries = getConstraintDefinitionQueries;
|
|
32
|
+
const getColConstraintsQuery = ({ column, table, types }) => {
|
|
33
|
+
let query = `
|
|
34
|
+
SELECT *
|
|
35
|
+
FROM (
|
|
36
|
+
SELECT distinct c.conname as name, c.contype as type,
|
|
37
|
+
pg_get_constraintdef(c.oid) as definition,
|
|
38
|
+
nsp.nspname as schema,
|
|
39
|
+
(SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
|
|
40
|
+
(SELECT array_agg(attname::text) from pg_attribute
|
|
41
|
+
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
|
|
42
|
+
-- (SELECT array_agg(attname::text) from pg_attribute
|
|
43
|
+
-- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
|
|
44
|
+
-- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
|
|
45
|
+
FROM pg_catalog.pg_constraint c
|
|
46
|
+
INNER JOIN pg_catalog.pg_class rel
|
|
47
|
+
ON rel.oid = c.conrelid
|
|
48
|
+
INNER JOIN pg_catalog.pg_namespace nsp
|
|
49
|
+
ON nsp.oid = connamespace
|
|
50
|
+
) t
|
|
51
|
+
WHERE TRUE
|
|
52
|
+
`;
|
|
53
|
+
if (table)
|
|
54
|
+
query += `\nAND "table" = ${(0, PubSubManager_1.asValue)(table)}`;
|
|
55
|
+
if (column)
|
|
56
|
+
query += `\nAND cols @> ARRAY[${(0, PubSubManager_1.asValue)(column)}]`;
|
|
57
|
+
if (types?.length)
|
|
58
|
+
query += `\nAND type IN (${types.map(v => (0, PubSubManager_1.asValue)(v)).join(", ")})`;
|
|
59
|
+
return query;
|
|
60
|
+
};
|
|
61
|
+
exports.getColConstraintsQuery = getColConstraintsQuery;
|
|
62
|
+
const getColConstraints = ({ db, column, table, types }) => {
|
|
63
|
+
return db.manyOrNone((0, exports.getColConstraintsQuery)({ column, table, types }));
|
|
64
|
+
};
|
|
65
|
+
exports.getColConstraints = getColConstraints;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import pgPromise from "pg-promise";
|
|
1
2
|
import { asName, getKeys } from "prostgles-types";
|
|
3
|
+
import { DB } from "../Prostgles";
|
|
4
|
+
import { asValue } from "../PubSubManager/PubSubManager";
|
|
2
5
|
import { TableConfig } from "./TableConfig";
|
|
3
6
|
|
|
4
7
|
type Args = {
|
|
@@ -7,19 +10,28 @@ type Args = {
|
|
|
7
10
|
// tableConf: BaseTableDefinition<LANG_IDS> & (TableDefinition<LANG_IDS> | LookupTableDefinition<LANG_IDS>)
|
|
8
11
|
};
|
|
9
12
|
|
|
10
|
-
export
|
|
13
|
+
export type ConstraintDef = {
|
|
14
|
+
/**
|
|
15
|
+
* Named constraints are used to show a relevant error message
|
|
16
|
+
*/
|
|
17
|
+
name?: string;
|
|
18
|
+
content: string;
|
|
19
|
+
alterQuery: string;
|
|
20
|
+
};
|
|
21
|
+
export const getConstraintDefinitionQueries = ({ tableConf, tableName }: Args): ConstraintDef[] | undefined => {
|
|
11
22
|
|
|
12
23
|
if ("constraints" in tableConf && tableConf.constraints) {
|
|
13
24
|
const { constraints } = tableConf;
|
|
14
25
|
if(!constraints){
|
|
15
26
|
return undefined;
|
|
16
27
|
}
|
|
17
|
-
|
|
28
|
+
|
|
18
29
|
if(Array.isArray(constraints)){
|
|
19
|
-
return constraints.map(c => `ALTER TABLE ${asName(tableName)} ADD ${c}`);
|
|
30
|
+
return constraints.map(c => ({ content: c, alterQuery: `ALTER TABLE ${asName(tableName)} ADD ${c}`}));
|
|
31
|
+
|
|
20
32
|
} else {
|
|
21
33
|
const constraintNames = getKeys(tableConf.constraints);
|
|
22
|
-
constraintNames.map(constraintName => {
|
|
34
|
+
return constraintNames.map(constraintName => {
|
|
23
35
|
const _cnstr = constraints[constraintName];
|
|
24
36
|
const constraintDef = typeof _cnstr === "string"? _cnstr : `${_cnstr.type} (${_cnstr.content})`;
|
|
25
37
|
|
|
@@ -29,9 +41,55 @@ export const getConstraintDefinitionQueries = ({ tableConf, tableName }: Args):
|
|
|
29
41
|
// if(canDrop) queries.push(`ALTER TABLE ${asName(tableName)} DROP CONSTRAINT ${asName(constraintName)};`);
|
|
30
42
|
// }
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
const alterQuery = `ALTER TABLE ${asName(tableName)} ADD CONSTRAINT ${asName(constraintName)} ${constraintDef};`;
|
|
45
|
+
|
|
46
|
+
return { name: constraintName, alterQuery, content: constraintDef };
|
|
33
47
|
});
|
|
34
|
-
return queries;
|
|
35
48
|
}
|
|
36
49
|
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ColConstraint = {
|
|
53
|
+
name: string;
|
|
54
|
+
table: string;
|
|
55
|
+
type: "c" | "p" | "u" | "f";
|
|
56
|
+
cols: Array<string>;
|
|
57
|
+
definition: string;
|
|
58
|
+
schema: string;
|
|
59
|
+
}
|
|
60
|
+
type ColConstraintsArgs = {
|
|
61
|
+
db: DB | pgPromise.ITask<{}>;
|
|
62
|
+
table?: string;
|
|
63
|
+
column?: string;
|
|
64
|
+
types?: ColConstraint["type"][];
|
|
65
|
+
}
|
|
66
|
+
export const getColConstraintsQuery = ({ column, table, types }: Omit<ColConstraintsArgs, "db">) => {
|
|
67
|
+
let query = `
|
|
68
|
+
SELECT *
|
|
69
|
+
FROM (
|
|
70
|
+
SELECT distinct c.conname as name, c.contype as type,
|
|
71
|
+
pg_get_constraintdef(c.oid) as definition,
|
|
72
|
+
nsp.nspname as schema,
|
|
73
|
+
(SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
|
|
74
|
+
(SELECT array_agg(attname::text) from pg_attribute
|
|
75
|
+
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
|
|
76
|
+
-- (SELECT array_agg(attname::text) from pg_attribute
|
|
77
|
+
-- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
|
|
78
|
+
-- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
|
|
79
|
+
FROM pg_catalog.pg_constraint c
|
|
80
|
+
INNER JOIN pg_catalog.pg_class rel
|
|
81
|
+
ON rel.oid = c.conrelid
|
|
82
|
+
INNER JOIN pg_catalog.pg_namespace nsp
|
|
83
|
+
ON nsp.oid = connamespace
|
|
84
|
+
) t
|
|
85
|
+
WHERE TRUE
|
|
86
|
+
`;
|
|
87
|
+
if (table) query += `\nAND "table" = ${asValue(table)}`;
|
|
88
|
+
if (column) query += `\nAND cols @> ARRAY[${asValue(column)}]`;
|
|
89
|
+
if (types?.length) query += `\nAND type IN (${types.map(v => asValue(v)).join(", ")})`;
|
|
90
|
+
return query;
|
|
91
|
+
}
|
|
92
|
+
export const getColConstraints = ({ db, column, table, types }: ColConstraintsArgs ): Promise<ColConstraint[]> => {
|
|
93
|
+
|
|
94
|
+
return db.manyOrNone(getColConstraintsQuery({ column, table, types }));
|
|
37
95
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DB } from "../Prostgles";
|
|
2
|
+
import { ColumnMinimalInfo } from "./getColumnDefinitionQuery";
|
|
3
|
+
import { ColConstraint, ConstraintDef } from "./getConstraintDefinitionQueries";
|
|
4
|
+
type Args = {
|
|
5
|
+
db: DB;
|
|
6
|
+
columnDefs: string[];
|
|
7
|
+
tableName: string;
|
|
8
|
+
constraintDefs?: ConstraintDef[];
|
|
9
|
+
};
|
|
10
|
+
export declare const getFutureTableSchema: ({ columnDefs, tableName, constraintDefs, db }: Args) => Promise<{
|
|
11
|
+
constraints: ColConstraint[];
|
|
12
|
+
cols: ColumnMinimalInfo[];
|
|
13
|
+
}>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=getFutureTableSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFutureTableSchema.d.ts","sourceRoot":"","sources":["getFutureTableSchema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAmB,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAqB,MAAM,kCAAkC,CAAC;AAEnG,KAAK,IAAI,GAAG;IACV,EAAE,EAAE,EAAE,CAAC;IACP,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,oBAAoB,kDAA8D,IAAI;iBACpF,aAAa,EAAE;UACtB,iBAAiB,EAAE;EAyD1B,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFutureTableSchema = void 0;
|
|
4
|
+
const prostgles_types_1 = require("prostgles-types");
|
|
5
|
+
const getColumnDefinitionQuery_1 = require("./getColumnDefinitionQuery");
|
|
6
|
+
const getConstraintDefinitionQueries_1 = require("./getConstraintDefinitionQueries");
|
|
7
|
+
const getFutureTableSchema = async ({ columnDefs, tableName, constraintDefs = [], db }) => {
|
|
8
|
+
let constraints = [];
|
|
9
|
+
let cols = [];
|
|
10
|
+
const ROLLBACK = "Rollback";
|
|
11
|
+
try {
|
|
12
|
+
await db.tx(async (t) => {
|
|
13
|
+
// const { v } = await t.one("SELECT md5(random()::text) as v");
|
|
14
|
+
// /** TODO: create all tables in a random new schema */
|
|
15
|
+
// const randomTableName = `prostgles_constr_${v}`;
|
|
16
|
+
// /* References are removed to avoid potential issues with ftables missing */
|
|
17
|
+
// const columnDefsWithoutReferences = columnDefs.map(cdef => {
|
|
18
|
+
// const refIdx = cdef.toLowerCase().indexOf(" references ");
|
|
19
|
+
// if(refIdx < 0) return cdef;
|
|
20
|
+
// return cdef.slice(0, refIdx);
|
|
21
|
+
// });
|
|
22
|
+
// const query = `CREATE TABLE ${randomTableName} (
|
|
23
|
+
// ${columnDefsWithoutReferences.join(",\n")}
|
|
24
|
+
// );
|
|
25
|
+
// ${alterQueries}
|
|
26
|
+
// `;
|
|
27
|
+
const tableEsc = (0, prostgles_types_1.asName)(tableName);
|
|
28
|
+
const consQueries = constraintDefs.map(c => `ALTER TABLE ${tableEsc} ADD ${c.name ? ` CONSTRAINT ${(0, prostgles_types_1.asName)(c.name)}` : ""} ${c.content};`).join("\n");
|
|
29
|
+
const query = `
|
|
30
|
+
DROP TABLE IF EXISTS ${tableEsc} CASCADE;
|
|
31
|
+
CREATE TABLE ${tableEsc} (
|
|
32
|
+
${columnDefs.join(",\n")}
|
|
33
|
+
);
|
|
34
|
+
${consQueries}
|
|
35
|
+
`;
|
|
36
|
+
await t.any(query);
|
|
37
|
+
constraints = await (0, getConstraintDefinitionQueries_1.getColConstraints)({ db: t, table: tableName });
|
|
38
|
+
cols = await (0, getColumnDefinitionQuery_1.getTableColumns)({ db: t, table: tableName });
|
|
39
|
+
/** Rollback */
|
|
40
|
+
return Promise.reject(ROLLBACK);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
if (e !== ROLLBACK) {
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { cols, constraints };
|
|
49
|
+
};
|
|
50
|
+
exports.getFutureTableSchema = getFutureTableSchema;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { asName } from "prostgles-types";
|
|
2
|
+
import { DB } from "../Prostgles";
|
|
3
|
+
import { log } from "../PubSubManager/PubSubManager";
|
|
4
|
+
import { ColumnMinimalInfo, getTableColumns } from "./getColumnDefinitionQuery";
|
|
5
|
+
import { ColConstraint, ConstraintDef, getColConstraints } from "./getConstraintDefinitionQueries";
|
|
6
|
+
|
|
7
|
+
type Args = {
|
|
8
|
+
db: DB,
|
|
9
|
+
columnDefs: string[];
|
|
10
|
+
tableName: string;
|
|
11
|
+
constraintDefs?: ConstraintDef[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const getFutureTableSchema = async ({ columnDefs, tableName, constraintDefs = [], db }: Args): Promise<{
|
|
15
|
+
constraints: ColConstraint[];
|
|
16
|
+
cols: ColumnMinimalInfo[];
|
|
17
|
+
}> => {
|
|
18
|
+
|
|
19
|
+
let constraints: ColConstraint[] = [];
|
|
20
|
+
let cols: ColumnMinimalInfo[] = [];
|
|
21
|
+
const ROLLBACK = "Rollback";
|
|
22
|
+
try {
|
|
23
|
+
await db.tx(async t => {
|
|
24
|
+
// const { v } = await t.one("SELECT md5(random()::text) as v");
|
|
25
|
+
|
|
26
|
+
// /** TODO: create all tables in a random new schema */
|
|
27
|
+
// const randomTableName = `prostgles_constr_${v}`;
|
|
28
|
+
|
|
29
|
+
// /* References are removed to avoid potential issues with ftables missing */
|
|
30
|
+
// const columnDefsWithoutReferences = columnDefs.map(cdef => {
|
|
31
|
+
// const refIdx = cdef.toLowerCase().indexOf(" references ");
|
|
32
|
+
// if(refIdx < 0) return cdef;
|
|
33
|
+
// return cdef.slice(0, refIdx);
|
|
34
|
+
// });
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// const query = `CREATE TABLE ${randomTableName} (
|
|
39
|
+
// ${columnDefsWithoutReferences.join(",\n")}
|
|
40
|
+
// );
|
|
41
|
+
// ${alterQueries}
|
|
42
|
+
// `;
|
|
43
|
+
|
|
44
|
+
const tableEsc = asName(tableName);
|
|
45
|
+
|
|
46
|
+
const consQueries = constraintDefs.map(c =>
|
|
47
|
+
`ALTER TABLE ${tableEsc} ADD ${c.name? ` CONSTRAINT ${asName(c.name)}` : ""} ${c.content};`
|
|
48
|
+
).join("\n");
|
|
49
|
+
|
|
50
|
+
const query = `
|
|
51
|
+
DROP TABLE IF EXISTS ${tableEsc} CASCADE;
|
|
52
|
+
CREATE TABLE ${tableEsc} (
|
|
53
|
+
${columnDefs.join(",\n")}
|
|
54
|
+
);
|
|
55
|
+
${consQueries}
|
|
56
|
+
`
|
|
57
|
+
|
|
58
|
+
await t.any(query);
|
|
59
|
+
constraints = await getColConstraints({ db: t, table: tableName });
|
|
60
|
+
cols = await getTableColumns({ db: t, table: tableName });
|
|
61
|
+
|
|
62
|
+
/** Rollback */
|
|
63
|
+
return Promise.reject(ROLLBACK);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
} catch(e){
|
|
67
|
+
if(e !== ROLLBACK) {
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { cols, constraints };
|
|
73
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DB, DBHandlerServer } from "../Prostgles";
|
|
2
|
+
import { TableConfig } from "./TableConfig";
|
|
3
|
+
type Args = {
|
|
4
|
+
db: DB;
|
|
5
|
+
tableConf: TableConfig[string];
|
|
6
|
+
tableName: string;
|
|
7
|
+
tableHandler: DBHandlerServer[string];
|
|
8
|
+
};
|
|
9
|
+
export declare const getTableColumnQueries: ({ db, tableConf, tableName, tableHandler }: Args) => Promise<{
|
|
10
|
+
columnDefs: string[];
|
|
11
|
+
newColumnDefs: string[];
|
|
12
|
+
fullQuery: string;
|
|
13
|
+
isCreate: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=getTableColumnQueries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTableColumnQueries.d.ts","sourceRoot":"","sources":["getTableColumnQueries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,KAAK,IAAI,GAAG;IACV,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;CACvC,CAAA;AAED,eAAO,MAAM,qBAAqB,+CAAsD,IAAI;gBAC9E,MAAM,EAAE;mBACL,MAAM,EAAE;eACZ,MAAM;cACP,OAAO;EA8GlB,CAAA"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTableColumnQueries = void 0;
|
|
4
|
+
const prostgles_types_1 = require("prostgles-types");
|
|
5
|
+
const validate_jsonb_schema_sql_1 = require("../JSONBValidation/validate_jsonb_schema_sql");
|
|
6
|
+
const getColumnDefinitionQuery_1 = require("./getColumnDefinitionQuery");
|
|
7
|
+
const getFutureTableSchema_1 = require("./getFutureTableSchema");
|
|
8
|
+
const getTableColumnQueries = async ({ db, tableConf, tableName, tableHandler }) => {
|
|
9
|
+
let newColumnDefs = [];
|
|
10
|
+
const droppedColNames = [];
|
|
11
|
+
const alteredColQueries = [];
|
|
12
|
+
let fullQuery = "";
|
|
13
|
+
let isCreate = false;
|
|
14
|
+
if ("columns" in tableConf && tableConf.columns) {
|
|
15
|
+
const hasJSONBValidation = (0, prostgles_types_1.getKeys)(tableConf.columns).some(c => {
|
|
16
|
+
const cConf = tableConf.columns?.[c];
|
|
17
|
+
return cConf && (0, prostgles_types_1.isObject)(cConf) && (cConf.jsonbSchema || cConf.jsonbSchemaType);
|
|
18
|
+
});
|
|
19
|
+
/** Must install validation function */
|
|
20
|
+
if (hasJSONBValidation) {
|
|
21
|
+
try {
|
|
22
|
+
await db.any(validate_jsonb_schema_sql_1.validate_jsonb_schema_sql);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.error("Could not install the jsonb validation function due to error: ", err);
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const columns = (0, prostgles_types_1.getKeys)(tableConf.columns).filter(c => {
|
|
30
|
+
const colDef = tableConf.columns[c];
|
|
31
|
+
/** Exclude NamedJoinColumn */
|
|
32
|
+
return typeof colDef === "string" || !("joinDef" in colDef);
|
|
33
|
+
});
|
|
34
|
+
const colDefs = [];
|
|
35
|
+
for await (const colName of columns) {
|
|
36
|
+
const colConf = tableConf.columns[colName];
|
|
37
|
+
/* Get column definition */
|
|
38
|
+
const colDef = await (0, getColumnDefinitionQuery_1.getColumnDefinitionQuery)({ colConf, column: colName, db, table: tableName });
|
|
39
|
+
if (colDef) {
|
|
40
|
+
colDefs.push({ name: colName, def: colDef });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const columnDefs = colDefs.map(c => c.def);
|
|
44
|
+
if (!colDefs.length) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const ALTERQ = `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)}`;
|
|
48
|
+
if (!tableHandler) {
|
|
49
|
+
newColumnDefs.push(...colDefs.map(c => c.def));
|
|
50
|
+
}
|
|
51
|
+
else if (tableHandler) {
|
|
52
|
+
const currCols = await (0, getColumnDefinitionQuery_1.getTableColumns)({ db, table: tableName });
|
|
53
|
+
/** Add new columns */
|
|
54
|
+
newColumnDefs = colDefs.filter(nc => !tableHandler.columns?.some(c => nc.name === c.name)).map(c => c.def);
|
|
55
|
+
/** Altered/Dropped columns */
|
|
56
|
+
const { cols: futureCols } = await (0, getFutureTableSchema_1.getFutureTableSchema)({ tableName, columnDefs, constraintDefs: [], db });
|
|
57
|
+
currCols.forEach(c => {
|
|
58
|
+
const newCol = futureCols.find(nc => nc.column_name === c.column_name);
|
|
59
|
+
if (!newCol) {
|
|
60
|
+
droppedColNames.push(c.column_name);
|
|
61
|
+
}
|
|
62
|
+
else if (newCol.nullable !== c.nullable) {
|
|
63
|
+
alteredColQueries.push(`${ALTERQ} ALTER COLUMN ${(0, prostgles_types_1.asName)(c.column_name)} ${newCol.nullable ? "SET" : "DROP"} NOT NULL;`);
|
|
64
|
+
}
|
|
65
|
+
else if (newCol.udt_name !== c.udt_name) {
|
|
66
|
+
alteredColQueries.push(`${ALTERQ} ALTER COLUMN ${(0, prostgles_types_1.asName)(c.column_name)} TYPE ${newCol.udt_name};`);
|
|
67
|
+
}
|
|
68
|
+
else if (newCol.column_default !== c.column_default) {
|
|
69
|
+
const colConfig = colDefs.find(cd => cd.name === c.column_name);
|
|
70
|
+
if (["serial", "bigserial"].some(t => colConfig?.def.toLowerCase().includes(` ${t}`)) && c.column_default?.toLowerCase().includes("nextval")) {
|
|
71
|
+
/** Ignore SERIAL/BIGSERIAL <> nextval mismatch */
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
alteredColQueries.push(`${ALTERQ} ALTER COLUMN ${(0, prostgles_types_1.asName)(c.column_name)} ${newCol.column_default === null ? "DROP DEFAULT" : `SET DEFAULT ${newCol.column_default}`};`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!tableHandler || tableConf.dropIfExists || tableConf.dropIfExistsCascade) {
|
|
80
|
+
isCreate = true;
|
|
81
|
+
const DROPQ = `DROP TABLE IF EXISTS ${(0, prostgles_types_1.asName)(tableName)}`;
|
|
82
|
+
fullQuery = ([
|
|
83
|
+
...(tableConf.dropIfExists ? [`${DROPQ};`] : tableConf.dropIfExistsCascade ? [`${DROPQ} CASCADE;`] : []),
|
|
84
|
+
`CREATE TABLE ${(0, prostgles_types_1.asName)(tableName)} (`,
|
|
85
|
+
columnDefs.join(", \n"),
|
|
86
|
+
`);`
|
|
87
|
+
].join("\n"));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
fullQuery = [
|
|
91
|
+
...droppedColNames.map(c => `${ALTERQ} DROP COLUMN ${(0, prostgles_types_1.asName)(c)};`),
|
|
92
|
+
...newColumnDefs.map(c => `${ALTERQ} ADD COLUMN ${c};`),
|
|
93
|
+
...alteredColQueries,
|
|
94
|
+
].join("\n");
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
fullQuery,
|
|
98
|
+
columnDefs,
|
|
99
|
+
isCreate,
|
|
100
|
+
newColumnDefs,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
exports.getTableColumnQueries = getTableColumnQueries;
|