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,304 @@
|
|
|
1
|
+
import { findModel } from '../ir.js';
|
|
2
|
+
import { toSnakeCase } from '../naming.js';
|
|
3
|
+
import { annotation, } from './jpaFormat.js';
|
|
4
|
+
import { attributeNameOf, javaString, uniqueName } from './jpaNames.js';
|
|
5
|
+
import { Imports, } from './jpaTypes.js';
|
|
6
|
+
const ON_DELETE = {
|
|
7
|
+
cascade: 'CASCADE',
|
|
8
|
+
setNull: 'SET_NULL',
|
|
9
|
+
setDefault: 'SET_DEFAULT',
|
|
10
|
+
restrict: 'RESTRICT',
|
|
11
|
+
noAction: undefined,
|
|
12
|
+
};
|
|
13
|
+
function planOf(ctx, name) {
|
|
14
|
+
return ctx.plans.get(name);
|
|
15
|
+
}
|
|
16
|
+
/** The column and Java type of the single-column key of a model, or undefined when it has none. */
|
|
17
|
+
export function singleKey(ctx, model) {
|
|
18
|
+
const info = ctx.keys.get(model.name);
|
|
19
|
+
const part = info?.parts.length === 1 ? info.parts[0] : undefined;
|
|
20
|
+
if (part === undefined) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return part.kind === 'field'
|
|
24
|
+
? { column: part.field.columnName, field: part.field }
|
|
25
|
+
: { column: part.relation.columnName };
|
|
26
|
+
}
|
|
27
|
+
/** The column a foreign key refers to: `toField`, else the single key of the target. */
|
|
28
|
+
function referencedColumn(ctx, target, toField) {
|
|
29
|
+
if (toField !== undefined) {
|
|
30
|
+
const field = target.fields.find((item) => item.name === toField) ??
|
|
31
|
+
target.fields.find((item) => item.columnName === toField);
|
|
32
|
+
return field?.columnName;
|
|
33
|
+
}
|
|
34
|
+
return singleKey(ctx, target)?.column;
|
|
35
|
+
}
|
|
36
|
+
function onDeleteNode(ctx, label, imports, action) {
|
|
37
|
+
const name = ON_DELETE[action];
|
|
38
|
+
if (name === undefined) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
if (ctx.style === 'javax' && action !== 'cascade') {
|
|
42
|
+
ctx.warn(`${label}: Hibernate 5 knows only ON DELETE CASCADE (@OnDelete); the ${name.replace('_', ' ')} action was dropped and the database default (no action) applies.`);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const type = imports.hibernate('OnDeleteAction');
|
|
46
|
+
return annotation(imports.hibernate('OnDelete'), [
|
|
47
|
+
['action', `${type}.${name}`],
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
function joinColumn(imports, name, referenced, extra) {
|
|
51
|
+
return annotation(imports.persistence('JoinColumn'), [
|
|
52
|
+
['name', javaString(name)],
|
|
53
|
+
['referencedColumnName', javaString(referenced)],
|
|
54
|
+
...extra,
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
57
|
+
function foreignKeyArgument(imports, constraintName) {
|
|
58
|
+
return constraintName === undefined
|
|
59
|
+
? []
|
|
60
|
+
: [
|
|
61
|
+
[
|
|
62
|
+
'foreignKey',
|
|
63
|
+
annotation(imports.persistence('ForeignKey'), [
|
|
64
|
+
['name', javaString(constraintName)],
|
|
65
|
+
]),
|
|
66
|
+
],
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function sideArguments(imports, optional, lazy) {
|
|
70
|
+
const args = [];
|
|
71
|
+
if (!optional) {
|
|
72
|
+
args.push(['optional', 'false']);
|
|
73
|
+
}
|
|
74
|
+
if (lazy) {
|
|
75
|
+
args.push(['fetch', `${imports.persistence('FetchType')}.LAZY`]);
|
|
76
|
+
}
|
|
77
|
+
return args;
|
|
78
|
+
}
|
|
79
|
+
/** True when the relation is a part of the primary key of its model. */
|
|
80
|
+
function isKeyRelation(info, relation) {
|
|
81
|
+
return (info?.parts.some((part) => part.kind === 'relation' && part.relation === relation) ?? false);
|
|
82
|
+
}
|
|
83
|
+
function collectionOf(imports, kind) {
|
|
84
|
+
imports.use(`java.util.${kind}`);
|
|
85
|
+
imports.use(kind === 'List' ? 'java.util.ArrayList' : 'java.util.HashSet');
|
|
86
|
+
return kind;
|
|
87
|
+
}
|
|
88
|
+
/** Adds the owning side of every relation of one model; returns the relations that are part of its key. */
|
|
89
|
+
export function addOwningRelations(ctx, plan) {
|
|
90
|
+
const model = plan.model;
|
|
91
|
+
const keyRelations = new Map();
|
|
92
|
+
const info = ctx.keys.get(model.name);
|
|
93
|
+
for (const relation of model.relations) {
|
|
94
|
+
const label = `${model.name}.${relation.name}`;
|
|
95
|
+
const target = findModel(ctx.schema, relation.targetModel);
|
|
96
|
+
const targetPlan = planOf(ctx, relation.targetModel);
|
|
97
|
+
if (target === undefined || targetPlan === undefined) {
|
|
98
|
+
ctx.warn(`${label}: the model ${relation.targetModel} is not in the input, so the relation was skipped${relation.kind === 'manyToMany' ? '' : ' and its column left out'}.`);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (relation.kind === 'manyToMany') {
|
|
102
|
+
addManyToMany(ctx, plan, targetPlan, relation);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const referenced = referencedColumn(ctx, target, relation.toField);
|
|
106
|
+
if (referenced === undefined) {
|
|
107
|
+
ctx.warn(`${label}: ${relation.targetModel} has no single-column key to reference, so the relation was skipped and its column left out.`);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const imports = new Imports(ctx.style);
|
|
111
|
+
const attributeName = uniqueName(attributeNameOf(relation.name), plan.used);
|
|
112
|
+
plan.relationNames.set(relation.name, attributeName);
|
|
113
|
+
const isKey = isKeyRelation(info, relation);
|
|
114
|
+
const oneToOne = relation.kind === 'oneToOne';
|
|
115
|
+
const required = !relation.isNullable || isKey;
|
|
116
|
+
if (relation.onUpdate !== undefined) {
|
|
117
|
+
ctx.warn(`${label}: JPA has no setting for the onUpdate action "${relation.onUpdate}", so it was ignored.`);
|
|
118
|
+
}
|
|
119
|
+
if (!relation.isNullable && relation.onDelete === 'setNull') {
|
|
120
|
+
ctx.warn(`${label}: SET NULL on a required relation; the column is NOT NULL, so deleting a ${relation.targetModel} that is referenced fails.`);
|
|
121
|
+
}
|
|
122
|
+
const annotations = [];
|
|
123
|
+
if (isKey) {
|
|
124
|
+
annotations.push(annotation(imports.persistence('Id')));
|
|
125
|
+
}
|
|
126
|
+
annotations.push(annotation(imports.persistence(oneToOne ? 'OneToOne' : 'ManyToOne'), sideArguments(imports, !required, !isKey)), joinColumn(imports, relation.columnName, referenced, [
|
|
127
|
+
...(required ? [['nullable', 'false']] : []),
|
|
128
|
+
...foreignKeyArgument(imports, relation.constraintName),
|
|
129
|
+
]));
|
|
130
|
+
const action = onDeleteNode(ctx, label, imports, relation.onDelete);
|
|
131
|
+
if (action !== undefined) {
|
|
132
|
+
annotations.push(action);
|
|
133
|
+
}
|
|
134
|
+
const attribute = {
|
|
135
|
+
name: attributeName,
|
|
136
|
+
type: targetPlan.className,
|
|
137
|
+
annotations,
|
|
138
|
+
imports,
|
|
139
|
+
};
|
|
140
|
+
plan.attributes.push(attribute);
|
|
141
|
+
if (isKey) {
|
|
142
|
+
const keyType = ctx.keyTypes.get(target.name);
|
|
143
|
+
keyRelations.set(relation, {
|
|
144
|
+
attribute: attributeName,
|
|
145
|
+
type: keyType?.type ?? 'Object',
|
|
146
|
+
imports: keyType?.imports ?? imports,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (relation.relatedName !== undefined) {
|
|
150
|
+
ctx.inverses.push({
|
|
151
|
+
owner: plan,
|
|
152
|
+
target: targetPlan,
|
|
153
|
+
kind: oneToOne ? 'oneToOne' : 'oneToMany',
|
|
154
|
+
mappedBy: attributeName,
|
|
155
|
+
relatedName: relation.relatedName,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const key of model.compositeForeignKeys ?? []) {
|
|
160
|
+
addCompositeKey(ctx, plan, key);
|
|
161
|
+
}
|
|
162
|
+
return keyRelations;
|
|
163
|
+
}
|
|
164
|
+
/** The column of a field of the model, by name or column name. */
|
|
165
|
+
function columnOfField(model, name) {
|
|
166
|
+
return (model.fields.find((item) => item.name === name)?.columnName ??
|
|
167
|
+
model.fields.find((item) => item.columnName === name)?.columnName);
|
|
168
|
+
}
|
|
169
|
+
function addCompositeKey(ctx, plan, key) {
|
|
170
|
+
const model = plan.model;
|
|
171
|
+
const label = `${model.name}.${key.name}`;
|
|
172
|
+
const target = findModel(ctx.schema, key.targetModel);
|
|
173
|
+
const targetPlan = planOf(ctx, key.targetModel);
|
|
174
|
+
const locals = key.fields.map((name) => columnOfField(model, name));
|
|
175
|
+
const referenced = key.references.map((name) => target === undefined ? undefined : columnOfField(target, name));
|
|
176
|
+
if (target === undefined ||
|
|
177
|
+
targetPlan === undefined ||
|
|
178
|
+
locals.some((column) => column === undefined) ||
|
|
179
|
+
referenced.some((column) => column === undefined)) {
|
|
180
|
+
ctx.warn(`${label}: a column of the composite foreign key to ${key.targetModel} is not a field of the models, so the relation was skipped.`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (key.onUpdate !== undefined) {
|
|
184
|
+
ctx.warn(`${label}: JPA has no setting for the onUpdate action "${key.onUpdate}", so it was ignored.`);
|
|
185
|
+
}
|
|
186
|
+
if (!key.isNullable && key.onDelete === 'setNull') {
|
|
187
|
+
ctx.warn(`${label}: SET NULL on a required relation; the columns are NOT NULL, so deleting a ${key.targetModel} that is referenced fails.`);
|
|
188
|
+
}
|
|
189
|
+
const imports = new Imports(ctx.style);
|
|
190
|
+
const attributeName = uniqueName(attributeNameOf(key.name), plan.used);
|
|
191
|
+
plan.relationNames.set(`composite:${key.name}`, attributeName);
|
|
192
|
+
const oneToOne = key.kind === 'oneToOne';
|
|
193
|
+
const columns = locals.map((column, position) => joinColumn(imports, column ?? '', referenced[position] ?? '', [
|
|
194
|
+
['insertable', 'false'],
|
|
195
|
+
['updatable', 'false'],
|
|
196
|
+
]));
|
|
197
|
+
const annotations = [
|
|
198
|
+
annotation(imports.persistence(oneToOne ? 'OneToOne' : 'ManyToOne'), sideArguments(imports, key.isNullable, true)),
|
|
199
|
+
annotation(imports.persistence('JoinColumns'), [
|
|
200
|
+
[key.constraintName === undefined ? undefined : 'value', columns],
|
|
201
|
+
...foreignKeyArgument(imports, key.constraintName),
|
|
202
|
+
]),
|
|
203
|
+
];
|
|
204
|
+
const action = onDeleteNode(ctx, label, imports, key.onDelete);
|
|
205
|
+
if (action !== undefined) {
|
|
206
|
+
annotations.push(action);
|
|
207
|
+
}
|
|
208
|
+
plan.attributes.push({
|
|
209
|
+
name: attributeName,
|
|
210
|
+
type: targetPlan.className,
|
|
211
|
+
annotations,
|
|
212
|
+
imports,
|
|
213
|
+
});
|
|
214
|
+
if (key.relatedName !== undefined) {
|
|
215
|
+
ctx.inverses.push({
|
|
216
|
+
owner: plan,
|
|
217
|
+
target: targetPlan,
|
|
218
|
+
kind: oneToOne ? 'oneToOne' : 'oneToMany',
|
|
219
|
+
mappedBy: attributeName,
|
|
220
|
+
relatedName: key.relatedName,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function addManyToMany(ctx, plan, targetPlan, relation) {
|
|
225
|
+
const model = plan.model;
|
|
226
|
+
const label = `${model.name}.${relation.name}`;
|
|
227
|
+
const ownerKey = singleKey(ctx, model);
|
|
228
|
+
const targetKey = singleKey(ctx, targetPlan.model);
|
|
229
|
+
if (ownerKey === undefined || targetKey === undefined) {
|
|
230
|
+
ctx.warn(`${label}: a many-to-many relation needs a single-column key on both models; the relation was skipped.`);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const imports = new Imports(ctx.style);
|
|
234
|
+
const attributeName = uniqueName(attributeNameOf(relation.name), plan.used);
|
|
235
|
+
plan.relationNames.set(relation.name, attributeName);
|
|
236
|
+
const isSelf = model.name === relation.targetModel;
|
|
237
|
+
const ownerColumn = `${isSelf ? 'from_' : ''}${toSnakeCase(model.name)}_id`;
|
|
238
|
+
const targetColumn = `${isSelf ? 'to_' : ''}${toSnakeCase(relation.targetModel)}_id`;
|
|
239
|
+
const table = annotation(imports.persistence('JoinTable'), [
|
|
240
|
+
['name', javaString(`${model.tableName}_${relation.name}`)],
|
|
241
|
+
...(model.schema === undefined
|
|
242
|
+
? []
|
|
243
|
+
: [['schema', javaString(model.schema)]]),
|
|
244
|
+
['joinColumns', joinColumn(imports, ownerColumn, ownerKey.column, [])],
|
|
245
|
+
[
|
|
246
|
+
'inverseJoinColumns',
|
|
247
|
+
joinColumn(imports, targetColumn, targetKey.column, []),
|
|
248
|
+
],
|
|
249
|
+
]);
|
|
250
|
+
const kind = collectionOf(imports, 'Set');
|
|
251
|
+
plan.attributes.push({
|
|
252
|
+
name: attributeName,
|
|
253
|
+
type: `${kind}<${targetPlan.className}>`,
|
|
254
|
+
annotations: [annotation(imports.persistence('ManyToMany')), table],
|
|
255
|
+
initializer: 'new HashSet<>()',
|
|
256
|
+
imports,
|
|
257
|
+
});
|
|
258
|
+
if (relation.relatedName !== undefined) {
|
|
259
|
+
ctx.inverses.push({
|
|
260
|
+
owner: plan,
|
|
261
|
+
target: targetPlan,
|
|
262
|
+
kind: 'manyToMany',
|
|
263
|
+
mappedBy: attributeName,
|
|
264
|
+
relatedName: relation.relatedName,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/** Adds the inverse side (`mappedBy`) of every relation that names one. */
|
|
269
|
+
export function addInverseRelations(ctx) {
|
|
270
|
+
for (const link of ctx.inverses) {
|
|
271
|
+
const imports = new Imports(ctx.style);
|
|
272
|
+
const name = uniqueName(attributeNameOf(link.relatedName), link.target.used);
|
|
273
|
+
const mapped = [
|
|
274
|
+
['mappedBy', javaString(link.mappedBy)],
|
|
275
|
+
];
|
|
276
|
+
const owner = link.owner.className;
|
|
277
|
+
let node;
|
|
278
|
+
let type;
|
|
279
|
+
let initializer;
|
|
280
|
+
switch (link.kind) {
|
|
281
|
+
case 'oneToOne':
|
|
282
|
+
node = annotation(imports.persistence('OneToOne'), mapped);
|
|
283
|
+
type = owner;
|
|
284
|
+
break;
|
|
285
|
+
case 'oneToMany':
|
|
286
|
+
node = annotation(imports.persistence('OneToMany'), mapped);
|
|
287
|
+
type = `${collectionOf(imports, 'List')}<${owner}>`;
|
|
288
|
+
initializer = 'new ArrayList<>()';
|
|
289
|
+
break;
|
|
290
|
+
default:
|
|
291
|
+
node = annotation(imports.persistence('ManyToMany'), mapped);
|
|
292
|
+
type = `${collectionOf(imports, 'Set')}<${owner}>`;
|
|
293
|
+
initializer = 'new HashSet<>()';
|
|
294
|
+
}
|
|
295
|
+
link.target.attributes.push({
|
|
296
|
+
name,
|
|
297
|
+
type,
|
|
298
|
+
annotations: [node],
|
|
299
|
+
imports,
|
|
300
|
+
...(initializer === undefined ? {} : { initializer }),
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=jpaRelations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaRelations.js","sourceRoot":"","sources":["../../src/emitters/jpaRelations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Imports, type ModelPlan } from './jpaTypes.js';
|
|
2
|
+
export interface FileLayout {
|
|
3
|
+
packageName: string;
|
|
4
|
+
/** Write the `// <auto-generated>` comment at the top of every file. */
|
|
5
|
+
header: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Assembles a Java file: the header comment, the package, the sorted imports and the body. */
|
|
8
|
+
export declare function renderFile(layout: FileLayout, imports: Imports, body: readonly string[]): string;
|
|
9
|
+
/** The text of an entity class file. */
|
|
10
|
+
export declare function renderEntity(plan: ModelPlan, layout: FileLayout): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { formatAnnotation } from './jpaFormat.js';
|
|
2
|
+
import { capitalize } from './jpaNames.js';
|
|
3
|
+
import { Imports } from './jpaTypes.js';
|
|
4
|
+
/** Turns the plan of a model into the text of its Java file. */
|
|
5
|
+
const INDENT = ' ';
|
|
6
|
+
/** Assembles a Java file: the header comment, the package, the sorted imports and the body. */
|
|
7
|
+
export function renderFile(layout, imports, body) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
if (layout.header) {
|
|
10
|
+
lines.push('// <auto-generated>', '// Generated by ormbridge. Review the output before use.', '// </auto-generated>');
|
|
11
|
+
}
|
|
12
|
+
lines.push(`package ${layout.packageName};`, '');
|
|
13
|
+
const importLines = imports.lines();
|
|
14
|
+
if (importLines.length > 0) {
|
|
15
|
+
lines.push(...importLines, '');
|
|
16
|
+
}
|
|
17
|
+
lines.push(...body);
|
|
18
|
+
return `${lines.join('\n')}\n`;
|
|
19
|
+
}
|
|
20
|
+
/** The getter and setter names of an attribute (`isFeatured` of a boolean is `isFeatured()` and `setFeatured`). */
|
|
21
|
+
function accessorNames(attribute) {
|
|
22
|
+
const name = attribute.name;
|
|
23
|
+
if (attribute.isPrimitiveBoolean === true) {
|
|
24
|
+
const prefixed = name.match(/^is([A-Z].*)$/);
|
|
25
|
+
return prefixed === null
|
|
26
|
+
? { get: `is${capitalize(name)}`, set: `set${capitalize(name)}` }
|
|
27
|
+
: { get: name, set: `set${prefixed[1] ?? ''}` };
|
|
28
|
+
}
|
|
29
|
+
return { get: `get${capitalize(name)}`, set: `set${capitalize(name)}` };
|
|
30
|
+
}
|
|
31
|
+
function attributeLines(attribute) {
|
|
32
|
+
const lines = [];
|
|
33
|
+
for (const node of attribute.annotations) {
|
|
34
|
+
lines.push(...formatAnnotation(node, INDENT.length));
|
|
35
|
+
}
|
|
36
|
+
lines.push(`${INDENT}private ${attribute.type} ${attribute.name}${attribute.initializer === undefined ? '' : ` = ${attribute.initializer}`};`);
|
|
37
|
+
return lines;
|
|
38
|
+
}
|
|
39
|
+
function accessorLines(attribute) {
|
|
40
|
+
const names = accessorNames(attribute);
|
|
41
|
+
return [
|
|
42
|
+
`${INDENT}public ${attribute.type} ${names.get}() {`,
|
|
43
|
+
`${INDENT}${INDENT}return ${attribute.name};`,
|
|
44
|
+
`${INDENT}}`,
|
|
45
|
+
'',
|
|
46
|
+
`${INDENT}public void ${names.set}(${attribute.type} ${attribute.name}) {`,
|
|
47
|
+
`${INDENT}${INDENT}this.${attribute.name} = ${attribute.name};`,
|
|
48
|
+
`${INDENT}}`,
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
/** The text of an entity class file. */
|
|
52
|
+
export function renderEntity(plan, layout) {
|
|
53
|
+
const imports = new Imports('jakarta');
|
|
54
|
+
imports.merge(plan.imports);
|
|
55
|
+
for (const attribute of plan.attributes) {
|
|
56
|
+
imports.merge(attribute.imports);
|
|
57
|
+
}
|
|
58
|
+
const body = [];
|
|
59
|
+
for (const node of plan.classAnnotations) {
|
|
60
|
+
body.push(...formatAnnotation(node, 0));
|
|
61
|
+
}
|
|
62
|
+
if (plan.serializable === true) {
|
|
63
|
+
imports.use('java.io.Serializable');
|
|
64
|
+
}
|
|
65
|
+
body.push(`public class ${plan.className}${plan.serializable === true ? ' implements Serializable' : ''} {`);
|
|
66
|
+
if (plan.serializable === true) {
|
|
67
|
+
body.push(`${INDENT}private static final long serialVersionUID = 1L;`, '');
|
|
68
|
+
}
|
|
69
|
+
plan.attributes.forEach((attribute, position) => {
|
|
70
|
+
if (position > 0) {
|
|
71
|
+
body.push('');
|
|
72
|
+
}
|
|
73
|
+
body.push(...attributeLines(attribute));
|
|
74
|
+
});
|
|
75
|
+
for (const attribute of plan.attributes) {
|
|
76
|
+
body.push('', ...accessorLines(attribute));
|
|
77
|
+
}
|
|
78
|
+
body.push('}');
|
|
79
|
+
return renderFile(layout, imports, body);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=jpaRender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpaRender.js","sourceRoot":"","sources":["../../src/emitters/jpaRender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IrField } from '../ir.js';
|
|
2
|
+
import { type AnnotationNode } from './jpaFormat.js';
|
|
3
|
+
import type { Imports, JpaStyle } from './jpaTypes.js';
|
|
4
|
+
import type { PrismaProvider } from './prisma.js';
|
|
5
|
+
/** The Java type, the extra annotations and the column facets of one IR scalar type. */
|
|
6
|
+
export interface Scalar {
|
|
7
|
+
/** The boxed Java type (`Integer`, `String`, `Map<String, Object>`). */
|
|
8
|
+
boxed: string;
|
|
9
|
+
/** The primitive Java type, for a column that cannot be null. */
|
|
10
|
+
primitive?: string;
|
|
11
|
+
/** `@Column(length)` for a string. */
|
|
12
|
+
length?: number;
|
|
13
|
+
/** `@Column(precision, scale)` for a decimal. */
|
|
14
|
+
precision?: {
|
|
15
|
+
precision: number;
|
|
16
|
+
scale: number;
|
|
17
|
+
};
|
|
18
|
+
/** `@Column(columnDefinition)`, for a type the Java type does not say. */
|
|
19
|
+
columnDefinition?: string;
|
|
20
|
+
/** Annotations that go with the type (`@Lob`, `@JdbcTypeCode`). */
|
|
21
|
+
extra: AnnotationNode[];
|
|
22
|
+
}
|
|
23
|
+
export interface ScalarContext {
|
|
24
|
+
style: JpaStyle;
|
|
25
|
+
provider: PrismaProvider;
|
|
26
|
+
imports: Imports;
|
|
27
|
+
warn: (message: string) => void;
|
|
28
|
+
}
|
|
29
|
+
/** The facets that a Prisma `@db.*` native type adds to a field the type alone leaves open. */
|
|
30
|
+
export declare function withNativeFacets(field: IrField): IrField;
|
|
31
|
+
/** Maps one scalar IR field (arrays are handled by the caller) to a Java type. */
|
|
32
|
+
export declare function scalarOf(context: ScalarContext, label: string, field: IrField): Scalar;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { isCockroach } from './cockroach.js';
|
|
2
|
+
import { isPostgres } from './jpaDefaults.js';
|
|
3
|
+
import { annotation } from './jpaFormat.js';
|
|
4
|
+
const RANGE_TYPES = {
|
|
5
|
+
int: 'int4range',
|
|
6
|
+
bigInt: 'int8range',
|
|
7
|
+
decimal: 'numrange',
|
|
8
|
+
date: 'daterange',
|
|
9
|
+
dateTime: 'tsrange',
|
|
10
|
+
};
|
|
11
|
+
/** The facets that a Prisma `@db.*` native type adds to a field the type alone leaves open. */
|
|
12
|
+
export function withNativeFacets(field) {
|
|
13
|
+
const native = field.nativeType;
|
|
14
|
+
if (native === undefined) {
|
|
15
|
+
return field;
|
|
16
|
+
}
|
|
17
|
+
const name = native.name.toLowerCase();
|
|
18
|
+
const first = Number(native.args[0]);
|
|
19
|
+
const second = Number(native.args[1] ?? 0);
|
|
20
|
+
if ((name === 'varchar' || name === 'char') &&
|
|
21
|
+
field.type === 'string' &&
|
|
22
|
+
field.maxLength === undefined &&
|
|
23
|
+
Number.isInteger(first)) {
|
|
24
|
+
return { ...field, maxLength: first };
|
|
25
|
+
}
|
|
26
|
+
if ((name === 'decimal' || name === 'numeric') &&
|
|
27
|
+
field.type === 'decimal' &&
|
|
28
|
+
field.maxDigits === undefined &&
|
|
29
|
+
Number.isInteger(first)) {
|
|
30
|
+
return {
|
|
31
|
+
...field,
|
|
32
|
+
maxDigits: first,
|
|
33
|
+
decimalPlaces: Number.isInteger(second) ? second : 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return field;
|
|
37
|
+
}
|
|
38
|
+
/** True when the column keeps a time zone, judging by the native type Prisma gave it. */
|
|
39
|
+
function hasTimeZone(field) {
|
|
40
|
+
return /timestamptz|datetimeoffset|with time zone/i.test(field.nativeType?.name ?? '');
|
|
41
|
+
}
|
|
42
|
+
/** A large text column: a `text` column on PostgreSQL, `@Lob` elsewhere. */
|
|
43
|
+
function largeText(context) {
|
|
44
|
+
const boxed = context.imports.use('java.lang.String');
|
|
45
|
+
if (isPostgres(context.provider)) {
|
|
46
|
+
return { boxed, columnDefinition: 'text', extra: [] };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
boxed,
|
|
50
|
+
extra: [annotation(context.imports.persistence('Lob'))],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** A JSON column: Hibernate 6 maps it itself, Hibernate 5 has no JSON type. */
|
|
54
|
+
function jsonColumn(context, label) {
|
|
55
|
+
const { imports } = context;
|
|
56
|
+
if (context.style === 'jakarta') {
|
|
57
|
+
imports.use('java.util.Map');
|
|
58
|
+
return {
|
|
59
|
+
boxed: 'Map<String, Object>',
|
|
60
|
+
extra: [
|
|
61
|
+
annotation(imports.hibernate('JdbcTypeCode'), [
|
|
62
|
+
[undefined, `${imports.use('org.hibernate.type.SqlTypes')}.JSON`],
|
|
63
|
+
]),
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const definition = isPostgres(context.provider)
|
|
68
|
+
? 'jsonb'
|
|
69
|
+
: context.provider === 'mysql'
|
|
70
|
+
? 'json'
|
|
71
|
+
: undefined;
|
|
72
|
+
context.warn(`${label}: Hibernate 5 has no JSON type; the column was written as a String${definition === undefined ? ' of large text' : ` with the column definition ${definition}`}, and the JSON text is yours to read and write (the hibernate-types library adds a mapping).`);
|
|
73
|
+
return definition === undefined
|
|
74
|
+
? largeText(context)
|
|
75
|
+
: {
|
|
76
|
+
boxed: imports.use('java.lang.String'),
|
|
77
|
+
columnDefinition: definition,
|
|
78
|
+
extra: [],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function stringWith(context, columnDefinition) {
|
|
82
|
+
return {
|
|
83
|
+
boxed: context.imports.use('java.lang.String'),
|
|
84
|
+
...(columnDefinition === undefined ? {} : { columnDefinition }),
|
|
85
|
+
extra: [],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Maps one scalar IR field (arrays are handled by the caller) to a Java type. */
|
|
89
|
+
export function scalarOf(context, label, field) {
|
|
90
|
+
const { imports } = context;
|
|
91
|
+
const postgres = isPostgres(context.provider);
|
|
92
|
+
switch (field.type) {
|
|
93
|
+
case 'string':
|
|
94
|
+
if (field.maxLength === undefined) {
|
|
95
|
+
if (postgres) {
|
|
96
|
+
return largeText(context);
|
|
97
|
+
}
|
|
98
|
+
// Large text columns cannot be keys, unique or indexed outside PostgreSQL; a string is meant to be.
|
|
99
|
+
context.warn(`${label}: a string without a length was written with the JPA default length of 255, because ${context.provider} cannot index a large text column.`);
|
|
100
|
+
return { ...stringWith(context, undefined), length: 255 };
|
|
101
|
+
}
|
|
102
|
+
return { ...stringWith(context, undefined), length: field.maxLength };
|
|
103
|
+
case 'text':
|
|
104
|
+
return largeText(context);
|
|
105
|
+
case 'int':
|
|
106
|
+
// GenerationType.IDENTITY creates SERIAL on CockroachDB, which fills 64-bit unique_rowid() values.
|
|
107
|
+
return isCockroach(context.provider) &&
|
|
108
|
+
field.default?.kind === 'autoIncrement'
|
|
109
|
+
? { boxed: 'Long', primitive: 'long', extra: [] }
|
|
110
|
+
: { boxed: 'Integer', primitive: 'int', extra: [] };
|
|
111
|
+
case 'bigInt':
|
|
112
|
+
return { boxed: 'Long', primitive: 'long', extra: [] };
|
|
113
|
+
case 'float':
|
|
114
|
+
return { boxed: 'Double', primitive: 'double', extra: [] };
|
|
115
|
+
case 'boolean':
|
|
116
|
+
return { boxed: 'Boolean', primitive: 'boolean', extra: [] };
|
|
117
|
+
case 'decimal': {
|
|
118
|
+
const digits = field.maxDigits ?? (field.decimalPlaces === undefined ? undefined : 38);
|
|
119
|
+
return {
|
|
120
|
+
boxed: imports.use('java.math.BigDecimal'),
|
|
121
|
+
extra: [],
|
|
122
|
+
...(digits === undefined
|
|
123
|
+
? {}
|
|
124
|
+
: {
|
|
125
|
+
precision: {
|
|
126
|
+
precision: digits,
|
|
127
|
+
scale: field.decimalPlaces ?? 0,
|
|
128
|
+
},
|
|
129
|
+
}),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
case 'dateTime':
|
|
133
|
+
return {
|
|
134
|
+
boxed: imports.use(hasTimeZone(field)
|
|
135
|
+
? 'java.time.OffsetDateTime'
|
|
136
|
+
: 'java.time.LocalDateTime'),
|
|
137
|
+
extra: [],
|
|
138
|
+
};
|
|
139
|
+
case 'date':
|
|
140
|
+
return { boxed: imports.use('java.time.LocalDate'), extra: [] };
|
|
141
|
+
case 'time':
|
|
142
|
+
return { boxed: imports.use('java.time.LocalTime'), extra: [] };
|
|
143
|
+
case 'duration':
|
|
144
|
+
return { boxed: imports.use('java.time.Duration'), extra: [] };
|
|
145
|
+
case 'uuid':
|
|
146
|
+
return { boxed: imports.use('java.util.UUID'), extra: [] };
|
|
147
|
+
case 'bytes':
|
|
148
|
+
return postgres
|
|
149
|
+
? { boxed: 'byte[]', extra: [] }
|
|
150
|
+
: {
|
|
151
|
+
boxed: 'byte[]',
|
|
152
|
+
extra: [annotation(imports.persistence('Lob'))],
|
|
153
|
+
};
|
|
154
|
+
case 'json':
|
|
155
|
+
return jsonColumn(context, label);
|
|
156
|
+
case 'ipAddress':
|
|
157
|
+
if (postgres && context.style === 'jakarta') {
|
|
158
|
+
return {
|
|
159
|
+
boxed: imports.use('java.net.InetAddress'),
|
|
160
|
+
extra: [
|
|
161
|
+
annotation(imports.hibernate('JdbcTypeCode'), [
|
|
162
|
+
[undefined, `${imports.use('org.hibernate.type.SqlTypes')}.INET`],
|
|
163
|
+
]),
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (postgres) {
|
|
168
|
+
context.warn(`${label}: Hibernate 5 has no inet mapping; the column was written as a String with the column definition inet.`);
|
|
169
|
+
return stringWith(context, 'inet');
|
|
170
|
+
}
|
|
171
|
+
context.warn(`${label}: only PostgreSQL has an inet type; the column was written as a string of at most 45 characters.`);
|
|
172
|
+
return { ...stringWith(context, undefined), length: 45 };
|
|
173
|
+
case 'hstore':
|
|
174
|
+
if (isCockroach(context.provider)) {
|
|
175
|
+
context.warn(`${label}: CockroachDB has no hstore type; the column was written as a JSON column.`);
|
|
176
|
+
return jsonColumn(context, label);
|
|
177
|
+
}
|
|
178
|
+
context.warn(postgres
|
|
179
|
+
? `${label}: Hibernate has no hstore mapping; the column was written as a String with the column definition hstore.`
|
|
180
|
+
: `${label}: hstore is a PostgreSQL type; the column was written as large text.`);
|
|
181
|
+
return postgres ? stringWith(context, 'hstore') : largeText(context);
|
|
182
|
+
case 'range': {
|
|
183
|
+
const range = field.rangeOf === undefined ? undefined : RANGE_TYPES[field.rangeOf];
|
|
184
|
+
if (isCockroach(context.provider)) {
|
|
185
|
+
context.warn(`${label}: CockroachDB has no range types (int4range, tstzrange, ...); the column was written as large text.`);
|
|
186
|
+
return largeText(context);
|
|
187
|
+
}
|
|
188
|
+
if (postgres && range !== undefined) {
|
|
189
|
+
context.warn(`${label}: Hibernate has no range mapping; the column was written as a String with the column definition ${range}.`);
|
|
190
|
+
return stringWith(context, range);
|
|
191
|
+
}
|
|
192
|
+
context.warn(`${label}: range types exist only in PostgreSQL; the column was written as large text.`);
|
|
193
|
+
return largeText(context);
|
|
194
|
+
}
|
|
195
|
+
case 'unsupported':
|
|
196
|
+
default:
|
|
197
|
+
context.warn(`${label}: the database type "${field.unsupportedType ?? 'unknown'}" has no Java mapping; the column was written as a String${field.unsupportedType === undefined ? '' : ` with the column definition ${field.unsupportedType}`}.`);
|
|
198
|
+
return stringWith(context, field.unsupportedType);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=jpaScalars.js.map
|