ormbridge 0.9.0 → 0.11.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 +19 -18
- package/dist/cliRunner.js +4 -4
- package/dist/cliRunner.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/convert.js +30 -1
- package/dist/convert.js.map +1 -1
- package/dist/emitters/cockroach.d.ts +33 -0
- package/dist/emitters/cockroach.js +81 -0
- package/dist/emitters/cockroach.js.map +1 -0
- package/dist/emitters/doctrine.js +11 -0
- package/dist/emitters/doctrine.js.map +1 -1
- package/dist/emitters/drizzle.js +39 -4
- package/dist/emitters/drizzle.js.map +1 -1
- package/dist/emitters/efcore.js +18 -1
- package/dist/emitters/efcore.js.map +1 -1
- package/dist/emitters/efcoreColumns.js +23 -2
- package/dist/emitters/efcoreColumns.js.map +1 -1
- package/dist/emitters/gorm.js +20 -1
- package/dist/emitters/gorm.js.map +1 -1
- package/dist/emitters/jpa.d.ts +36 -0
- package/dist/emitters/jpa.js +262 -0
- package/dist/emitters/jpa.js.map +1 -0
- package/dist/emitters/jpaColumns.d.ts +27 -0
- package/dist/emitters/jpaColumns.js +342 -0
- package/dist/emitters/jpaColumns.js.map +1 -0
- package/dist/emitters/jpaDefaults.d.ts +24 -0
- package/dist/emitters/jpaDefaults.js +223 -0
- package/dist/emitters/jpaDefaults.js.map +1 -0
- package/dist/emitters/jpaEnums.d.ts +11 -0
- package/dist/emitters/jpaEnums.js +134 -0
- package/dist/emitters/jpaEnums.js.map +1 -0
- package/dist/emitters/jpaFormat.d.ts +16 -0
- package/dist/emitters/jpaFormat.js +73 -0
- package/dist/emitters/jpaFormat.js.map +1 -0
- package/dist/emitters/jpaKeys.d.ts +25 -0
- package/dist/emitters/jpaKeys.js +110 -0
- package/dist/emitters/jpaKeys.js.map +1 -0
- package/dist/emitters/jpaNames.d.ts +26 -0
- package/dist/emitters/jpaNames.js +234 -0
- package/dist/emitters/jpaNames.js.map +1 -0
- package/dist/emitters/jpaRelations.d.ts +41 -0
- package/dist/emitters/jpaRelations.js +304 -0
- package/dist/emitters/jpaRelations.js.map +1 -0
- package/dist/emitters/jpaRender.d.ts +10 -0
- package/dist/emitters/jpaRender.js +81 -0
- package/dist/emitters/jpaRender.js.map +1 -0
- package/dist/emitters/jpaScalars.d.ts +32 -0
- package/dist/emitters/jpaScalars.js +201 -0
- package/dist/emitters/jpaScalars.js.map +1 -0
- package/dist/emitters/jpaTable.d.ts +10 -0
- package/dist/emitters/jpaTable.js +109 -0
- package/dist/emitters/jpaTable.js.map +1 -0
- package/dist/emitters/jpaTypes.d.ts +85 -0
- package/dist/emitters/jpaTypes.js +36 -0
- package/dist/emitters/jpaTypes.js.map +1 -0
- package/dist/emitters/laravel.js +11 -0
- package/dist/emitters/laravel.js.map +1 -1
- package/dist/emitters/prisma.d.ts +1 -1
- package/dist/emitters/prisma.js +47 -5
- package/dist/emitters/prisma.js.map +1 -1
- package/dist/emitters/sequelize.js +82 -6
- package/dist/emitters/sequelize.js.map +1 -1
- package/dist/emitters/sqlClickhouse.d.ts +43 -0
- package/dist/emitters/sqlClickhouse.js +265 -0
- package/dist/emitters/sqlClickhouse.js.map +1 -0
- package/dist/emitters/sqlClickhouseIndexes.d.ts +3 -0
- package/dist/emitters/sqlClickhouseIndexes.js +98 -0
- package/dist/emitters/sqlClickhouseIndexes.js.map +1 -0
- package/dist/emitters/sqlClickhouseTypes.d.ts +39 -0
- package/dist/emitters/sqlClickhouseTypes.js +360 -0
- package/dist/emitters/sqlClickhouseTypes.js.map +1 -0
- package/dist/emitters/sqlDdl.d.ts +29 -1
- package/dist/emitters/sqlDdl.js +141 -21
- package/dist/emitters/sqlDdl.js.map +1 -1
- package/dist/emitters/sqlalchemy.d.ts +7 -1
- package/dist/emitters/sqlalchemy.js +39 -0
- package/dist/emitters/sqlalchemy.js.map +1 -1
- package/dist/emitters/typeorm.js +44 -9
- package/dist/emitters/typeorm.js.map +1 -1
- package/dist/formats.d.ts +5 -2
- package/dist/formats.js +36 -1
- package/dist/formats.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/io.js +27 -1
- package/dist/io.js.map +1 -1
- package/dist/parsers/javaSyntax.d.ts +120 -0
- package/dist/parsers/javaSyntax.js +304 -0
- package/dist/parsers/javaSyntax.js.map +1 -0
- package/dist/parsers/javaValues.d.ts +5 -0
- package/dist/parsers/javaValues.js +187 -0
- package/dist/parsers/javaValues.js.map +1 -0
- package/dist/parsers/jpa.d.ts +17 -0
- package/dist/parsers/jpa.js +131 -0
- package/dist/parsers/jpa.js.map +1 -0
- package/dist/parsers/jpaAnnotations.d.ts +46 -0
- package/dist/parsers/jpaAnnotations.js +156 -0
- package/dist/parsers/jpaAnnotations.js.map +1 -0
- package/dist/parsers/jpaBuild.d.ts +4 -0
- package/dist/parsers/jpaBuild.js +297 -0
- package/dist/parsers/jpaBuild.js.map +1 -0
- package/dist/parsers/jpaClasses.d.ts +27 -0
- package/dist/parsers/jpaClasses.js +257 -0
- package/dist/parsers/jpaClasses.js.map +1 -0
- package/dist/parsers/jpaCollections.d.ts +12 -0
- package/dist/parsers/jpaCollections.js +106 -0
- package/dist/parsers/jpaCollections.js.map +1 -0
- package/dist/parsers/jpaColumns.d.ts +26 -0
- package/dist/parsers/jpaColumns.js +361 -0
- package/dist/parsers/jpaColumns.js.map +1 -0
- package/dist/parsers/jpaEntities.d.ts +9 -0
- package/dist/parsers/jpaEntities.js +181 -0
- package/dist/parsers/jpaEntities.js.map +1 -0
- package/dist/parsers/jpaIndexes.d.ts +12 -0
- package/dist/parsers/jpaIndexes.js +87 -0
- package/dist/parsers/jpaIndexes.js.map +1 -0
- package/dist/parsers/jpaJoins.d.ts +68 -0
- package/dist/parsers/jpaJoins.js +131 -0
- package/dist/parsers/jpaJoins.js.map +1 -0
- package/dist/parsers/jpaModel.d.ts +73 -0
- package/dist/parsers/jpaModel.js +2 -0
- package/dist/parsers/jpaModel.js.map +1 -0
- package/dist/parsers/jpaNotes.d.ts +20 -0
- package/dist/parsers/jpaNotes.js +138 -0
- package/dist/parsers/jpaNotes.js.map +1 -0
- package/dist/parsers/jpaRelations.d.ts +4 -0
- package/dist/parsers/jpaRelations.js +242 -0
- package/dist/parsers/jpaRelations.js.map +1 -0
- package/dist/parsers/jpaTypes.d.ts +23 -0
- package/dist/parsers/jpaTypes.js +232 -0
- package/dist/parsers/jpaTypes.js.map +1 -0
- package/dist/parsers/prisma.js +9 -1
- package/dist/parsers/prisma.js.map +1 -1
- package/dist/parsers/sqlDdl.js +40 -2
- package/dist/parsers/sqlDdl.js.map +1 -1
- package/dist/parsers/sqlSyntax.js +15 -1
- package/dist/parsers/sqlSyntax.js.map +1 -1
- package/dist/parsers/sqlTypes.js +37 -2
- package/dist/parsers/sqlTypes.js.map +1 -1
- package/dist/parsers/typeorm.js +2 -0
- package/dist/parsers/typeorm.js.map +1 -1
- package/dist/styles.d.ts +3 -2
- package/dist/styles.js +4 -1
- package/dist/styles.js.map +1 -1
- package/package.json +8 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { cleanIdentifier } from './jpaColumns.js';
|
|
2
|
+
/** Splits `a, b DESC, c ASC` into column names and sort flags. */
|
|
3
|
+
function parseColumnList(list) {
|
|
4
|
+
return list
|
|
5
|
+
.split(',')
|
|
6
|
+
.map((part) => part.trim())
|
|
7
|
+
.filter((part) => part !== '')
|
|
8
|
+
.map((part) => {
|
|
9
|
+
const match = part.match(/^(.*?)(?:\s+(ASC|DESC))?$/i);
|
|
10
|
+
return {
|
|
11
|
+
column: cleanIdentifier((match?.[1] ?? part).trim()),
|
|
12
|
+
descending: (match?.[2] ?? '').toUpperCase() === 'DESC',
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Reads `@Table(uniqueConstraints, indexes)` and the natural id into IR indexes. `names` maps a column name (any
|
|
18
|
+
* case) or an attribute name to the IR field or relation that owns it.
|
|
19
|
+
*/
|
|
20
|
+
export function buildIndexes(entity, names, naturalId, warn) {
|
|
21
|
+
const indexes = [];
|
|
22
|
+
const uniqueFields = new Set();
|
|
23
|
+
const place = entity.name;
|
|
24
|
+
const table = entity.notes.get('Table');
|
|
25
|
+
const resolve = (columns, label) => {
|
|
26
|
+
const resolved = [];
|
|
27
|
+
for (const column of columns) {
|
|
28
|
+
const found = names.get(column.toLowerCase()) ?? names.get(column);
|
|
29
|
+
if (found === undefined) {
|
|
30
|
+
warn(`${place}: ${label} refers to "${column}", which is not a column of the table; it was skipped.`);
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
resolved.push(found);
|
|
34
|
+
}
|
|
35
|
+
return resolved.length === 0 ? undefined : resolved;
|
|
36
|
+
};
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const add = (columns, unique, name, descending, label) => {
|
|
39
|
+
const fields = resolve(columns, label);
|
|
40
|
+
if (fields === undefined) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const signature = `${unique ? 'u' : 'i'}|${fields.join(',')}|${name ?? ''}`;
|
|
44
|
+
if (seen.has(signature)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
seen.add(signature);
|
|
48
|
+
const only = fields[0];
|
|
49
|
+
if (unique && fields.length === 1 && only !== undefined && !name) {
|
|
50
|
+
uniqueFields.add(only);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const fieldOptions = {};
|
|
54
|
+
descending.forEach((flag, position) => {
|
|
55
|
+
const field = fields[position];
|
|
56
|
+
if (flag && field !== undefined) {
|
|
57
|
+
fieldOptions[field] = { sort: 'desc' };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
indexes.push({
|
|
61
|
+
fields,
|
|
62
|
+
isUnique: unique,
|
|
63
|
+
...(name ? { name } : {}),
|
|
64
|
+
...(Object.keys(fieldOptions).length === 0 ? {} : { fieldOptions }),
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
for (const constraint of table?.annotations('uniqueConstraints') ?? []) {
|
|
68
|
+
const name = constraint.string('name');
|
|
69
|
+
const columns = constraint.strings('columnNames');
|
|
70
|
+
add(columns.map(cleanIdentifier), true, name, columns.map(() => false), `the unique constraint${name ? ` "${name}"` : ''}`);
|
|
71
|
+
}
|
|
72
|
+
for (const index of table?.annotations('indexes') ?? []) {
|
|
73
|
+
const name = index.string('name');
|
|
74
|
+
const parts = parseColumnList(index.string('columnList') ?? '');
|
|
75
|
+
add(parts.map((part) => part.column), index.boolean('unique') === true, name, parts.map((part) => part.descending), `the index${name ? ` "${name}"` : ''}`);
|
|
76
|
+
}
|
|
77
|
+
if (naturalId.length > 0) {
|
|
78
|
+
if (naturalId.length === 1 && naturalId[0] !== undefined) {
|
|
79
|
+
uniqueFields.add(naturalId[0]);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
indexes.push({ fields: [...naturalId], isUnique: true });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { indexes, uniqueFields };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=jpaIndexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaIndexes.js","sourceRoot":"","sources":["../../src/parsers/jpaIndexes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQlD,kEAAkE;AAClE,SAAS,eAAe,CACtB,IAAY;IAEZ,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;SACrC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;QACpB,MAAM,KAAK,GAA4B,IAAI,CAAC,KAAK,CAC/C,4BAA4B,CAC7B,CAAC;QACF,OAAO;YACL,MAAM,EAAE,eAAe,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACpD,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM;SACxD,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAkB,EAClB,KAAkC,EAClC,SAA4B,EAC5B,IAA+B;IAE/B,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAgB,IAAI,GAAG,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAW,MAAM,CAAC,IAAI,CAAC;IAClC,MAAM,KAAK,GAAoB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,CAAC,OAAiB,EAAE,KAAa,EAAwB,EAAE;QACzE,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,KAAK,GACT,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,CACF,GAAG,KAAK,KAAK,KAAK,eAAe,MAAM,wDAAwD,CAChG,CAAC;gBACF,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtD,CAAC,CAAC;IACF,MAAM,IAAI,GAAgB,IAAI,GAAG,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,CACV,OAAiB,EACjB,MAAe,EACf,IAAwB,EACxB,UAAqB,EACrB,KAAa,EACP,EAAE;QACR,MAAM,MAAM,GAAyB,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAW,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACpF,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,IAAI,GAAuB,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;YACjE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QACD,MAAM,YAAY,GAAwC,EAAE,CAAC;QAC7D,UAAU,CAAC,OAAO,CAAC,CAAC,IAAa,EAAE,QAAgB,EAAE,EAAE;YACrD,MAAM,KAAK,GAAuB,MAAM,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAChC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC;YACX,MAAM;YACN,QAAQ,EAAE,MAAM;YAChB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;SACpE,CAAC,CAAC;IACL,CAAC,CAAC;IACF,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC;QACvE,MAAM,IAAI,GAAuB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAa,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC5D,GAAG,CACD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAC5B,IAAI,EACJ,IAAI,EACJ,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EACxB,wBAAwB,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,GAAuB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,GAAG,CACD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAChC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,EAChC,IAAI,EACJ,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EACpC,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACvC,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACzD,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { IrOnDelete } from '../ir.js';
|
|
2
|
+
import type { Ann } from './jpaAnnotations.js';
|
|
3
|
+
import type { BuiltField } from './jpaColumns.js';
|
|
4
|
+
import type { EntityInfo, Member, Project } from './jpaModel.js';
|
|
5
|
+
import type { IrCompositeForeignKey, IrField, IrRelation } from '../ir.js';
|
|
6
|
+
/** A primary key column of an entity: the IR name of its field (or relation) and the database column. */
|
|
7
|
+
export interface KeyColumn {
|
|
8
|
+
name: string;
|
|
9
|
+
columnName: string;
|
|
10
|
+
}
|
|
11
|
+
/** Everything the relationship steps look up. */
|
|
12
|
+
export interface Resolver {
|
|
13
|
+
project: Project;
|
|
14
|
+
entities: Map<string, EntityInfo>;
|
|
15
|
+
warn: (message: string) => void;
|
|
16
|
+
/** Built fields of every model, by model name, for the types of foreign key columns. */
|
|
17
|
+
fieldsOf: (model: EntityInfo) => readonly BuiltField[];
|
|
18
|
+
/** The primary key columns of an entity's table. */
|
|
19
|
+
keyOf: (entity: EntityInfo) => KeyColumn[];
|
|
20
|
+
}
|
|
21
|
+
/** A relationship placed on a model, with the position of its attribute (for ordering). */
|
|
22
|
+
export interface PlacedRelation {
|
|
23
|
+
order: number;
|
|
24
|
+
relation: IrRelation;
|
|
25
|
+
}
|
|
26
|
+
export interface RelationOutput {
|
|
27
|
+
relations: PlacedRelation[];
|
|
28
|
+
composite: IrCompositeForeignKey[];
|
|
29
|
+
/** Local columns that composite foreign keys need and no attribute declares. */
|
|
30
|
+
extraFields: IrField[];
|
|
31
|
+
/** Paths (`a.b`) of scalar members whose column a relationship now carries. */
|
|
32
|
+
consumed: Map<string, string>;
|
|
33
|
+
/** Relationships that belong on another model (a one-to-many with a join column). */
|
|
34
|
+
foreign: {
|
|
35
|
+
model: EntityInfo;
|
|
36
|
+
relation: IrRelation;
|
|
37
|
+
}[];
|
|
38
|
+
/** The inverse sides: the owning relationship named `attribute` on `model` gets `relatedName`. */
|
|
39
|
+
inverse: {
|
|
40
|
+
model: EntityInfo;
|
|
41
|
+
attribute: string;
|
|
42
|
+
relatedName: string;
|
|
43
|
+
}[];
|
|
44
|
+
}
|
|
45
|
+
/** The model a table belongs to: single-table subclasses live in the table of their root. */
|
|
46
|
+
export declare function modelOwner(entity: EntityInfo): EntityInfo;
|
|
47
|
+
export declare function relationAnnotation(member: Member): Ann;
|
|
48
|
+
/** The entity a relationship points at: `targetEntity`, else the (element) type of the attribute. */
|
|
49
|
+
export declare function targetOf(member: Member, annotation: Ann, resolver: Resolver): EntityInfo | undefined;
|
|
50
|
+
/** `@JoinColumn` entries of an attribute: one, several (`@JoinColumns`), or none. */
|
|
51
|
+
export declare function joinColumnsOf(member: Member): Ann[];
|
|
52
|
+
export interface JoinPair {
|
|
53
|
+
/** The column in the table that holds the foreign key. */
|
|
54
|
+
columnName: string;
|
|
55
|
+
/** The key column of the target it points at. */
|
|
56
|
+
target: KeyColumn;
|
|
57
|
+
nullable: boolean | undefined;
|
|
58
|
+
unique: boolean;
|
|
59
|
+
constraint?: Ann;
|
|
60
|
+
}
|
|
61
|
+
/** Pairs each join column with the target key column it refers to, applying the JPA default names. */
|
|
62
|
+
export declare function joinPairs(member: Member, target: EntityInfo, resolver: Resolver, place: string): JoinPair[] | undefined;
|
|
63
|
+
/** The referential action of a relationship: `@OnDelete` or, for none, the database default. */
|
|
64
|
+
export declare function onDeleteOf(member: Member, place: string, resolver: Resolver): IrOnDelete;
|
|
65
|
+
export declare function cascadeNote(member: Member, annotation: Ann, place: string, resolver: Resolver): void;
|
|
66
|
+
export declare function constraintName(pair: JoinPair | undefined, member: Member, place: string, resolver: Resolver): string | undefined;
|
|
67
|
+
/** The table name of an entity: `@Table(name)`, else the entity name. */
|
|
68
|
+
export declare function tableNameOf(entity: EntityInfo): string;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { cleanIdentifier } from './jpaColumns.js';
|
|
2
|
+
import { onDeleteAction } from './jpaTypes.js';
|
|
3
|
+
const RELATION_NAMES = [
|
|
4
|
+
'ManyToOne',
|
|
5
|
+
'OneToOne',
|
|
6
|
+
'OneToMany',
|
|
7
|
+
'ManyToMany',
|
|
8
|
+
];
|
|
9
|
+
/** The model a table belongs to: single-table subclasses live in the table of their root. */
|
|
10
|
+
export function modelOwner(entity) {
|
|
11
|
+
return entity.inheritance === 'singleTable' ? entity.root : entity;
|
|
12
|
+
}
|
|
13
|
+
export function relationAnnotation(member) {
|
|
14
|
+
for (const name of RELATION_NAMES) {
|
|
15
|
+
const found = member.attr.notes.get(name);
|
|
16
|
+
if (found !== undefined) {
|
|
17
|
+
return found;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// Callers only pass members that carry one of the four annotations.
|
|
21
|
+
throw new Error(`${member.attr.name} has no relationship annotation`);
|
|
22
|
+
}
|
|
23
|
+
/** The entity a relationship points at: `targetEntity`, else the (element) type of the attribute. */
|
|
24
|
+
export function targetOf(member, annotation, resolver) {
|
|
25
|
+
const type = member.attr.type;
|
|
26
|
+
const named = annotation.className('targetEntity') ??
|
|
27
|
+
(type.args.length > 0 ? type.args[type.args.length - 1]?.name : type.name);
|
|
28
|
+
return named === undefined ? undefined : resolver.entities.get(named);
|
|
29
|
+
}
|
|
30
|
+
/** `@JoinColumn` entries of an attribute: one, several (`@JoinColumns`), or none. */
|
|
31
|
+
export function joinColumnsOf(member) {
|
|
32
|
+
return member.attr.notes.repeated('JoinColumn', 'JoinColumns');
|
|
33
|
+
}
|
|
34
|
+
/** The column a join column refers to: a key column, or any other column of the target (a unique one, usually). */
|
|
35
|
+
function referencedKey(keys, target, columnName, resolver) {
|
|
36
|
+
const wanted = columnName.toLowerCase();
|
|
37
|
+
const key = keys.find((item) => item.columnName.toLowerCase() === wanted);
|
|
38
|
+
if (key !== undefined) {
|
|
39
|
+
return key;
|
|
40
|
+
}
|
|
41
|
+
const other = resolver
|
|
42
|
+
.fieldsOf(target)
|
|
43
|
+
.find((item) => item.field.columnName.toLowerCase() === wanted);
|
|
44
|
+
return other === undefined
|
|
45
|
+
? undefined
|
|
46
|
+
: { name: other.field.name, columnName: other.field.columnName };
|
|
47
|
+
}
|
|
48
|
+
/** Pairs each join column with the target key column it refers to, applying the JPA default names. */
|
|
49
|
+
export function joinPairs(member, target, resolver, place) {
|
|
50
|
+
const keys = resolver.keyOf(target);
|
|
51
|
+
const columns = joinColumnsOf(member);
|
|
52
|
+
if (keys.length === 0) {
|
|
53
|
+
resolver.warn(`${place}: the target ${target.name} has no primary key, so the foreign key cannot be placed.`);
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
if (columns.length === 0) {
|
|
57
|
+
return keys.map((key) => ({
|
|
58
|
+
columnName: `${member.attr.name}_${key.columnName}`,
|
|
59
|
+
target: key,
|
|
60
|
+
nullable: undefined,
|
|
61
|
+
unique: false,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
const pairs = [];
|
|
65
|
+
columns.forEach((column, position) => {
|
|
66
|
+
const referenced = column.string('referencedColumnName');
|
|
67
|
+
const key = referenced === undefined || referenced === ''
|
|
68
|
+
? (keys[position] ?? keys[0])
|
|
69
|
+
: referencedKey(keys, target, cleanIdentifier(referenced), resolver);
|
|
70
|
+
const named = column.string('name');
|
|
71
|
+
if (key === undefined) {
|
|
72
|
+
resolver.warn(`${place}: the join column refers to "${referenced ?? ''}", which is not a key column of ${target.name}; the relationship was skipped.`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const constraint = column.annotation('foreignKey');
|
|
76
|
+
pairs.push({
|
|
77
|
+
columnName: named === undefined || named === ''
|
|
78
|
+
? `${member.attr.name}_${key.columnName}`
|
|
79
|
+
: cleanIdentifier(named),
|
|
80
|
+
target: key,
|
|
81
|
+
nullable: column.boolean('nullable'),
|
|
82
|
+
unique: column.boolean('unique') ?? false,
|
|
83
|
+
...(constraint === undefined ? {} : { constraint }),
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
return pairs.length === columns.length ? pairs : undefined;
|
|
87
|
+
}
|
|
88
|
+
/** The referential action of a relationship: `@OnDelete` or, for none, the database default. */
|
|
89
|
+
export function onDeleteOf(member, place, resolver) {
|
|
90
|
+
const action = member.attr.notes.get('OnDelete', true);
|
|
91
|
+
const name = action?.member('action');
|
|
92
|
+
if (name === undefined) {
|
|
93
|
+
return 'noAction';
|
|
94
|
+
}
|
|
95
|
+
const mapped = onDeleteAction(name);
|
|
96
|
+
if (mapped === undefined) {
|
|
97
|
+
resolver.warn(`${place}: the @OnDelete action ${name} is not known; the database default (no action) was used.`);
|
|
98
|
+
return 'noAction';
|
|
99
|
+
}
|
|
100
|
+
return mapped;
|
|
101
|
+
}
|
|
102
|
+
export function cascadeNote(member, annotation, place, resolver) {
|
|
103
|
+
const cascade = annotation.members('cascade');
|
|
104
|
+
const removes = cascade.some((name) => name === 'REMOVE' || name === 'ALL');
|
|
105
|
+
const orphan = annotation.boolean('orphanRemoval') === true;
|
|
106
|
+
if (!removes && !orphan) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const cascadesInDatabase = member.attr.notes.get('OnDelete', true)?.member('action') === 'CASCADE';
|
|
110
|
+
if (!cascadesInDatabase) {
|
|
111
|
+
resolver.warn(`${place}: ${removes ? `cascade ${cascade.includes('ALL') ? 'ALL' : 'REMOVE'}` : 'orphanRemoval'} deletes children through the ORM only; it adds no ON DELETE CASCADE to the foreign key, which is written as read (add @OnDelete(action = OnDeleteAction.CASCADE) on the owning side for that).`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function constraintName(pair, member, place, resolver) {
|
|
115
|
+
const own = pair?.constraint ??
|
|
116
|
+
member.attr.notes.get('JoinColumn')?.annotation('foreignKey');
|
|
117
|
+
const legacy = member.attr.notes.get('ForeignKey', true);
|
|
118
|
+
if (own?.member('value') === 'NO_CONSTRAINT') {
|
|
119
|
+
resolver.warn(`${place}: ConstraintMode.NO_CONSTRAINT means Hibernate creates no foreign key constraint; it was read as a foreign key.`);
|
|
120
|
+
}
|
|
121
|
+
const name = own?.string('name') ?? legacy?.string('name');
|
|
122
|
+
return name === undefined || name === '' ? undefined : name;
|
|
123
|
+
}
|
|
124
|
+
/** The table name of an entity: `@Table(name)`, else the entity name. */
|
|
125
|
+
export function tableNameOf(entity) {
|
|
126
|
+
const given = entity.notes.get('Table')?.string('name');
|
|
127
|
+
return given === undefined || given === ''
|
|
128
|
+
? entity.entityName
|
|
129
|
+
: cleanIdentifier(given);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=jpaJoins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaJoins.js","sourceRoot":"","sources":["../../src/parsers/jpaJoins.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAuC/C,MAAM,cAAc,GAAsB;IACxC,WAAW;IACX,UAAU;IACV,WAAW;IACX,YAAY;CACb,CAAC;AAEF,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,OAAO,MAAM,CAAC,WAAW,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,KAAK,GAAoB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,oEAAoE;IACpE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,iCAAiC,CAAC,CAAC;AACxE,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,QAAQ,CACtB,MAAc,EACd,UAAe,EACf,QAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9B,MAAM,KAAK,GACT,UAAU,CAAC,SAAS,CAAC,cAAc,CAAC;QACpC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxE,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;AACjE,CAAC;AAYD,mHAAmH;AACnH,SAAS,aAAa,CACpB,IAA0B,EAC1B,MAAkB,EAClB,UAAkB,EAClB,QAAkB;IAElB,MAAM,MAAM,GAAW,UAAU,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,GAAG,GAA0B,IAAI,CAAC,IAAI,CAC1C,CAAC,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,MAAM,CAC9D,CAAC;IACF,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,KAAK,GAA2B,QAAQ;SAC3C,QAAQ,CAAC,MAAM,CAAC;SAChB,IAAI,CAAC,CAAC,IAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;IAC9E,OAAO,KAAK,KAAK,SAAS;QACxB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;AACrE,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,MAAkB,EAClB,QAAkB,EAClB,KAAa;IAEb,MAAM,IAAI,GAAgB,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAU,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CACX,GAAG,KAAK,gBAAgB,MAAM,CAAC,IAAI,2DAA2D,CAC/F,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAc,EAAY,EAAE,CAAC,CAAC;YAC7C,UAAU,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE;YACnD,MAAM,EAAE,GAAG;YACX,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,KAAK;SACd,CAAC,CAAC,CAAC;IACN,CAAC;IACD,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,QAAgB,EAAE,EAAE;QAChD,MAAM,UAAU,GAAuB,MAAM,CAAC,MAAM,CAClD,sBAAsB,CACvB,CAAC;QACF,MAAM,GAAG,GACP,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,EAAE;YAC3C,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzE,MAAM,KAAK,GAAuB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CACX,GAAG,KAAK,gCAAgC,UAAU,IAAI,EAAE,mCAAmC,MAAM,CAAC,IAAI,iCAAiC,CACxI,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAoB,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC;YACT,UAAU,EACR,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;gBACjC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE;gBACzC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC;YAC5B,MAAM,EAAE,GAAG;YACX,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;YACpC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK;YACzC,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;SACpD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,UAAU,CACxB,MAAc,EACd,KAAa,EACb,QAAkB;IAElB,MAAM,MAAM,GAAoB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACxE,MAAM,IAAI,GAAuB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,MAAM,GAA2B,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CACX,GAAG,KAAK,0BAA0B,IAAI,2DAA2D,CAClG,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,UAAe,EACf,KAAa,EACb,QAAkB;IAElB,MAAM,OAAO,GAAa,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,OAAO,GAAY,OAAO,CAAC,IAAI,CACnC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,KAAK,CACtD,CAAC;IACF,MAAM,MAAM,GAAY,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IACrE,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IACD,MAAM,kBAAkB,GACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;IAC1E,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CACX,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,eAAe,iMAAiM,CAClS,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAA0B,EAC1B,MAAc,EACd,KAAa,EACb,QAAkB;IAElB,MAAM,GAAG,GACP,IAAI,EAAE,UAAU;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAChE,MAAM,MAAM,GAAoB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC1E,IAAI,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,eAAe,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CACX,GAAG,KAAK,iHAAiH,CAC1H,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GACR,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,MAAM,KAAK,GAAuB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5E,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QACxC,CAAC,CAAC,MAAM,CAAC,UAAU;QACnB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Ann, Annotated } from './jpaAnnotations.js';
|
|
2
|
+
import type { ConstLookup, JavaClass, JavaType, SyntaxNode } from './javaSyntax.js';
|
|
3
|
+
/** What the reader knows about the whole input; shared by every step. */
|
|
4
|
+
export interface Project {
|
|
5
|
+
/** Every class of the input by simple name (enums are in `enums`). */
|
|
6
|
+
classes: Map<string, JavaClass>;
|
|
7
|
+
/** Java `enum` types by simple name. */
|
|
8
|
+
enums: Map<string, JavaClass>;
|
|
9
|
+
/** `AttributeConverter` classes by simple name. */
|
|
10
|
+
converters: Map<string, ConverterInfo>;
|
|
11
|
+
lookup: ConstLookup;
|
|
12
|
+
warnings: string[];
|
|
13
|
+
appLabel: string;
|
|
14
|
+
}
|
|
15
|
+
/** An `AttributeConverter<X, Y>` class: attributes of type X are stored as Y. */
|
|
16
|
+
export interface ConverterInfo {
|
|
17
|
+
name: string;
|
|
18
|
+
attributeType: JavaType;
|
|
19
|
+
columnType: JavaType;
|
|
20
|
+
autoApply: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** A mapped attribute of a class: a field, or a getter under property access. */
|
|
23
|
+
export interface Attribute {
|
|
24
|
+
name: string;
|
|
25
|
+
type: JavaType;
|
|
26
|
+
notes: Annotated;
|
|
27
|
+
/** The class that declares the attribute. */
|
|
28
|
+
declaredIn: string;
|
|
29
|
+
/** The class's imports, to tell `java.sql.Date` from `java.util.Date`. */
|
|
30
|
+
imports: readonly string[];
|
|
31
|
+
isProperty: boolean;
|
|
32
|
+
initializer?: SyntaxNode;
|
|
33
|
+
}
|
|
34
|
+
export type MemberKind = 'basic' | 'relation' | 'collection';
|
|
35
|
+
/** An attribute of an entity after embeddables are flattened into it. */
|
|
36
|
+
export interface Member {
|
|
37
|
+
attr: Attribute;
|
|
38
|
+
/** Attribute names from the entity down to this attribute: `['address', 'street']`. */
|
|
39
|
+
path: string[];
|
|
40
|
+
kind: MemberKind;
|
|
41
|
+
/** The `@Column` that applies: from the closest `@AttributeOverride`, else the attribute's own. */
|
|
42
|
+
column?: Ann;
|
|
43
|
+
/** True for `@Id` attributes and the attributes of an `@EmbeddedId`. */
|
|
44
|
+
isId: boolean;
|
|
45
|
+
/** True for the attributes of an `@EmbeddedId`. */
|
|
46
|
+
inEmbeddedId: boolean;
|
|
47
|
+
/** The entity class the member belongs to (the subclass in a hierarchy). */
|
|
48
|
+
declaredIn: string;
|
|
49
|
+
}
|
|
50
|
+
export type InheritanceKind = 'none' | 'singleTable' | 'joined' | 'tablePerClass';
|
|
51
|
+
/** An entity class with its position in a hierarchy. */
|
|
52
|
+
export interface EntityInfo {
|
|
53
|
+
cls: JavaClass;
|
|
54
|
+
/** The class name, which is also the IR model name. */
|
|
55
|
+
name: string;
|
|
56
|
+
/** The JPA entity name: `@Entity(name)`, else the class name. */
|
|
57
|
+
entityName: string;
|
|
58
|
+
notes: Annotated;
|
|
59
|
+
/** The superclasses in the input, root first, ending with the class itself. */
|
|
60
|
+
chain: JavaClass[];
|
|
61
|
+
/** The access type of each class of `chain`. */
|
|
62
|
+
accesses: ('field' | 'property')[];
|
|
63
|
+
/** The closest superclass that is an entity, when there is one. */
|
|
64
|
+
parent?: EntityInfo;
|
|
65
|
+
/** The entities that extend this one directly. */
|
|
66
|
+
children: EntityInfo[];
|
|
67
|
+
/** The first entity of the hierarchy. */
|
|
68
|
+
root: EntityInfo;
|
|
69
|
+
inheritance: InheritanceKind;
|
|
70
|
+
isAbstract: boolean;
|
|
71
|
+
/** The attributes that become columns or relationships of this entity's table. */
|
|
72
|
+
members: Member[];
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaModel.js","sourceRoot":"","sources":["../../src/parsers/jpaModel.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IrField, IrRelation } from '../ir.js';
|
|
2
|
+
import type { BuiltField } from './jpaColumns.js';
|
|
3
|
+
import type { EntityInfo } from './jpaModel.js';
|
|
4
|
+
import type { Resolver } from './jpaJoins.js';
|
|
5
|
+
/** What the inheritance of an entity adds to its model. */
|
|
6
|
+
export interface InheritanceParts {
|
|
7
|
+
leadingFields: IrField[];
|
|
8
|
+
trailingFields: IrField[];
|
|
9
|
+
relations: IrRelation[];
|
|
10
|
+
/** Set when the primary key is the foreign key to the parent table (joined inheritance). */
|
|
11
|
+
primaryKeyRelation?: IrRelation;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads the inheritance strategy. Single-table subclasses are merged into the root (the discriminator column is
|
|
15
|
+
* added), joined subclasses get the foreign key to their parent as primary key, and table-per-class entities
|
|
16
|
+
* are independent tables; each case warns, because the shared model has no inheritance.
|
|
17
|
+
*/
|
|
18
|
+
export declare function inheritanceNotes(entity: EntityInfo, fields: readonly IrField[], resolver: Resolver): InheritanceParts;
|
|
19
|
+
/** Warns about table-level settings that have no place in the shared model. */
|
|
20
|
+
export declare function tableNotes(entity: EntityInfo, built: readonly BuiltField[], warn: (message: string) => void): void;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { toCamelCase } from '../naming.js';
|
|
2
|
+
import { decapitalize, onDeleteAction } from './jpaTypes.js';
|
|
3
|
+
function descendants(entity) {
|
|
4
|
+
return entity.children.flatMap((child) => [
|
|
5
|
+
child,
|
|
6
|
+
...descendants(child),
|
|
7
|
+
]);
|
|
8
|
+
}
|
|
9
|
+
/** The discriminator value of an entity: `@DiscriminatorValue`, else the entity name. */
|
|
10
|
+
function discriminatorValue(entity) {
|
|
11
|
+
return (entity.notes.get('DiscriminatorValue')?.string('value') ?? entity.entityName);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads the inheritance strategy. Single-table subclasses are merged into the root (the discriminator column is
|
|
15
|
+
* added), joined subclasses get the foreign key to their parent as primary key, and table-per-class entities
|
|
16
|
+
* are independent tables; each case warns, because the shared model has no inheritance.
|
|
17
|
+
*/
|
|
18
|
+
export function inheritanceNotes(entity, fields, resolver) {
|
|
19
|
+
const parts = {
|
|
20
|
+
leadingFields: [],
|
|
21
|
+
trailingFields: [],
|
|
22
|
+
relations: [],
|
|
23
|
+
};
|
|
24
|
+
const warn = resolver.warn;
|
|
25
|
+
if (entity.inheritance === 'singleTable' &&
|
|
26
|
+
entity.root === entity &&
|
|
27
|
+
entity.children.length > 0) {
|
|
28
|
+
const column = entity.notes.get('DiscriminatorColumn');
|
|
29
|
+
const columnName = column?.string('name') || 'DTYPE';
|
|
30
|
+
const kind = column?.member('discriminatorType') ?? 'STRING';
|
|
31
|
+
const all = descendants(entity);
|
|
32
|
+
if (entity.notes.has('DiscriminatorFormula', true)) {
|
|
33
|
+
warn(`${entity.name}: @DiscriminatorFormula is computed in SQL and has no equivalent; a plain discriminator column was assumed.`);
|
|
34
|
+
}
|
|
35
|
+
if (!fields.some((field) => field.columnName === columnName)) {
|
|
36
|
+
parts.trailingFields.push({
|
|
37
|
+
name: toCamelCase(columnName),
|
|
38
|
+
columnName,
|
|
39
|
+
type: kind === 'INTEGER' ? 'int' : 'string',
|
|
40
|
+
isPrimaryKey: false,
|
|
41
|
+
isUnique: false,
|
|
42
|
+
isNullable: false,
|
|
43
|
+
isAutoUpdated: false,
|
|
44
|
+
...(kind === 'INTEGER'
|
|
45
|
+
? {}
|
|
46
|
+
: {
|
|
47
|
+
maxLength: kind === 'CHAR' ? 1 : (column?.number('length') ?? 31),
|
|
48
|
+
}),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
warn(`${entity.name}: ${all.map((child) => child.name).join(', ')} extend${all.length === 1 ? 's' : ''} ${entity.name} in one table (single table inheritance). ` +
|
|
52
|
+
`The hierarchy was read as a single model with the columns of every class and the discriminator column "${columnName}" (values: ${[entity, ...all].map((item) => `${discriminatorValue(item)} = ${item.name}`).join(', ')}); the subclasses are not separate models. A column that a subclass declares NOT NULL stays NOT NULL, as in the DDL Hibernate writes.`);
|
|
53
|
+
}
|
|
54
|
+
if (entity.inheritance === 'joined' && entity.parent !== undefined) {
|
|
55
|
+
const parent = entity.parent;
|
|
56
|
+
const keys = resolver.keyOf(entity);
|
|
57
|
+
const only = keys[0];
|
|
58
|
+
if (only === undefined || keys.length > 1) {
|
|
59
|
+
warn(`${entity.name}: the parent ${parent.name} has a composite key; the join to the parent table was not read.`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const name = decapitalize(parent.name);
|
|
63
|
+
const action = entity.notes
|
|
64
|
+
.get('OnDelete', true)
|
|
65
|
+
?.member('action');
|
|
66
|
+
const onDelete = (action === undefined ? undefined : onDeleteAction(action)) ??
|
|
67
|
+
'noAction';
|
|
68
|
+
const relation = {
|
|
69
|
+
name,
|
|
70
|
+
kind: 'oneToOne',
|
|
71
|
+
targetModel: parent.name,
|
|
72
|
+
columnName: only.columnName,
|
|
73
|
+
isNullable: false,
|
|
74
|
+
onDelete,
|
|
75
|
+
isPrimaryKey: true,
|
|
76
|
+
};
|
|
77
|
+
parts.relations.push(relation);
|
|
78
|
+
parts.primaryKeyRelation = relation;
|
|
79
|
+
}
|
|
80
|
+
warn(`${entity.name}: extends ${parent.name} with joined table inheritance. It was read as a model of its own whose primary key is also a foreign key to ${parent.name} (a one-to-one primary key relation); the attributes inherited from ${parent.name} stay on ${parent.name}.`);
|
|
81
|
+
}
|
|
82
|
+
if (entity.inheritance === 'joined' && entity.root === entity) {
|
|
83
|
+
const column = entity.notes.get('DiscriminatorColumn');
|
|
84
|
+
if (column !== undefined) {
|
|
85
|
+
const columnName = column.string('name') || 'DTYPE';
|
|
86
|
+
parts.trailingFields.push({
|
|
87
|
+
name: toCamelCase(columnName),
|
|
88
|
+
columnName,
|
|
89
|
+
type: column.member('discriminatorType') === 'INTEGER' ? 'int' : 'string',
|
|
90
|
+
isPrimaryKey: false,
|
|
91
|
+
isUnique: false,
|
|
92
|
+
isNullable: false,
|
|
93
|
+
isAutoUpdated: false,
|
|
94
|
+
maxLength: column.number('length') ?? 31,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (entity.inheritance === 'tablePerClass') {
|
|
99
|
+
warn(`${entity.name}: table per class inheritance (${entity.parent === undefined ? 'root' : `extends ${entity.parent.name}`}). ${entity.name} was read as an independent table with all inherited columns; the shared model does not link it to the other classes of the hierarchy.`);
|
|
100
|
+
}
|
|
101
|
+
return parts;
|
|
102
|
+
}
|
|
103
|
+
/** Warns about table-level settings that have no place in the shared model. */
|
|
104
|
+
export function tableNotes(entity, built, warn) {
|
|
105
|
+
const notes = entity.notes;
|
|
106
|
+
const place = entity.name;
|
|
107
|
+
if (notes.has('SecondaryTable') || notes.has('SecondaryTables')) {
|
|
108
|
+
warn(`${place}: @SecondaryTable stores some attributes in a second table; all attributes were read into the primary table.`);
|
|
109
|
+
}
|
|
110
|
+
if (notes.has('Check', true) || notes.has('Checks', true)) {
|
|
111
|
+
warn(`${place}: the @Check constraint has no equivalent in the shared model and was dropped.`);
|
|
112
|
+
}
|
|
113
|
+
const comments = built
|
|
114
|
+
.filter((item) => item.member.attr.notes.has('Comment', true))
|
|
115
|
+
.map((item) => item.member.attr.name);
|
|
116
|
+
if (notes.has('Comment', true) || notes.get('Table', true)?.has('comment')) {
|
|
117
|
+
comments.unshift('the table');
|
|
118
|
+
}
|
|
119
|
+
if (comments.length > 0) {
|
|
120
|
+
warn(`${place}: comments (${comments.join(', ')}) are not preserved.`);
|
|
121
|
+
}
|
|
122
|
+
const checks = built
|
|
123
|
+
.filter((item) => item.member.attr.notes.has('Check', true))
|
|
124
|
+
.map((item) => item.member.attr.name);
|
|
125
|
+
if (checks.length > 0) {
|
|
126
|
+
warn(`${place}: the @Check constraints on ${checks.join(', ')} have no equivalent in the shared model and were dropped.`);
|
|
127
|
+
}
|
|
128
|
+
if (notes.has('SqlResultSetMapping') || notes.has('SqlResultSetMappings')) {
|
|
129
|
+
warn(`${place}: @SqlResultSetMapping maps query results, not tables, and was ignored.`);
|
|
130
|
+
}
|
|
131
|
+
if (notes.has('Audited', true) || notes.has('Audited')) {
|
|
132
|
+
warn(`${place}: @Audited (Hibernate Envers) also creates an audit table and a revision table, which are not read.`);
|
|
133
|
+
}
|
|
134
|
+
if (built.some((item) => item.member.attr.notes.has('TenantId', true))) {
|
|
135
|
+
warn(`${place}: a @TenantId column is part of the table; it was read as an ordinary column of the attribute's type.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=jpaNotes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaNotes.js","sourceRoot":"","sources":["../../src/parsers/jpaNotes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type RelationOutput, type Resolver } from './jpaJoins.js';
|
|
2
|
+
import type { EntityInfo, Member } from './jpaModel.js';
|
|
3
|
+
/** Resolves the relationship attributes of one model. */
|
|
4
|
+
export declare function resolveRelations(model: EntityInfo, members: readonly Member[], resolver: Resolver): RelationOutput;
|