prostgles-server 2.0.188 → 2.0.191
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/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/dist/DboBuilder/insertDataParse.js +14 -4
- package/dist/DboBuilder/insertDataParse.js.map +1 -1
- package/dist/DboBuilder.d.ts +5 -3
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +67 -161
- package/dist/DboBuilder.js.map +1 -1
- package/dist/FileManager.d.ts +20 -72
- package/dist/FileManager.d.ts.map +1 -1
- package/dist/FileManager.js +232 -164
- package/dist/FileManager.js.map +1 -1
- package/dist/Prostgles.d.ts +13 -2
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js.map +1 -1
- package/dist/TableConfig.d.ts +1 -2
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js.map +1 -1
- package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/lib/DboBuilder/insertDataParse.js +14 -4
- package/lib/DboBuilder/insertDataParse.ts +14 -4
- package/lib/DboBuilder.d.ts +5 -3
- package/lib/DboBuilder.d.ts.map +1 -1
- package/lib/DboBuilder.js +67 -161
- package/lib/DboBuilder.ts +84 -191
- package/lib/FileManager.d.ts +19 -71
- package/lib/FileManager.d.ts.map +1 -1
- package/lib/FileManager.js +232 -164
- package/lib/FileManager.ts +272 -191
- package/lib/Prostgles.d.ts +13 -2
- package/lib/Prostgles.d.ts.map +1 -1
- package/lib/Prostgles.ts +2 -2
- package/lib/TableConfig.d.ts +1 -2
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.ts +2 -4
- package/lib/fileType/core.js +1527 -0
- package/lib/fileType/supported.js +278 -0
- package/package.json +5 -5
- package/tests/client/PID.txt +1 -1
- package/tests/server/DBoGenerated.d.ts +1 -1
- package/tests/server/package-lock.json +9 -9
package/lib/DboBuilder.js
CHANGED
|
@@ -390,16 +390,16 @@ class ViewHandler {
|
|
|
390
390
|
};
|
|
391
391
|
});
|
|
392
392
|
let expectOne = false;
|
|
393
|
-
paths.map(({ source, target, on }, i) => {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
})
|
|
393
|
+
// paths.map(({ source, target, on }, i) => {
|
|
394
|
+
// if(expectOne && on.length === 1){
|
|
395
|
+
// const sourceCol = on[0][1];
|
|
396
|
+
// const targetCol = on[0][0];
|
|
397
|
+
// const sCol = this.dboBuilder.dbo[source].columns.find(c => c.name === sourceCol)
|
|
398
|
+
// const tCol = this.dboBuilder.dbo[target].columns.find(c => c.name === targetCol)
|
|
399
|
+
// console.log({ sourceCol, targetCol, sCol, source, tCol, target, on})
|
|
400
|
+
// expectOne = sCol.is_pkey && tCol.is_pkey
|
|
401
|
+
// }
|
|
402
|
+
// })
|
|
403
403
|
return {
|
|
404
404
|
paths,
|
|
405
405
|
expectOne
|
|
@@ -414,31 +414,32 @@ class ViewHandler {
|
|
|
414
414
|
if (!p.getInfo)
|
|
415
415
|
throw "Not allowed";
|
|
416
416
|
let has_media = undefined;
|
|
417
|
-
/**
|
|
418
|
-
* Media is directly related to this table (does not come from a deeply joined table)
|
|
419
|
-
*/
|
|
420
|
-
let has_direct_media = false;
|
|
421
417
|
const mediaTable = this.dboBuilder.prostgles?.opts?.fileTable?.tableName;
|
|
422
418
|
if (!this.is_media && mediaTable) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
419
|
+
const joinConf = this.dboBuilder.prostgles?.opts?.fileTable?.referencedTables?.[this.name];
|
|
420
|
+
if (joinConf) {
|
|
421
|
+
has_media = typeof joinConf === "string" ? joinConf : "one";
|
|
426
422
|
}
|
|
427
423
|
else {
|
|
428
424
|
const jp = this.dboBuilder.joinPaths.find(jp => jp.t1 === this.name && jp.t2 === mediaTable);
|
|
429
425
|
if (jp && jp.path.length <= 3) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
426
|
+
if (jp.path.length <= 2) {
|
|
427
|
+
has_media = "one";
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
await Promise.all(jp.path.map(async (tableName) => {
|
|
431
|
+
const pkeyFcols = this?.dboBuilder?.dbo?.[tableName]?.columns?.filter(c => c.is_pkey).map(c => c.name);
|
|
432
|
+
const cols = this?.dboBuilder?.dbo?.[tableName]?.columns?.filter(c => c?.references && jp.path.includes(c?.references?.ftable));
|
|
433
|
+
if (cols && cols.length && has_media !== "many") {
|
|
434
|
+
if (cols.some(c => !pkeyFcols?.includes(c.name))) {
|
|
435
|
+
has_media = "many";
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
has_media = "one";
|
|
439
|
+
}
|
|
438
440
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}));
|
|
441
|
+
}));
|
|
442
|
+
}
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
445
|
}
|
|
@@ -448,7 +449,6 @@ class ViewHandler {
|
|
|
448
449
|
info: this.dboBuilder.prostgles?.tableConfigurator?.getTableInfo({ tableName: this.name, lang }),
|
|
449
450
|
is_media: this.is_media,
|
|
450
451
|
has_media,
|
|
451
|
-
has_direct_media,
|
|
452
452
|
media_table_name: mediaTable,
|
|
453
453
|
dynamicRules: {
|
|
454
454
|
update: Boolean(tableRules?.update?.dynamicFields?.length)
|
|
@@ -485,6 +485,8 @@ class ViewHandler {
|
|
|
485
485
|
let label = c.comment || capitalizeFirstLetter(c.name, " ");
|
|
486
486
|
const select = c.privileges.some(p => p.privilege_type === "SELECT"), insert = c.privileges.some(p => p.privilege_type === "INSERT"), update = c.privileges.some(p => p.privilege_type === "UPDATE"), _delete = this.tableOrViewInfo.privileges.delete; // c.privileges.some(p => p.privilege_type === "DELETE");
|
|
487
487
|
delete c.privileges;
|
|
488
|
+
const prostgles = this.dboBuilder?.prostgles;
|
|
489
|
+
const fileConfig = prostgles.fileManager?.getColInfo({ colName: c.name, tableName: this.name });
|
|
488
490
|
let result = {
|
|
489
491
|
...c,
|
|
490
492
|
label,
|
|
@@ -494,7 +496,8 @@ class ViewHandler {
|
|
|
494
496
|
filter: Boolean(p.select && p.select.filterFields && p.select.filterFields.includes(c.name)),
|
|
495
497
|
update: update && Boolean(p.update && p.update.fields && p.update.fields.includes(c.name)),
|
|
496
498
|
delete: _delete && Boolean(p.delete && p.delete.filterFields && p.delete.filterFields.includes(c.name)),
|
|
497
|
-
...(
|
|
499
|
+
...(prostgles?.tableConfigurator?.getColInfo({ table: this.name, col: c.name, lang }) || {}),
|
|
500
|
+
...(fileConfig && { file: fileConfig })
|
|
498
501
|
};
|
|
499
502
|
if (dynamicUpdateFields) {
|
|
500
503
|
result.update = dynamicUpdateFields.includes(c.name);
|
|
@@ -1381,8 +1384,8 @@ class ViewHandler {
|
|
|
1381
1384
|
*/
|
|
1382
1385
|
}
|
|
1383
1386
|
else if (isPlainObject(fieldParams)) {
|
|
1384
|
-
if (
|
|
1385
|
-
let keys =
|
|
1387
|
+
if ((0, prostgles_types_1.getKeys)(fieldParams).length) {
|
|
1388
|
+
let keys = (0, prostgles_types_1.getKeys)(fieldParams);
|
|
1386
1389
|
if (keys[0] === "") {
|
|
1387
1390
|
if (allow_empty) {
|
|
1388
1391
|
return [""];
|
|
@@ -1997,20 +2000,9 @@ class DboBuilder {
|
|
|
1997
2000
|
return this.db.tx((t) => {
|
|
1998
2001
|
let dbTX = {};
|
|
1999
2002
|
this.tablesOrViews?.map(tov => {
|
|
2000
|
-
|
|
2001
|
-
dbTX[tov.name] = new ViewHandler(this.db, tov, this, t, dbTX, this.joinPaths);
|
|
2002
|
-
}
|
|
2003
|
-
else {
|
|
2004
|
-
dbTX[tov.name] = new TableHandler(this.db, tov, this, t, dbTX, this.joinPaths);
|
|
2005
|
-
/**
|
|
2006
|
-
* Pass only the transaction object to ensure consistency
|
|
2007
|
-
*/
|
|
2008
|
-
// dbTX[tov.name] = new ViewHandler(t, tov, this.pubSubManager, this, t, this.joinPaths);
|
|
2009
|
-
// } else {
|
|
2010
|
-
// dbTX[tov.name] = new TableHandler(t as any, tov, this.pubSubManager, this, t, this.joinPaths);
|
|
2011
|
-
}
|
|
2003
|
+
dbTX[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, t, dbTX, this.joinPaths);
|
|
2012
2004
|
});
|
|
2013
|
-
|
|
2005
|
+
(0, prostgles_types_1.getKeys)(dbTX).map(k => {
|
|
2014
2006
|
dbTX[k].dbTX = dbTX;
|
|
2015
2007
|
});
|
|
2016
2008
|
return cb(dbTX, t);
|
|
@@ -2069,16 +2061,19 @@ class DboBuilder {
|
|
|
2069
2061
|
}
|
|
2070
2062
|
// 3 find incorrect fields
|
|
2071
2063
|
joins.map(({ tables, on }) => {
|
|
2072
|
-
const t1 = tables[0], t2 = tables[1]
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2064
|
+
const t1 = tables[0], t2 = tables[1];
|
|
2065
|
+
on.map(cond => {
|
|
2066
|
+
const f1s = Object.keys(cond), f2s = Object.values(cond);
|
|
2067
|
+
[[t1, f1s], [t2, f2s]].map(v => {
|
|
2068
|
+
var t = v[0], f = v[1];
|
|
2069
|
+
let tov = this.tablesOrViews.find(_t => _t.name === t);
|
|
2070
|
+
if (!tov)
|
|
2071
|
+
throw "Table not found: " + t;
|
|
2072
|
+
const m1 = f.filter(k => !tov.columns.map(c => c.name).includes(k));
|
|
2073
|
+
if (m1 && m1.length) {
|
|
2074
|
+
throw `Table ${t}(${tov.columns.map(c => c.name).join()}) has no fields named: ${m1.join()}`;
|
|
2075
|
+
}
|
|
2076
|
+
});
|
|
2082
2077
|
});
|
|
2083
2078
|
});
|
|
2084
2079
|
// 4 find incorrect/missing join types
|
|
@@ -2125,21 +2120,9 @@ class DboBuilder {
|
|
|
2125
2120
|
buildJoinPaths() {
|
|
2126
2121
|
}
|
|
2127
2122
|
async build() {
|
|
2128
|
-
|
|
2129
|
-
this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db); //, this.schema
|
|
2130
|
-
// console.log(this.tablesOrViews.map(t => `${t.name} (${t.columns.map(c => c.name).join(", ")})`))
|
|
2123
|
+
this.tablesOrViews = await getTablesForSchemaPostgresSQL(this.db);
|
|
2131
2124
|
this.constraints = await getConstraints(this.db);
|
|
2132
2125
|
await this.parseJoins();
|
|
2133
|
-
// const common_types =
|
|
2134
|
-
// `
|
|
2135
|
-
// import { ViewHandler, TableHandler, JoinMaker } from "prostgles-types";
|
|
2136
|
-
// export type TxCB = {
|
|
2137
|
-
// (t: DBObj): (any | void | Promise<(any | void)>)
|
|
2138
|
-
// };
|
|
2139
|
-
// `
|
|
2140
|
-
// this.dboDefinition = `export type DBObj = {\n`;
|
|
2141
|
-
// let joinTableNames: string[] = [];
|
|
2142
|
-
// let allDataDefs = "";
|
|
2143
2126
|
this.tablesOrViews.map(tov => {
|
|
2144
2127
|
const columnsForTypes = tov.columns.slice(0).sort((a, b) => a.name.localeCompare(b.name));
|
|
2145
2128
|
const filterKeywords = Object.values(this.prostgles.keywords);
|
|
@@ -2149,23 +2132,9 @@ class DboBuilder {
|
|
|
2149
2132
|
Please provide a replacement keyword name using the $filter_keyName init option.
|
|
2150
2133
|
Alternatively you can rename the table column\n`;
|
|
2151
2134
|
}
|
|
2152
|
-
|
|
2153
|
-
const TSTableHandlerName = escapeTSNames(tov.name);
|
|
2154
|
-
if (tov.is_view) {
|
|
2155
|
-
this.dbo[tov.name] = new ViewHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
|
|
2156
|
-
// this.dboDefinition += ` ${TSTableHandlerName}: ViewHandler<${TSTableDataName}> \n`;
|
|
2157
|
-
}
|
|
2158
|
-
else {
|
|
2159
|
-
this.dbo[tov.name] = new TableHandler(this.db, tov, this, undefined, undefined, this.joinPaths);
|
|
2160
|
-
// this.dboDefinition += ` ${TSTableHandlerName}: TableHandler<${TSTableDataName}> \n`;
|
|
2161
|
-
}
|
|
2162
|
-
// allDataDefs += `export type ${TSTableDataName} = { \n` +
|
|
2163
|
-
// (this.dbo[tov.name] as ViewHandler).tsColumnDefs.map(str => ` ` + str).join("\n") +
|
|
2164
|
-
// `\n}\n`;
|
|
2165
|
-
// this.dboDefinition += ` ${escapeTSNames(tov.name, false)}: ${(this.dbo[tov.name] as TableHandler).tsDboName};\n`;
|
|
2135
|
+
this.dbo[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, undefined, undefined, this.joinPaths);
|
|
2166
2136
|
if (this.joinPaths && this.joinPaths.find(jp => [jp.t1, jp.t2].includes(tov.name))) {
|
|
2167
2137
|
let table = tov.name;
|
|
2168
|
-
// joinTableNames.push(table);
|
|
2169
2138
|
const makeJoin = (isLeft = true, filter, select, options) => {
|
|
2170
2139
|
return {
|
|
2171
2140
|
[isLeft ? "$leftJoin" : "$innerJoin"]: table,
|
|
@@ -2192,17 +2161,6 @@ class DboBuilder {
|
|
|
2192
2161
|
};
|
|
2193
2162
|
}
|
|
2194
2163
|
});
|
|
2195
|
-
// let joinBuilderDef = "";
|
|
2196
|
-
// if(joinTableNames.length){
|
|
2197
|
-
// joinBuilderDef += "export type JoinMakerTables = {\n";
|
|
2198
|
-
// joinTableNames.map(tname => {
|
|
2199
|
-
// joinBuilderDef += ` ${escapeTSNames(tname)}: JoinMaker<${snakify(tname, true)}>;\n`
|
|
2200
|
-
// })
|
|
2201
|
-
// joinBuilderDef += "};\n";
|
|
2202
|
-
// ["leftJoin", "innerJoin", "leftJoinOne", "innerJoinOne"].map(joinType => {
|
|
2203
|
-
// this.dboDefinition += ` ${joinType}: JoinMakerTables;\n`;
|
|
2204
|
-
// });
|
|
2205
|
-
// }
|
|
2206
2164
|
if (this.prostgles.opts.transactions) {
|
|
2207
2165
|
let txKey = "tx";
|
|
2208
2166
|
if (typeof this.prostgles.opts.transactions === "string")
|
|
@@ -2211,7 +2169,7 @@ class DboBuilder {
|
|
|
2211
2169
|
this.dbo[txKey] = (cb) => this.getTX(cb);
|
|
2212
2170
|
}
|
|
2213
2171
|
if (!this.dbo.sql) {
|
|
2214
|
-
let needType = true;
|
|
2172
|
+
let needType = true;
|
|
2215
2173
|
let DATA_TYPES = !needType ? [] : await this.db.any("SELECT oid, typname FROM pg_type");
|
|
2216
2174
|
let USER_TABLES = !needType ? [] : await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables");
|
|
2217
2175
|
this.dbo.sql = async (query, params, options, localParams) => {
|
|
@@ -2309,16 +2267,11 @@ class DboBuilder {
|
|
|
2309
2267
|
}
|
|
2310
2268
|
this.dboDefinition += "};\n";
|
|
2311
2269
|
this.tsTypesDefinition = [
|
|
2312
|
-
// common_types,
|
|
2313
2270
|
`/* SCHEMA DEFINITON. Table names have been altered to work with Typescript */`,
|
|
2314
|
-
|
|
2315
|
-
// joinBuilderDef,
|
|
2316
|
-
`/* DBO Definition. Isomorphic */`,
|
|
2317
|
-
// this.dboDefinition,
|
|
2271
|
+
`/* DBO Definition */`,
|
|
2318
2272
|
(0, DBSchemaBuilder_1.getDBSchema)(this)
|
|
2319
2273
|
].join("\n");
|
|
2320
2274
|
return this.dbo;
|
|
2321
|
-
// let dbo = makeDBO(db, allTablesViews, pubSubManager, true);
|
|
2322
2275
|
}
|
|
2323
2276
|
}
|
|
2324
2277
|
exports.DboBuilder = DboBuilder;
|
|
@@ -2455,15 +2408,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
|
|
|
2455
2408
|
`;
|
|
2456
2409
|
// console.log(pgp.as.format(query, { schema }), schema);
|
|
2457
2410
|
let res = await db.any(query, { schema });
|
|
2458
|
-
// res = await Promise.all(res.map(async tbl => {
|
|
2459
|
-
// tbl.columns = await Promise.all(tbl.columns.map(async col => {
|
|
2460
|
-
// if(col.has_default){
|
|
2461
|
-
// col.column_default = !col.column_default.startsWith("nextval(")? (await db.oneOrNone(`SELECT ${col.column_default} as val`)).val : null;
|
|
2462
|
-
// }
|
|
2463
|
-
// return col;
|
|
2464
|
-
// }))
|
|
2465
|
-
// return tbl;
|
|
2466
|
-
// }))
|
|
2467
2411
|
res = res.map(tbl => {
|
|
2468
2412
|
tbl.columns = tbl.columns.map(col => {
|
|
2469
2413
|
if (col.has_default) {
|
|
@@ -2478,8 +2422,6 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
|
|
|
2478
2422
|
}
|
|
2479
2423
|
/**
|
|
2480
2424
|
* Throw error if illegal keys found in object
|
|
2481
|
-
* @param {Object} obj - Object to be checked
|
|
2482
|
-
* @param {string[]} allowedKeys - The name of the employee.
|
|
2483
2425
|
*/
|
|
2484
2426
|
function validateObj(obj, allowedKeys) {
|
|
2485
2427
|
if (obj && Object.keys(obj).length) {
|
|
@@ -2753,13 +2695,16 @@ function sqlErrCodeToMsg(code) {
|
|
|
2753
2695
|
}
|
|
2754
2696
|
async function getInferredJoins2(schema) {
|
|
2755
2697
|
let joins = [];
|
|
2756
|
-
const upsertJoin = (t1, t2, cols) => {
|
|
2698
|
+
const upsertJoin = (t1, t2, cols, type) => {
|
|
2757
2699
|
let existingIdx = joins.findIndex(j => j.tables.slice(0).sort().join() === [t1, t2].sort().join());
|
|
2758
2700
|
let existing = joins[existingIdx];
|
|
2759
2701
|
const normalCond = cols.reduce((a, v) => ({ ...a, [v.col1]: v.col2 }), {});
|
|
2760
2702
|
const revertedCond = cols.reduce((a, v) => ({ ...a, [v.col2]: v.col1 }), {});
|
|
2761
2703
|
if (existing) {
|
|
2762
|
-
const
|
|
2704
|
+
const isLTR = existing.tables[0] === t1;
|
|
2705
|
+
const cond = isLTR ? normalCond : revertedCond;
|
|
2706
|
+
/** At some point we should add relationship type to EACH JOIN CONDITION GROUP */
|
|
2707
|
+
// const fixedType = isLTR? type : type.split("").reverse().join("") as Join["type"];
|
|
2763
2708
|
/** Avoid duplicates */
|
|
2764
2709
|
if (!existing.on.some(_cond => JSON.stringify(_cond) === JSON.stringify(cond))) {
|
|
2765
2710
|
existing.on.push(cond);
|
|
@@ -2770,7 +2715,7 @@ async function getInferredJoins2(schema) {
|
|
|
2770
2715
|
joins.push({
|
|
2771
2716
|
tables: [t1, t2],
|
|
2772
2717
|
on: [normalCond],
|
|
2773
|
-
type
|
|
2718
|
+
type
|
|
2774
2719
|
});
|
|
2775
2720
|
}
|
|
2776
2721
|
};
|
|
@@ -2778,54 +2723,15 @@ async function getInferredJoins2(schema) {
|
|
|
2778
2723
|
tov.columns.map(col => {
|
|
2779
2724
|
if (col.references) {
|
|
2780
2725
|
const r = col.references;
|
|
2781
|
-
|
|
2726
|
+
const joinCols = r.cols.map((c, i) => ({ col1: c, col2: r.fcols[i] }));
|
|
2727
|
+
let type = "one-many";
|
|
2728
|
+
const ftablePkeys = schema.find(_tov => _tov.name === r.ftable)?.columns.filter(fcol => fcol.is_pkey);
|
|
2729
|
+
if (ftablePkeys?.length && ftablePkeys.every(fkey => r.fcols.includes(fkey.name))) {
|
|
2730
|
+
type = "one-one";
|
|
2731
|
+
}
|
|
2732
|
+
upsertJoin(tov.name, r.ftable, joinCols, type);
|
|
2782
2733
|
}
|
|
2783
2734
|
});
|
|
2784
2735
|
});
|
|
2785
2736
|
return joins;
|
|
2786
2737
|
}
|
|
2787
|
-
// async function getInferredJoins(db: DB, schema: string = "public"): Promise<Join[]>{
|
|
2788
|
-
// let joins: Join[] = [];
|
|
2789
|
-
// let res = await db.any(`SELECT
|
|
2790
|
-
// tc.table_schema,
|
|
2791
|
-
// tc.constraint_name,
|
|
2792
|
-
// tc.table_name,
|
|
2793
|
-
// kcu.column_name,
|
|
2794
|
-
// ccu.table_schema AS foreign_table_schema,
|
|
2795
|
-
// ccu.table_name AS foreign_table_name,
|
|
2796
|
-
// ccu.column_name AS foreign_column_name,
|
|
2797
|
-
// tc.constraint_type IN ('UNIQUE', 'PRIMARY KEY') as foreign_is_unique
|
|
2798
|
-
// FROM
|
|
2799
|
-
// information_schema.table_constraints AS tc
|
|
2800
|
-
// JOIN information_schema.key_column_usage AS kcu
|
|
2801
|
-
// ON tc.constraint_name = kcu.constraint_name
|
|
2802
|
-
// AND tc.table_schema = kcu.table_schema
|
|
2803
|
-
// JOIN information_schema.constraint_column_usage AS ccu
|
|
2804
|
-
// ON ccu.constraint_name = tc.constraint_name
|
|
2805
|
-
// AND ccu.table_schema = tc.table_schema
|
|
2806
|
-
// WHERE tc.table_schema=` + "${schema}" + `
|
|
2807
|
-
// AND tc.constraint_type = 'FOREIGN KEY'
|
|
2808
|
-
// AND tc.table_name <> ccu.table_name -- Exclude self-referencing tables
|
|
2809
|
-
// `, { schema });
|
|
2810
|
-
// res.map((d: any) => {
|
|
2811
|
-
// let eIdx = joins.findIndex(j => j.tables.includes(d.table_name) && j.tables.includes(d.foreign_table_name));
|
|
2812
|
-
// let existing = joins[eIdx];
|
|
2813
|
-
// if(existing){
|
|
2814
|
-
// if(existing.tables[0] === d.table_name){
|
|
2815
|
-
// existing.on = { ...existing.on, [d.column_name]: d.foreign_column_name }
|
|
2816
|
-
// } else {
|
|
2817
|
-
// existing.on = { ...existing.on, [d.foreign_column_name]: d.column_name }
|
|
2818
|
-
// }
|
|
2819
|
-
// joins[eIdx] = existing;
|
|
2820
|
-
// } else {
|
|
2821
|
-
// joins.push({
|
|
2822
|
-
// tables: [d.table_name, d.foreign_table_name],
|
|
2823
|
-
// on: {
|
|
2824
|
-
// [d.column_name]: d.foreign_column_name
|
|
2825
|
-
// },
|
|
2826
|
-
// type: "many-many"
|
|
2827
|
-
// })
|
|
2828
|
-
// }
|
|
2829
|
-
// });
|
|
2830
|
-
// return joins;
|
|
2831
|
-
// }
|