@mikro-orm/knex 6.0.0-dev.11 → 6.0.0-dev.111
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/AbstractSqlConnection.d.ts +8 -4
- package/AbstractSqlConnection.js +30 -18
- package/AbstractSqlDriver.d.ts +16 -17
- package/AbstractSqlDriver.js +283 -118
- package/AbstractSqlPlatform.d.ts +5 -4
- package/AbstractSqlPlatform.js +34 -5
- package/MonkeyPatchable.d.ts +1 -0
- package/MonkeyPatchable.js +3 -0
- package/README.md +64 -107
- package/SqlEntityManager.d.ts +2 -6
- package/SqlEntityManager.js +5 -9
- package/SqlEntityRepository.d.ts +7 -6
- package/SqlEntityRepository.js +11 -8
- package/index.mjs +22 -6
- package/package.json +8 -8
- package/query/ArrayCriteriaNode.d.ts +3 -3
- package/query/CriteriaNode.d.ts +8 -8
- package/query/CriteriaNode.js +16 -9
- package/query/CriteriaNodeFactory.d.ts +6 -6
- package/query/CriteriaNodeFactory.js +10 -13
- package/query/ObjectCriteriaNode.d.ts +3 -3
- package/query/ObjectCriteriaNode.js +12 -8
- package/query/QueryBuilder.d.ts +39 -19
- package/query/QueryBuilder.js +331 -111
- package/query/QueryBuilderHelper.d.ts +9 -13
- package/query/QueryBuilderHelper.js +153 -107
- package/query/ScalarCriteriaNode.d.ts +3 -2
- package/query/ScalarCriteriaNode.js +9 -6
- package/query/enums.js +1 -1
- package/schema/DatabaseSchema.d.ts +5 -2
- package/schema/DatabaseSchema.js +26 -8
- package/schema/DatabaseTable.d.ts +4 -2
- package/schema/DatabaseTable.js +55 -30
- package/schema/SchemaComparator.js +12 -2
- package/schema/SchemaHelper.d.ts +6 -4
- package/schema/SchemaHelper.js +11 -4
- package/schema/SqlSchemaGenerator.d.ts +3 -6
- package/schema/SqlSchemaGenerator.js +61 -28
- package/typings.d.ts +13 -7
package/schema/DatabaseSchema.js
CHANGED
|
@@ -7,15 +7,19 @@ const DatabaseTable_1 = require("./DatabaseTable");
|
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
class DatabaseSchema {
|
|
10
|
+
platform;
|
|
11
|
+
name;
|
|
12
|
+
tables = [];
|
|
13
|
+
namespaces = new Set();
|
|
14
|
+
nativeEnums = {}; // for postgres
|
|
10
15
|
constructor(platform, name) {
|
|
11
16
|
this.platform = platform;
|
|
12
17
|
this.name = name;
|
|
13
|
-
this.tables = [];
|
|
14
|
-
this.namespaces = new Set();
|
|
15
18
|
}
|
|
16
19
|
addTable(name, schema, comment) {
|
|
17
20
|
const namespaceName = schema ?? this.name;
|
|
18
21
|
const table = new DatabaseTable_1.DatabaseTable(this.platform, name, namespaceName);
|
|
22
|
+
table.nativeEnums = this.nativeEnums;
|
|
19
23
|
table.comment = comment;
|
|
20
24
|
this.tables.push(table);
|
|
21
25
|
if (namespaceName != null) {
|
|
@@ -32,24 +36,38 @@ class DatabaseSchema {
|
|
|
32
36
|
hasTable(name) {
|
|
33
37
|
return !!this.getTable(name);
|
|
34
38
|
}
|
|
39
|
+
setNativeEnums(nativeEnums) {
|
|
40
|
+
this.nativeEnums = nativeEnums;
|
|
41
|
+
this.tables.forEach(t => t.nativeEnums = nativeEnums);
|
|
42
|
+
}
|
|
43
|
+
getNativeEnums() {
|
|
44
|
+
return this.nativeEnums;
|
|
45
|
+
}
|
|
35
46
|
hasNamespace(namespace) {
|
|
36
47
|
return this.namespaces.has(namespace);
|
|
37
48
|
}
|
|
38
49
|
getNamespaces() {
|
|
39
50
|
return [...this.namespaces];
|
|
40
51
|
}
|
|
41
|
-
static async create(connection, platform, config, schemaName) {
|
|
42
|
-
const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema'));
|
|
52
|
+
static async create(connection, platform, config, schemaName, schemas) {
|
|
53
|
+
const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema') ?? platform.getDefaultSchemaName());
|
|
43
54
|
const allTables = await connection.execute(platform.getSchemaHelper().getListTablesSQL());
|
|
44
55
|
const parts = config.get('migrations').tableName.split('.');
|
|
45
56
|
const migrationsTableName = parts[1] ?? parts[0];
|
|
46
57
|
const migrationsSchemaName = parts.length > 1 ? parts[0] : config.get('schema', platform.getDefaultSchemaName());
|
|
47
58
|
const tables = allTables.filter(t => t.table_name !== migrationsTableName || (t.schema_name && t.schema_name !== migrationsSchemaName));
|
|
48
|
-
await platform.getSchemaHelper().loadInformationSchema(schema, connection, tables);
|
|
59
|
+
await platform.getSchemaHelper().loadInformationSchema(schema, connection, tables, schemas && schemas.length > 0 ? schemas : undefined);
|
|
49
60
|
return schema;
|
|
50
61
|
}
|
|
51
62
|
static fromMetadata(metadata, platform, config, schemaName) {
|
|
52
63
|
const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema'));
|
|
64
|
+
const nativeEnums = {};
|
|
65
|
+
for (const meta of metadata) {
|
|
66
|
+
meta.props
|
|
67
|
+
.filter(prop => prop.nativeEnumName)
|
|
68
|
+
.forEach(prop => nativeEnums[prop.nativeEnumName] = prop.items?.map(val => '' + val) ?? []);
|
|
69
|
+
}
|
|
70
|
+
schema.setNativeEnums(nativeEnums);
|
|
53
71
|
for (const meta of metadata) {
|
|
54
72
|
const table = schema.addTable(meta.collection, this.getSchemaName(meta, config, schemaName));
|
|
55
73
|
table.comment = meta.comment;
|
|
@@ -78,15 +96,15 @@ class DatabaseSchema {
|
|
|
78
96
|
if (prop.persist === false || !prop.fieldNames) {
|
|
79
97
|
return false;
|
|
80
98
|
}
|
|
81
|
-
if (meta.pivotTable || (core_1.
|
|
99
|
+
if (meta.pivotTable || (core_1.ReferenceKind.EMBEDDED && prop.object)) {
|
|
82
100
|
return true;
|
|
83
101
|
}
|
|
84
102
|
const getRootProperty = (prop) => prop.embedded ? getRootProperty(meta.properties[prop.embedded[0]]) : prop;
|
|
85
103
|
const rootProp = getRootProperty(prop);
|
|
86
|
-
if (rootProp.
|
|
104
|
+
if (rootProp.kind === core_1.ReferenceKind.EMBEDDED) {
|
|
87
105
|
return prop === rootProp || !rootProp.object;
|
|
88
106
|
}
|
|
89
|
-
return [core_1.
|
|
107
|
+
return [core_1.ReferenceKind.SCALAR, core_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind) || (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && prop.owner);
|
|
90
108
|
}
|
|
91
109
|
toJSON() {
|
|
92
110
|
const { platform, namespaces, ...rest } = this;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Dictionary, type EntityMetadata, type EntityProperty, type NamingStrategy } from '@mikro-orm/core';
|
|
2
2
|
import type { SchemaHelper } from './SchemaHelper';
|
|
3
3
|
import type { CheckDef, Column, ForeignKey, IndexDef } from '../typings';
|
|
4
4
|
import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
|
|
@@ -13,10 +13,12 @@ export declare class DatabaseTable {
|
|
|
13
13
|
private indexes;
|
|
14
14
|
private checks;
|
|
15
15
|
private foreignKeys;
|
|
16
|
+
nativeEnums: Dictionary<unknown[]>;
|
|
16
17
|
comment?: string;
|
|
17
18
|
constructor(platform: AbstractSqlPlatform, name: string, schema?: string | undefined);
|
|
18
19
|
getColumns(): Column[];
|
|
19
20
|
getColumn(name: string): Column | undefined;
|
|
21
|
+
removeColumn(name: string): void;
|
|
20
22
|
getIndexes(): IndexDef[];
|
|
21
23
|
getChecks(): CheckDef[];
|
|
22
24
|
init(cols: Column[], indexes: IndexDef[] | undefined, checks: CheckDef<unknown>[] | undefined, pks: string[], fks?: Dictionary<ForeignKey>, enums?: Dictionary<string[]>): void;
|
|
@@ -37,7 +39,7 @@ export declare class DatabaseTable {
|
|
|
37
39
|
getPrimaryKey(): IndexDef | undefined;
|
|
38
40
|
hasPrimaryKey(): boolean;
|
|
39
41
|
private getPropertyDeclaration;
|
|
40
|
-
private
|
|
42
|
+
private getReferenceKind;
|
|
41
43
|
private getPropertyName;
|
|
42
44
|
private getPropertyType;
|
|
43
45
|
private getPropertyDefaultValue;
|
package/schema/DatabaseTable.js
CHANGED
|
@@ -6,14 +6,19 @@ const core_1 = require("@mikro-orm/core");
|
|
|
6
6
|
* @internal
|
|
7
7
|
*/
|
|
8
8
|
class DatabaseTable {
|
|
9
|
+
platform;
|
|
10
|
+
name;
|
|
11
|
+
schema;
|
|
12
|
+
columns = {};
|
|
13
|
+
indexes = [];
|
|
14
|
+
checks = [];
|
|
15
|
+
foreignKeys = {};
|
|
16
|
+
nativeEnums = {}; // for postgres
|
|
17
|
+
comment;
|
|
9
18
|
constructor(platform, name, schema) {
|
|
10
19
|
this.platform = platform;
|
|
11
20
|
this.name = name;
|
|
12
21
|
this.schema = schema;
|
|
13
|
-
this.columns = {};
|
|
14
|
-
this.indexes = [];
|
|
15
|
-
this.checks = [];
|
|
16
|
-
this.foreignKeys = {};
|
|
17
22
|
Object.defineProperties(this, {
|
|
18
23
|
platform: { enumerable: false, writable: true },
|
|
19
24
|
});
|
|
@@ -24,8 +29,11 @@ class DatabaseTable {
|
|
|
24
29
|
getColumn(name) {
|
|
25
30
|
return this.columns[name];
|
|
26
31
|
}
|
|
32
|
+
removeColumn(name) {
|
|
33
|
+
delete this.columns[name];
|
|
34
|
+
}
|
|
27
35
|
getIndexes() {
|
|
28
|
-
return this.indexes;
|
|
36
|
+
return core_1.Utils.removeDuplicates(this.indexes);
|
|
29
37
|
}
|
|
30
38
|
getChecks() {
|
|
31
39
|
return this.checks;
|
|
@@ -41,7 +49,7 @@ class DatabaseTable {
|
|
|
41
49
|
const type = v.name in enums ? 'enum' : v.type;
|
|
42
50
|
v.mappedType = this.platform.getMappedType(type);
|
|
43
51
|
v.default = v.default?.toString().startsWith('nextval(') ? null : v.default;
|
|
44
|
-
v.enumItems
|
|
52
|
+
v.enumItems ??= enums[v.name] || [];
|
|
45
53
|
o[v.name] = v;
|
|
46
54
|
return o;
|
|
47
55
|
}, {});
|
|
@@ -51,7 +59,6 @@ class DatabaseTable {
|
|
|
51
59
|
}
|
|
52
60
|
addColumnFromProperty(prop, meta) {
|
|
53
61
|
prop.fieldNames.forEach((field, idx) => {
|
|
54
|
-
var _a;
|
|
55
62
|
const type = prop.enum ? 'enum' : prop.columnTypes[idx];
|
|
56
63
|
const mappedType = this.platform.getMappedType(type);
|
|
57
64
|
if (mappedType instanceof core_1.DecimalType) {
|
|
@@ -64,9 +71,9 @@ class DatabaseTable {
|
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
if (mappedType instanceof core_1.DateTimeType) {
|
|
67
|
-
prop.length
|
|
74
|
+
prop.length ??= this.platform.getDefaultDateTimeLength();
|
|
68
75
|
}
|
|
69
|
-
const primary = !meta.compositePK && !!prop.primary && prop.
|
|
76
|
+
const primary = !meta.compositePK && !!prop.primary && prop.kind === core_1.ReferenceKind.SCALAR && this.platform.isNumericColumn(mappedType);
|
|
70
77
|
this.columns[field] = {
|
|
71
78
|
name: prop.fieldNames[idx],
|
|
72
79
|
type: prop.columnTypes[idx],
|
|
@@ -74,21 +81,22 @@ class DatabaseTable {
|
|
|
74
81
|
unsigned: prop.unsigned && this.platform.isNumericColumn(mappedType),
|
|
75
82
|
autoincrement: prop.autoincrement ?? primary,
|
|
76
83
|
primary,
|
|
77
|
-
nullable: !!prop.nullable,
|
|
84
|
+
nullable: this.columns[field]?.nullable ?? !!prop.nullable,
|
|
85
|
+
nativeEnumName: prop.nativeEnumName,
|
|
78
86
|
length: prop.length,
|
|
79
87
|
precision: prop.precision,
|
|
80
88
|
scale: prop.scale,
|
|
81
89
|
default: prop.defaultRaw,
|
|
82
|
-
enumItems: prop.items?.every(core_1.Utils.isString) ? prop.items : undefined,
|
|
90
|
+
enumItems: prop.nativeEnumName || prop.items?.every(core_1.Utils.isString) ? prop.items : undefined,
|
|
83
91
|
comment: prop.comment,
|
|
84
92
|
extra: prop.extra,
|
|
85
93
|
ignoreSchemaChanges: prop.ignoreSchemaChanges,
|
|
86
94
|
};
|
|
87
|
-
|
|
95
|
+
this.columns[field].unsigned ||= this.columns[field].autoincrement;
|
|
88
96
|
const defaultValue = this.platform.getSchemaHelper().normalizeDefaultValue(prop.defaultRaw, prop.length);
|
|
89
97
|
this.columns[field].default = defaultValue;
|
|
90
98
|
});
|
|
91
|
-
if ([core_1.
|
|
99
|
+
if ([core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
92
100
|
const constraintName = this.getIndexName(true, prop.fieldNames, 'foreign');
|
|
93
101
|
let schema = prop.targetMeta.schema === '*' ? this.schema : prop.targetMeta.schema ?? this.schema;
|
|
94
102
|
if (prop.referencedTableName.includes('.')) {
|
|
@@ -102,11 +110,11 @@ class DatabaseTable {
|
|
|
102
110
|
referencedTableName: schema ? `${schema}.${prop.referencedTableName}` : prop.referencedTableName,
|
|
103
111
|
};
|
|
104
112
|
const cascade = prop.cascade.includes(core_1.Cascade.REMOVE) || prop.cascade.includes(core_1.Cascade.ALL);
|
|
105
|
-
if (prop.
|
|
106
|
-
this.foreignKeys[constraintName].deleteRule = prop.
|
|
113
|
+
if (prop.deleteRule || cascade || prop.nullable) {
|
|
114
|
+
this.foreignKeys[constraintName].deleteRule = prop.deleteRule || (cascade ? 'cascade' : 'set null');
|
|
107
115
|
}
|
|
108
|
-
if (prop.
|
|
109
|
-
this.foreignKeys[constraintName].updateRule = prop.
|
|
116
|
+
if (prop.updateRule || prop.cascade.includes(core_1.Cascade.PERSIST) || prop.cascade.includes(core_1.Cascade.ALL)) {
|
|
117
|
+
this.foreignKeys[constraintName].updateRule = prop.updateRule || 'cascade';
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
if (prop.index) {
|
|
@@ -114,6 +122,7 @@ class DatabaseTable {
|
|
|
114
122
|
columnNames: prop.fieldNames,
|
|
115
123
|
composite: prop.fieldNames.length > 1,
|
|
116
124
|
keyName: this.getIndexName(prop.index, prop.fieldNames, 'index'),
|
|
125
|
+
constraint: false,
|
|
117
126
|
primary: false,
|
|
118
127
|
unique: false,
|
|
119
128
|
});
|
|
@@ -123,6 +132,7 @@ class DatabaseTable {
|
|
|
123
132
|
columnNames: prop.fieldNames,
|
|
124
133
|
composite: prop.fieldNames.length > 1,
|
|
125
134
|
keyName: this.getIndexName(prop.unique, prop.fieldNames, 'unique'),
|
|
135
|
+
constraint: !prop.fieldNames.some((d) => d.includes('.')),
|
|
126
136
|
primary: false,
|
|
127
137
|
unique: true,
|
|
128
138
|
});
|
|
@@ -164,8 +174,8 @@ class DatabaseTable {
|
|
|
164
174
|
}
|
|
165
175
|
const meta = schema.init().meta;
|
|
166
176
|
meta.relations
|
|
167
|
-
.filter(prop => prop.primary && prop.
|
|
168
|
-
.forEach(prop => prop.
|
|
177
|
+
.filter(prop => prop.primary && prop.kind === core_1.ReferenceKind.MANY_TO_ONE && !meta.compositePK)
|
|
178
|
+
.forEach(prop => prop.kind = core_1.ReferenceKind.ONE_TO_ONE);
|
|
169
179
|
return meta;
|
|
170
180
|
}
|
|
171
181
|
/**
|
|
@@ -206,20 +216,20 @@ class DatabaseTable {
|
|
|
206
216
|
const prop = this.getPropertyName(namingStrategy, column);
|
|
207
217
|
const index = compositeFkIndexes[prop] || this.indexes.find(idx => idx.columnNames[0] === column.name && !idx.composite && !idx.unique && !idx.primary);
|
|
208
218
|
const unique = compositeFkUniques[prop] || this.indexes.find(idx => idx.columnNames[0] === column.name && !idx.composite && idx.unique && !idx.primary);
|
|
209
|
-
const
|
|
219
|
+
const kind = this.getReferenceKind(fk, unique);
|
|
210
220
|
const type = this.getPropertyType(namingStrategy, column, fk);
|
|
211
221
|
const fkOptions = {};
|
|
212
222
|
if (fk) {
|
|
213
223
|
fkOptions.fieldNames = fk.columnNames;
|
|
214
224
|
fkOptions.referencedTableName = fk.referencedTableName;
|
|
215
225
|
fkOptions.referencedColumnNames = fk.referencedColumnNames;
|
|
216
|
-
fkOptions.
|
|
217
|
-
fkOptions.
|
|
226
|
+
fkOptions.updateRule = fk.updateRule?.toLowerCase();
|
|
227
|
+
fkOptions.deleteRule = fk.deleteRule?.toLowerCase();
|
|
218
228
|
}
|
|
219
229
|
return {
|
|
220
230
|
name: prop,
|
|
221
231
|
type,
|
|
222
|
-
|
|
232
|
+
kind,
|
|
223
233
|
columnType: column.type,
|
|
224
234
|
default: this.getPropertyDefaultValue(schemaHelper, column, type),
|
|
225
235
|
defaultRaw: this.getPropertyDefaultValue(schemaHelper, column, type, true),
|
|
@@ -227,6 +237,8 @@ class DatabaseTable {
|
|
|
227
237
|
primary: column.primary,
|
|
228
238
|
fieldName: column.name,
|
|
229
239
|
length: column.length,
|
|
240
|
+
precision: column.precision,
|
|
241
|
+
scale: column.scale,
|
|
230
242
|
index: index ? index.keyName : undefined,
|
|
231
243
|
unique: unique ? unique.keyName : undefined,
|
|
232
244
|
enum: !!column.enumItems?.length,
|
|
@@ -234,14 +246,14 @@ class DatabaseTable {
|
|
|
234
246
|
...fkOptions,
|
|
235
247
|
};
|
|
236
248
|
}
|
|
237
|
-
|
|
249
|
+
getReferenceKind(fk, unique) {
|
|
238
250
|
if (fk && unique) {
|
|
239
|
-
return core_1.
|
|
251
|
+
return core_1.ReferenceKind.ONE_TO_ONE;
|
|
240
252
|
}
|
|
241
253
|
if (fk) {
|
|
242
|
-
return core_1.
|
|
254
|
+
return core_1.ReferenceKind.MANY_TO_ONE;
|
|
243
255
|
}
|
|
244
|
-
return core_1.
|
|
256
|
+
return core_1.ReferenceKind.SCALAR;
|
|
245
257
|
}
|
|
246
258
|
getPropertyName(namingStrategy, column) {
|
|
247
259
|
const fk = Object.values(this.foreignKeys).find(fk => fk.columnNames.includes(column.name));
|
|
@@ -288,7 +300,17 @@ class DatabaseTable {
|
|
|
288
300
|
return '' + val;
|
|
289
301
|
}
|
|
290
302
|
addIndex(meta, index, type) {
|
|
291
|
-
const properties = core_1.Utils.flatten(core_1.Utils.asArray(index.properties).map(prop =>
|
|
303
|
+
const properties = core_1.Utils.unique(core_1.Utils.flatten(core_1.Utils.asArray(index.properties).map(prop => {
|
|
304
|
+
const root = prop.replace(/\..+$/, '');
|
|
305
|
+
if (meta.properties[prop]) {
|
|
306
|
+
return meta.properties[prop].fieldNames;
|
|
307
|
+
}
|
|
308
|
+
// json index, we need to rename the column only
|
|
309
|
+
if (meta.properties[root]) {
|
|
310
|
+
return [prop.replace(root, meta.properties[root].fieldNames[0])];
|
|
311
|
+
}
|
|
312
|
+
return [prop];
|
|
313
|
+
})));
|
|
292
314
|
if (properties.length === 0 && !index.expression) {
|
|
293
315
|
return;
|
|
294
316
|
}
|
|
@@ -297,10 +319,13 @@ class DatabaseTable {
|
|
|
297
319
|
keyName: name,
|
|
298
320
|
columnNames: properties,
|
|
299
321
|
composite: properties.length > 1,
|
|
322
|
+
// JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
|
|
323
|
+
constraint: type !== 'index' && !properties.some((d) => d.includes('.')),
|
|
300
324
|
primary: type === 'primary',
|
|
301
325
|
unique: type !== 'index',
|
|
302
326
|
type: index.type,
|
|
303
327
|
expression: index.expression,
|
|
328
|
+
options: index.options,
|
|
304
329
|
});
|
|
305
330
|
}
|
|
306
331
|
addCheck(check) {
|
|
@@ -308,10 +333,10 @@ class DatabaseTable {
|
|
|
308
333
|
}
|
|
309
334
|
toJSON() {
|
|
310
335
|
const { platform, columns, ...rest } = this;
|
|
311
|
-
const columnsMapped =
|
|
336
|
+
const columnsMapped = core_1.Utils.keys(columns).reduce((o, col) => {
|
|
312
337
|
const { mappedType, ...restCol } = columns[col];
|
|
313
338
|
o[col] = restCol;
|
|
314
|
-
o[col].mappedType =
|
|
339
|
+
o[col].mappedType = core_1.Utils.keys(core_1.t).find(k => core_1.t[k] === mappedType.constructor);
|
|
315
340
|
return o;
|
|
316
341
|
}, {});
|
|
317
342
|
return { columns: columnsMapped, ...rest };
|
|
@@ -7,6 +7,9 @@ const core_1 = require("@mikro-orm/core");
|
|
|
7
7
|
* Compares two Schemas and return an instance of SchemaDifference.
|
|
8
8
|
*/
|
|
9
9
|
class SchemaComparator {
|
|
10
|
+
platform;
|
|
11
|
+
helper;
|
|
12
|
+
logger;
|
|
10
13
|
constructor(platform) {
|
|
11
14
|
this.platform = platform;
|
|
12
15
|
this.helper = this.platform.getSchemaHelper();
|
|
@@ -425,8 +428,10 @@ class SchemaComparator {
|
|
|
425
428
|
return index1.primary === index2.primary && index1.unique === index2.unique;
|
|
426
429
|
}
|
|
427
430
|
diffCheck(check1, check2) {
|
|
428
|
-
|
|
429
|
-
|
|
431
|
+
// check constraint definition might be normalized by the driver,
|
|
432
|
+
// e.g. quotes might be added (https://github.com/mikro-orm/mikro-orm/issues/3827)
|
|
433
|
+
const simplify = (str) => str?.replace(/['"`()]/g, '').toLowerCase();
|
|
434
|
+
return simplify(check1.expression) !== simplify(check2.expression);
|
|
430
435
|
}
|
|
431
436
|
hasSameDefaultValue(from, to) {
|
|
432
437
|
if (from.default == null || from.default.toString().toLowerCase() === 'null' || from.default.toString().startsWith('nextval(')) {
|
|
@@ -437,6 +442,11 @@ class SchemaComparator {
|
|
|
437
442
|
const defaultValueTo = !['0', 'false', 'f', 'n', 'no', 'off'].includes('' + to.default);
|
|
438
443
|
return defaultValueFrom === defaultValueTo;
|
|
439
444
|
}
|
|
445
|
+
if (to.mappedType instanceof core_1.JsonType) {
|
|
446
|
+
const defaultValueFrom = (0, core_1.parseJsonSafe)(from.default.replace(/^'(.*)'$/, '$1'));
|
|
447
|
+
const defaultValueTo = (0, core_1.parseJsonSafe)(to.default?.replace(/^'(.*)'$/, '$1'));
|
|
448
|
+
return core_1.Utils.equals(defaultValueFrom, defaultValueTo);
|
|
449
|
+
}
|
|
440
450
|
if (to.mappedType instanceof core_1.DateTimeType && from.default && to.default) {
|
|
441
451
|
// normalize now/current_timestamp defaults, also remove `()` from the end of default expression
|
|
442
452
|
const defaultValueFrom = from.default.toLowerCase().replace('current_timestamp', 'now').replace(/\(\)$/, '');
|
package/schema/SchemaHelper.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
|
-
import type
|
|
2
|
+
import { type Connection, type Dictionary } from '@mikro-orm/core';
|
|
3
3
|
import type { AbstractSqlConnection } from '../AbstractSqlConnection';
|
|
4
4
|
import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
|
|
5
5
|
import type { CheckDef, Column, IndexDef, Table, TableDifference } from '../typings';
|
|
@@ -18,7 +18,9 @@ export declare abstract class SchemaHelper {
|
|
|
18
18
|
getForeignKeys(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Dictionary>;
|
|
19
19
|
protected getTableKey(t: Table): string;
|
|
20
20
|
getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
|
|
21
|
-
|
|
21
|
+
getDropNativeEnumSQL(name: string, schema?: string): string;
|
|
22
|
+
getAlterNativeEnumSQL(name: string, schema?: string, value?: string): string;
|
|
23
|
+
loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[], schemas?: string[]): Promise<void>;
|
|
22
24
|
getListTablesSQL(schemaName?: string): string;
|
|
23
25
|
getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column, schemaName?: string): string;
|
|
24
26
|
getCreateIndexSQL(tableName: string, index: IndexDef): string;
|
|
@@ -29,8 +31,8 @@ export declare abstract class SchemaHelper {
|
|
|
29
31
|
configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
|
|
30
32
|
configureColumnDefault(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
|
|
31
33
|
getPreAlterTable(tableDiff: TableDifference, safe: boolean): string;
|
|
32
|
-
getAlterColumnAutoincrement(tableName: string, column: Column): string;
|
|
33
|
-
getChangeColumnCommentSQL(tableName: string, to: Column): string;
|
|
34
|
+
getAlterColumnAutoincrement(tableName: string, column: Column, schemaName?: string): string;
|
|
35
|
+
getChangeColumnCommentSQL(tableName: string, to: Column, schemaName?: string): string;
|
|
34
36
|
getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
|
|
35
37
|
getColumns(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Column[]>;
|
|
36
38
|
getIndexes(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<IndexDef[]>;
|
package/schema/SchemaHelper.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SchemaHelper = void 0;
|
|
4
4
|
const core_1 = require("@mikro-orm/core");
|
|
5
5
|
class SchemaHelper {
|
|
6
|
+
platform;
|
|
6
7
|
constructor(platform) {
|
|
7
8
|
this.platform = platform;
|
|
8
9
|
}
|
|
@@ -46,7 +47,13 @@ class SchemaHelper {
|
|
|
46
47
|
async getEnumDefinitions(connection, checks, tableName, schemaName) {
|
|
47
48
|
return {};
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
getDropNativeEnumSQL(name, schema) {
|
|
51
|
+
throw new Error('Not supported by given driver');
|
|
52
|
+
}
|
|
53
|
+
getAlterNativeEnumSQL(name, schema, value) {
|
|
54
|
+
throw new Error('Not supported by given driver');
|
|
55
|
+
}
|
|
56
|
+
async loadInformationSchema(schema, connection, tables, schemas) {
|
|
50
57
|
for (const t of tables) {
|
|
51
58
|
const table = schema.addTable(t.table_name, t.schema_name);
|
|
52
59
|
table.comment = t.table_comment;
|
|
@@ -122,17 +129,17 @@ class SchemaHelper {
|
|
|
122
129
|
core_1.Utils.runIfNotEmpty(() => col.defaultTo(column.default == null ? null : knex.raw(column.default)), guard('default'));
|
|
123
130
|
}
|
|
124
131
|
else {
|
|
125
|
-
core_1.Utils.runIfNotEmpty(() => col.defaultTo(
|
|
132
|
+
core_1.Utils.runIfNotEmpty(() => col.defaultTo(knex.raw(column.default)), column.default != null && column.default !== 'null');
|
|
126
133
|
}
|
|
127
134
|
return col;
|
|
128
135
|
}
|
|
129
136
|
getPreAlterTable(tableDiff, safe) {
|
|
130
137
|
return '';
|
|
131
138
|
}
|
|
132
|
-
getAlterColumnAutoincrement(tableName, column) {
|
|
139
|
+
getAlterColumnAutoincrement(tableName, column, schemaName) {
|
|
133
140
|
return '';
|
|
134
141
|
}
|
|
135
|
-
getChangeColumnCommentSQL(tableName, to) {
|
|
142
|
+
getChangeColumnCommentSQL(tableName, to, schemaName) {
|
|
136
143
|
return '';
|
|
137
144
|
}
|
|
138
145
|
async getNamespaces(connection) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { AbstractSchemaGenerator } from '@mikro-orm/core';
|
|
1
|
+
import { AbstractSchemaGenerator, type MikroORM, type ISchemaGenerator } from '@mikro-orm/core';
|
|
3
2
|
import type { SchemaDifference } from '../typings';
|
|
4
3
|
import { DatabaseSchema } from './DatabaseSchema';
|
|
5
4
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
@@ -8,8 +7,6 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
8
7
|
private readonly options;
|
|
9
8
|
protected lastEnsuredDatabase?: string;
|
|
10
9
|
static register(orm: MikroORM): void;
|
|
11
|
-
/** @deprecated use `dropSchema` and `createSchema` commands respectively */
|
|
12
|
-
generate(): Promise<string>;
|
|
13
10
|
createSchema(options?: {
|
|
14
11
|
wrap?: boolean;
|
|
15
12
|
schema?: string;
|
|
@@ -82,10 +79,10 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
82
79
|
* creates new database and connects to it
|
|
83
80
|
*/
|
|
84
81
|
createDatabase(name: string): Promise<void>;
|
|
85
|
-
dropDatabase(name
|
|
82
|
+
dropDatabase(name?: string): Promise<void>;
|
|
86
83
|
execute(sql: string, options?: {
|
|
87
84
|
wrap?: boolean;
|
|
88
|
-
}): Promise<
|
|
85
|
+
}): Promise<void>;
|
|
89
86
|
private wrapSchema;
|
|
90
87
|
private createSchemaBuilder;
|
|
91
88
|
private createTable;
|