@mikro-orm/knex 6.0.0-dev.2 → 6.0.0-dev.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/AbstractSqlConnection.d.ts → AbstractSqlConnection.d.ts} +8 -4
- package/{dist/AbstractSqlConnection.js → AbstractSqlConnection.js} +35 -18
- package/AbstractSqlDriver.d.ts +73 -0
- package/AbstractSqlDriver.js +1085 -0
- package/AbstractSqlPlatform.d.ts +22 -0
- package/{dist/AbstractSqlPlatform.js → AbstractSqlPlatform.js} +46 -19
- package/{dist/MonkeyPatchable.d.ts → MonkeyPatchable.d.ts} +1 -0
- package/{dist/MonkeyPatchable.js → MonkeyPatchable.js} +3 -0
- package/PivotCollectionPersister.d.ts +17 -0
- package/PivotCollectionPersister.js +128 -0
- package/{dist/README.md → README.md} +66 -109
- package/{dist/SqlEntityManager.d.ts → SqlEntityManager.d.ts} +6 -10
- package/{dist/SqlEntityManager.js → SqlEntityManager.js} +5 -10
- package/SqlEntityRepository.d.ts +24 -0
- package/{dist/SqlEntityRepository.js → SqlEntityRepository.js} +11 -8
- package/{dist/index.d.ts → index.d.ts} +1 -0
- package/{dist/index.js → index.js} +6 -1
- package/index.mjs +211 -0
- package/package.json +20 -49
- package/query/ArrayCriteriaNode.d.ts +10 -0
- package/{dist/query → query}/ArrayCriteriaNode.js +7 -2
- package/{dist/query → query}/CriteriaNode.d.ts +11 -9
- package/{dist/query → query}/CriteriaNode.js +31 -15
- package/query/CriteriaNodeFactory.d.ts +12 -0
- package/{dist/query → query}/CriteriaNodeFactory.js +32 -15
- package/query/ObjectCriteriaNode.d.ts +15 -0
- package/{dist/query → query}/ObjectCriteriaNode.js +68 -21
- package/query/QueryBuilder.d.ts +284 -0
- package/query/QueryBuilder.js +1218 -0
- package/{dist/query → query}/QueryBuilderHelper.d.ts +26 -23
- package/query/QueryBuilderHelper.js +661 -0
- package/query/ScalarCriteriaNode.d.ts +10 -0
- package/{dist/query → query}/ScalarCriteriaNode.js +12 -8
- package/query/enums.d.ts +15 -0
- package/query/enums.js +20 -0
- package/{dist/query → query}/index.js +5 -1
- package/{dist/schema → schema}/DatabaseSchema.d.ts +6 -3
- package/{dist/schema → schema}/DatabaseSchema.js +35 -25
- package/{dist/schema → schema}/DatabaseTable.d.ts +21 -13
- package/schema/DatabaseTable.js +645 -0
- package/{dist/schema → schema}/SchemaComparator.d.ts +9 -7
- package/{dist/schema → schema}/SchemaComparator.js +99 -25
- package/{dist/schema → schema}/SchemaHelper.d.ts +20 -13
- package/{dist/schema → schema}/SchemaHelper.js +70 -18
- package/{dist/schema/SchemaGenerator.d.ts → schema/SqlSchemaGenerator.d.ts} +11 -14
- package/{dist/schema/SchemaGenerator.js → schema/SqlSchemaGenerator.js} +149 -63
- package/{dist/schema → schema}/index.d.ts +1 -1
- package/{dist/schema → schema}/index.js +6 -2
- package/{dist/typings.d.ts → typings.d.ts} +45 -22
- package/CHANGELOG.md +0 -661
- package/dist/AbstractSqlDriver.d.ts +0 -55
- package/dist/AbstractSqlDriver.js +0 -644
- package/dist/AbstractSqlPlatform.d.ts +0 -21
- package/dist/LICENSE +0 -21
- package/dist/SqlEntityRepository.d.ts +0 -23
- package/dist/index.mjs +0 -26
- package/dist/package.json +0 -99
- package/dist/query/ArrayCriteriaNode.d.ts +0 -9
- package/dist/query/CriteriaNodeFactory.d.ts +0 -12
- package/dist/query/ObjectCriteriaNode.d.ts +0 -14
- package/dist/query/QueryBuilder.d.ts +0 -211
- package/dist/query/QueryBuilder.js +0 -688
- package/dist/query/QueryBuilderHelper.js +0 -523
- package/dist/query/ScalarCriteriaNode.d.ts +0 -9
- package/dist/query/enums.d.ts +0 -8
- package/dist/query/enums.js +0 -12
- package/dist/schema/DatabaseTable.js +0 -319
- /package/{dist/query → query}/index.d.ts +0 -0
- /package/{dist/typings.js → typings.js} +0 -0
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
import { AbstractSchemaGenerator } from '@mikro-orm/core';
|
|
1
|
+
import { AbstractSchemaGenerator, type MikroORM, type ISchemaGenerator } from '@mikro-orm/core';
|
|
2
2
|
import type { SchemaDifference } from '../typings';
|
|
3
3
|
import { DatabaseSchema } from './DatabaseSchema';
|
|
4
4
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Should be renamed to `SqlSchemaGenerator` in v6
|
|
8
|
-
*/
|
|
9
|
-
export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> {
|
|
5
|
+
export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> implements ISchemaGenerator {
|
|
10
6
|
private readonly helper;
|
|
11
|
-
private readonly knex;
|
|
12
7
|
private readonly options;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
constructor(em: SqlEntityManager);
|
|
17
|
-
generate(): Promise<string>;
|
|
8
|
+
protected lastEnsuredDatabase?: string;
|
|
9
|
+
static register(orm: MikroORM): void;
|
|
18
10
|
createSchema(options?: {
|
|
19
11
|
wrap?: boolean;
|
|
20
12
|
schema?: string;
|
|
@@ -34,6 +26,10 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
|
|
|
34
26
|
dropDb?: boolean;
|
|
35
27
|
schema?: string;
|
|
36
28
|
}): Promise<void>;
|
|
29
|
+
clearDatabase(options?: {
|
|
30
|
+
schema?: string;
|
|
31
|
+
truncate?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
37
33
|
getDropSchemaSQL(options?: {
|
|
38
34
|
wrap?: boolean;
|
|
39
35
|
dropMigrationsTable?: boolean;
|
|
@@ -83,7 +79,7 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
|
|
|
83
79
|
* creates new database and connects to it
|
|
84
80
|
*/
|
|
85
81
|
createDatabase(name: string): Promise<void>;
|
|
86
|
-
dropDatabase(name
|
|
82
|
+
dropDatabase(name?: string): Promise<void>;
|
|
87
83
|
execute(sql: string, options?: {
|
|
88
84
|
wrap?: boolean;
|
|
89
85
|
}): Promise<void>;
|
|
@@ -95,7 +91,8 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
|
|
|
95
91
|
private createCheck;
|
|
96
92
|
private dropCheck;
|
|
97
93
|
private dropTable;
|
|
98
|
-
private configureColumn;
|
|
99
94
|
private createForeignKeys;
|
|
100
95
|
private dump;
|
|
96
|
+
private get knex();
|
|
101
97
|
}
|
|
98
|
+
export { SqlSchemaGenerator as SchemaGenerator };
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SchemaGenerator = void 0;
|
|
3
|
+
exports.SchemaGenerator = exports.SqlSchemaGenerator = void 0;
|
|
4
4
|
const core_1 = require("@mikro-orm/core");
|
|
5
5
|
const DatabaseSchema_1 = require("./DatabaseSchema");
|
|
6
6
|
const SchemaComparator_1 = require("./SchemaComparator");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* `orm.getSchemaGenerator()` should be preferred way of getting the SchemaGenerator instance.
|
|
14
|
-
*/
|
|
15
|
-
constructor(driver) {
|
|
16
|
-
super(driver instanceof SqlEntityManager_1.SqlEntityManager ? driver.getDriver() : driver);
|
|
17
|
-
this.helper = this.platform.getSchemaHelper();
|
|
18
|
-
this.knex = this.connection.getKnex();
|
|
19
|
-
this.options = this.config.get('schemaGenerator');
|
|
20
|
-
}
|
|
21
|
-
async generate() {
|
|
22
|
-
const [dropSchema, createSchema] = await Promise.all([
|
|
23
|
-
this.getDropSchemaSQL({ wrap: false }),
|
|
24
|
-
this.getCreateSchemaSQL({ wrap: false }),
|
|
25
|
-
]);
|
|
26
|
-
return this.wrapSchema(dropSchema + createSchema);
|
|
7
|
+
class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
8
|
+
helper = this.platform.getSchemaHelper();
|
|
9
|
+
options = this.config.get('schemaGenerator');
|
|
10
|
+
lastEnsuredDatabase;
|
|
11
|
+
static register(orm) {
|
|
12
|
+
orm.config.registerExtension('@mikro-orm/schema-generator', () => new SqlSchemaGenerator(orm.em));
|
|
27
13
|
}
|
|
28
14
|
async createSchema(options) {
|
|
29
15
|
await this.ensureDatabase();
|
|
@@ -35,7 +21,11 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
35
21
|
*/
|
|
36
22
|
async ensureDatabase() {
|
|
37
23
|
const dbName = this.config.get('dbName');
|
|
24
|
+
if (this.lastEnsuredDatabase === dbName) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
38
27
|
const exists = await this.helper.databaseExists(this.connection, dbName);
|
|
28
|
+
this.lastEnsuredDatabase = dbName;
|
|
39
29
|
if (!exists) {
|
|
40
30
|
this.config.set('dbName', this.helper.getManagementDbName());
|
|
41
31
|
await this.driver.reconnect();
|
|
@@ -48,7 +38,8 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
48
38
|
}
|
|
49
39
|
getTargetSchema(schema) {
|
|
50
40
|
const metadata = this.getOrderedMetadata(schema);
|
|
51
|
-
|
|
41
|
+
const schemaName = schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
|
|
42
|
+
return DatabaseSchema_1.DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schemaName);
|
|
52
43
|
}
|
|
53
44
|
async getCreateSchemaSQL(options = {}) {
|
|
54
45
|
const wrap = options.wrap ?? this.options.disableForeignKeys;
|
|
@@ -69,7 +60,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
69
60
|
return this.wrapSchema(ret, { wrap });
|
|
70
61
|
}
|
|
71
62
|
async dropSchema(options = {}) {
|
|
72
|
-
options.wrap ?? (options.wrap = true);
|
|
73
63
|
if (options.dropDb) {
|
|
74
64
|
const name = this.config.get('dbName');
|
|
75
65
|
return this.dropDatabase(name);
|
|
@@ -77,51 +67,99 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
77
67
|
const sql = await this.getDropSchemaSQL(options);
|
|
78
68
|
await this.execute(sql);
|
|
79
69
|
}
|
|
70
|
+
async clearDatabase(options) {
|
|
71
|
+
// truncate by default, so no value is considered as true
|
|
72
|
+
/* istanbul ignore if */
|
|
73
|
+
if (options?.truncate === false) {
|
|
74
|
+
return super.clearDatabase(options);
|
|
75
|
+
}
|
|
76
|
+
await this.execute(this.helper.disableForeignKeysSQL());
|
|
77
|
+
for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
|
|
78
|
+
await this.driver.createQueryBuilder(meta.className, this.em?.getTransactionContext(), 'write', false)
|
|
79
|
+
.withSchema(options?.schema)
|
|
80
|
+
.truncate();
|
|
81
|
+
}
|
|
82
|
+
await this.execute(this.helper.enableForeignKeysSQL());
|
|
83
|
+
if (this.em) {
|
|
84
|
+
const allowGlobalContext = this.config.get('allowGlobalContext');
|
|
85
|
+
this.config.set('allowGlobalContext', true);
|
|
86
|
+
this.em.clear();
|
|
87
|
+
this.config.set('allowGlobalContext', allowGlobalContext);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
80
90
|
async getDropSchemaSQL(options = {}) {
|
|
91
|
+
await this.ensureDatabase();
|
|
81
92
|
const wrap = options.wrap ?? this.options.disableForeignKeys;
|
|
82
93
|
const metadata = this.getOrderedMetadata(options.schema).reverse();
|
|
94
|
+
const schemas = this.getTargetSchema(options.schema).getNamespaces();
|
|
95
|
+
const schema = await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas);
|
|
83
96
|
let ret = '';
|
|
97
|
+
// remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
|
|
98
|
+
for (const meta of metadata) {
|
|
99
|
+
const table = schema.getTable(meta.tableName);
|
|
100
|
+
if (!this.platform.usesCascadeStatement() && table && !wrap) {
|
|
101
|
+
for (const fk of Object.values(table.getForeignKeys())) {
|
|
102
|
+
const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
|
|
103
|
+
tbl.dropForeign(fk.columnNames, fk.constraintName);
|
|
104
|
+
});
|
|
105
|
+
ret += await this.dump(builder, '\n');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
84
109
|
for (const meta of metadata) {
|
|
85
110
|
ret += await this.dump(this.dropTable(meta.collection, this.getSchemaName(meta, options)), '\n');
|
|
86
111
|
}
|
|
112
|
+
if (this.platform.supportsNativeEnums()) {
|
|
113
|
+
for (const columnName of Object.keys(schema.getNativeEnums())) {
|
|
114
|
+
const sql = this.helper.getDropNativeEnumSQL(columnName, options.schema ?? this.config.get('schema'));
|
|
115
|
+
ret += await this.dump(this.knex.schema.raw(sql), '\n');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
87
118
|
if (options.dropMigrationsTable) {
|
|
88
119
|
ret += await this.dump(this.dropTable(this.config.get('migrations').tableName, this.config.get('schema')), '\n');
|
|
89
120
|
}
|
|
90
121
|
return this.wrapSchema(ret + '\n', { wrap });
|
|
91
122
|
}
|
|
92
123
|
getSchemaName(meta, options) {
|
|
124
|
+
const schemaName = options.schema ?? this.config.get('schema');
|
|
93
125
|
/* istanbul ignore next */
|
|
94
|
-
return meta.schema === '*' ?
|
|
126
|
+
return meta.schema && meta.schema === '*' ? schemaName : (meta.schema ?? schemaName);
|
|
95
127
|
}
|
|
96
128
|
async updateSchema(options = {}) {
|
|
97
129
|
const sql = await this.getUpdateSchemaSQL(options);
|
|
98
130
|
await this.execute(sql);
|
|
99
131
|
}
|
|
100
132
|
async getUpdateSchemaSQL(options = {}) {
|
|
133
|
+
await this.ensureDatabase();
|
|
101
134
|
const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
|
|
102
135
|
const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
|
|
103
136
|
const diffUp = comparator.compare(fromSchema, toSchema);
|
|
104
137
|
return this.diffToSQL(diffUp, options);
|
|
105
138
|
}
|
|
106
139
|
async getUpdateSchemaMigrationSQL(options = {}) {
|
|
140
|
+
if (!options.fromSchema) {
|
|
141
|
+
await this.ensureDatabase();
|
|
142
|
+
}
|
|
107
143
|
const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
|
|
108
144
|
const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
|
|
109
145
|
const diffUp = comparator.compare(fromSchema, toSchema);
|
|
110
|
-
const diffDown = comparator.compare(toSchema, fromSchema);
|
|
146
|
+
const diffDown = comparator.compare(toSchema, fromSchema, diffUp);
|
|
111
147
|
return {
|
|
112
148
|
up: await this.diffToSQL(diffUp, options),
|
|
113
149
|
down: this.platform.supportsDownMigrations() ? await this.diffToSQL(diffDown, options) : '',
|
|
114
150
|
};
|
|
115
151
|
}
|
|
116
152
|
async prepareSchemaForComparison(options) {
|
|
117
|
-
options.wrap
|
|
118
|
-
options.safe
|
|
119
|
-
options.dropTables
|
|
153
|
+
options.wrap ??= this.options.disableForeignKeys;
|
|
154
|
+
options.safe ??= false;
|
|
155
|
+
options.dropTables ??= true;
|
|
120
156
|
const toSchema = this.getTargetSchema(options.schema);
|
|
121
|
-
const
|
|
157
|
+
const schemas = toSchema.getNamespaces();
|
|
158
|
+
const fromSchema = options.fromSchema ?? await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas);
|
|
122
159
|
const wildcardSchemaTables = Object.values(this.metadata.getAll()).filter(meta => meta.schema === '*').map(meta => meta.tableName);
|
|
123
160
|
fromSchema.prune(options.schema, wildcardSchemaTables);
|
|
124
161
|
toSchema.prune(options.schema, wildcardSchemaTables);
|
|
162
|
+
toSchema.setNativeEnums(fromSchema.getNativeEnums());
|
|
125
163
|
return { fromSchema, toSchema };
|
|
126
164
|
}
|
|
127
165
|
async diffToSQL(schemaDiff, options) {
|
|
@@ -177,7 +215,7 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
177
215
|
if (schema && schemaName === '*') {
|
|
178
216
|
return `${schema}.${referencedTableName.replace(/^\*\./, '')}`;
|
|
179
217
|
}
|
|
180
|
-
if (schemaName === this.platform.getDefaultSchemaName()) {
|
|
218
|
+
if (!schemaName || schemaName === this.platform.getDefaultSchemaName()) {
|
|
181
219
|
return tableName;
|
|
182
220
|
}
|
|
183
221
|
return `${schemaName}.${tableName}`;
|
|
@@ -225,6 +263,12 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
225
263
|
alterTable(diff, safe) {
|
|
226
264
|
const ret = [];
|
|
227
265
|
const [schemaName, tableName] = this.splitTableName(diff.name);
|
|
266
|
+
const changedNativeEnums = [];
|
|
267
|
+
for (const { column, changedProperties } of Object.values(diff.changedColumns)) {
|
|
268
|
+
if (column.nativeEnumName && changedProperties.has('enumItems') && column.nativeEnumName in diff.fromTable.nativeEnums) {
|
|
269
|
+
changedNativeEnums.push([column.nativeEnumName, column.enumItems, diff.fromTable.getColumn(column.name).enumItems]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
228
272
|
ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
|
|
229
273
|
for (const index of Object.values(diff.removedIndexes)) {
|
|
230
274
|
this.dropIndex(table, index);
|
|
@@ -238,9 +282,17 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
238
282
|
for (const check of Object.values(diff.changedChecks)) {
|
|
239
283
|
this.dropCheck(table, check);
|
|
240
284
|
}
|
|
285
|
+
/* istanbul ignore else */
|
|
286
|
+
if (!safe) {
|
|
287
|
+
for (const column of Object.values(diff.removedColumns)) {
|
|
288
|
+
this.helper.pushTableQuery(table, `alter table ${this.platform.quoteIdentifier(tableName)} drop column ${this.platform.quoteIdentifier(column.name)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}));
|
|
292
|
+
ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
|
|
241
293
|
for (const column of Object.values(diff.addedColumns)) {
|
|
242
294
|
const col = this.helper.createTableColumn(table, column, diff.fromTable);
|
|
243
|
-
this.configureColumn(column, col);
|
|
295
|
+
this.helper.configureColumn(column, col, this.knex);
|
|
244
296
|
const foreignKey = Object.values(diff.addedForeignKeys).find(fk => fk.columnNames.length === 1 && fk.columnNames[0] === column.name);
|
|
245
297
|
if (foreignKey && this.options.createForeignKeyConstraints) {
|
|
246
298
|
delete diff.addedForeignKeys[foreignKey.constraintName];
|
|
@@ -251,30 +303,27 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
251
303
|
.onDelete(foreignKey.deleteRule);
|
|
252
304
|
}
|
|
253
305
|
}
|
|
254
|
-
/* istanbul ignore else */
|
|
255
|
-
if (!safe) {
|
|
256
|
-
for (const column of Object.values(diff.removedColumns)) {
|
|
257
|
-
table.dropColumn(column.name);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
306
|
for (const { column, changedProperties } of Object.values(diff.changedColumns)) {
|
|
261
307
|
if (changedProperties.size === 1 && changedProperties.has('comment')) {
|
|
262
308
|
continue;
|
|
263
309
|
}
|
|
310
|
+
if (changedProperties.size === 1 && changedProperties.has('enumItems') && column.nativeEnumName) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
264
313
|
const col = this.helper.createTableColumn(table, column, diff.fromTable, changedProperties).alter();
|
|
265
|
-
this.configureColumn(column, col, changedProperties);
|
|
314
|
+
this.helper.configureColumn(column, col, this.knex, changedProperties);
|
|
266
315
|
}
|
|
267
316
|
for (const { column } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('autoincrement'))) {
|
|
268
|
-
this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column));
|
|
317
|
+
this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column, schemaName));
|
|
269
318
|
}
|
|
270
319
|
for (const { column, changedProperties } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('comment'))) {
|
|
271
320
|
if (['type', 'nullable', 'autoincrement', 'unsigned', 'default', 'enumItems'].some(t => changedProperties.has(t))) {
|
|
272
321
|
continue; // will be handled via knex
|
|
273
322
|
}
|
|
274
|
-
this.helper.pushTableQuery(table, this.helper.getChangeColumnCommentSQL(tableName, column));
|
|
323
|
+
this.helper.pushTableQuery(table, this.helper.getChangeColumnCommentSQL(tableName, column, schemaName));
|
|
275
324
|
}
|
|
276
325
|
for (const [oldColumnName, column] of Object.entries(diff.renamedColumns)) {
|
|
277
|
-
this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column));
|
|
326
|
+
this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column, schemaName));
|
|
278
327
|
}
|
|
279
328
|
for (const foreignKey of Object.values(diff.addedForeignKeys)) {
|
|
280
329
|
this.createForeignKey(table, foreignKey);
|
|
@@ -283,15 +332,15 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
283
332
|
this.createForeignKey(table, foreignKey);
|
|
284
333
|
}
|
|
285
334
|
for (const index of Object.values(diff.addedIndexes)) {
|
|
286
|
-
this.createIndex(table, index, diff.
|
|
335
|
+
this.createIndex(table, index, diff.toTable);
|
|
287
336
|
}
|
|
288
337
|
for (const index of Object.values(diff.changedIndexes)) {
|
|
289
|
-
this.createIndex(table, index, diff.
|
|
338
|
+
this.createIndex(table, index, diff.toTable, true);
|
|
290
339
|
}
|
|
291
340
|
for (const [oldIndexName, index] of Object.entries(diff.renamedIndexes)) {
|
|
292
341
|
if (index.unique) {
|
|
293
342
|
this.dropIndex(table, index, oldIndexName);
|
|
294
|
-
this.createIndex(table, index, diff.
|
|
343
|
+
this.createIndex(table, index, diff.toTable);
|
|
295
344
|
}
|
|
296
345
|
else {
|
|
297
346
|
this.helper.pushTableQuery(table, this.helper.getRenameIndexSQL(diff.name, index, oldIndexName));
|
|
@@ -304,9 +353,17 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
304
353
|
this.createCheck(table, check);
|
|
305
354
|
}
|
|
306
355
|
if ('changedComment' in diff) {
|
|
307
|
-
|
|
356
|
+
const comment = diff.changedComment ? this.platform.quoteValue(diff.changedComment).replace(/^'|'$/g, '') : '';
|
|
357
|
+
table.comment(comment);
|
|
308
358
|
}
|
|
309
359
|
}));
|
|
360
|
+
if (this.platform.supportsNativeEnums()) {
|
|
361
|
+
changedNativeEnums.forEach(([enumName, itemsNew, itemsOld]) => {
|
|
362
|
+
// postgres allows only adding new items
|
|
363
|
+
const newItems = itemsNew.filter(val => !itemsOld.includes(val));
|
|
364
|
+
ret.push(...newItems.map(val => this.knex.schema.raw(this.helper.getAlterNativeEnumSQL(enumName, schemaName, val))));
|
|
365
|
+
});
|
|
366
|
+
}
|
|
310
367
|
return ret;
|
|
311
368
|
}
|
|
312
369
|
/**
|
|
@@ -318,19 +375,26 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
318
375
|
await this.driver.reconnect();
|
|
319
376
|
}
|
|
320
377
|
async dropDatabase(name) {
|
|
378
|
+
name ??= this.config.get('dbName');
|
|
321
379
|
this.config.set('dbName', this.helper.getManagementDbName());
|
|
322
380
|
await this.driver.reconnect();
|
|
323
381
|
await this.driver.execute(this.helper.getDropDatabaseSQL('' + this.knex.ref(name)));
|
|
324
382
|
}
|
|
325
383
|
async execute(sql, options = {}) {
|
|
326
|
-
options.wrap
|
|
384
|
+
options.wrap ??= false;
|
|
327
385
|
const lines = this.wrapSchema(sql, options).split('\n').filter(i => i.trim());
|
|
328
|
-
|
|
329
|
-
|
|
386
|
+
if (lines.length === 0) {
|
|
387
|
+
return;
|
|
330
388
|
}
|
|
389
|
+
if (this.platform.supportsMultipleStatements()) {
|
|
390
|
+
const query = lines.join('\n');
|
|
391
|
+
await this.driver.execute(query);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
await core_1.Utils.runSerial(lines, line => this.driver.execute(line));
|
|
331
395
|
}
|
|
332
|
-
wrapSchema(sql, options
|
|
333
|
-
options.wrap
|
|
396
|
+
wrapSchema(sql, options) {
|
|
397
|
+
options.wrap ??= this.options.disableForeignKeys;
|
|
334
398
|
if (!options.wrap || sql.trim() === '') {
|
|
335
399
|
return sql;
|
|
336
400
|
}
|
|
@@ -350,16 +414,18 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
350
414
|
return this.createSchemaBuilder(tableDef.schema).createTable(tableDef.name, table => {
|
|
351
415
|
tableDef.getColumns().forEach(column => {
|
|
352
416
|
const col = this.helper.createTableColumn(table, column, tableDef);
|
|
353
|
-
this.configureColumn(column, col);
|
|
417
|
+
this.helper.configureColumn(column, col, this.knex);
|
|
354
418
|
});
|
|
355
419
|
for (const index of tableDef.getIndexes()) {
|
|
356
|
-
|
|
420
|
+
const createPrimary = !tableDef.getColumns().some(c => c.autoincrement && c.primary) || this.helper.hasNonDefaultPrimaryKeyName(tableDef);
|
|
421
|
+
this.createIndex(table, index, tableDef, createPrimary);
|
|
357
422
|
}
|
|
358
423
|
for (const check of tableDef.getChecks()) {
|
|
359
424
|
this.createCheck(table, check);
|
|
360
425
|
}
|
|
361
426
|
if (tableDef.comment) {
|
|
362
|
-
|
|
427
|
+
const comment = this.platform.quoteValue(tableDef.comment).replace(/^'|'$/g, '');
|
|
428
|
+
table.comment(comment);
|
|
363
429
|
}
|
|
364
430
|
if (!this.helper.supportsSchemaConstraints()) {
|
|
365
431
|
for (const fk of Object.values(tableDef.getForeignKeys())) {
|
|
@@ -369,30 +435,49 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
369
435
|
this.helper.finalizeTable(table, this.config.get('charset'), this.config.get('collate'));
|
|
370
436
|
});
|
|
371
437
|
}
|
|
372
|
-
createIndex(table, index,
|
|
438
|
+
createIndex(table, index, tableDef, createPrimary = false) {
|
|
373
439
|
if (index.primary && !createPrimary) {
|
|
374
440
|
return;
|
|
375
441
|
}
|
|
376
442
|
if (index.primary) {
|
|
377
|
-
|
|
378
|
-
const keyName = tableName.includes('.') ? tableName.split('.').pop() + '_pkey' : undefined;
|
|
443
|
+
const keyName = this.helper.hasNonDefaultPrimaryKeyName(tableDef) ? index.keyName : undefined;
|
|
379
444
|
table.primary(index.columnNames, keyName);
|
|
380
445
|
}
|
|
381
446
|
else if (index.unique) {
|
|
382
|
-
|
|
447
|
+
// JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
|
|
448
|
+
if (index.columnNames.some(column => column.includes('.'))) {
|
|
449
|
+
const columns = this.platform.getJsonIndexDefinition(index);
|
|
450
|
+
table.index(columns.map(column => this.knex.raw(`(${column})`)), index.keyName, { indexType: 'unique' });
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
table.unique(index.columnNames, { indexName: index.keyName });
|
|
454
|
+
}
|
|
383
455
|
}
|
|
384
456
|
else if (index.expression) {
|
|
385
457
|
this.helper.pushTableQuery(table, index.expression);
|
|
386
458
|
}
|
|
459
|
+
else if (index.type === 'fulltext') {
|
|
460
|
+
const columns = index.columnNames.map(name => ({ name, type: tableDef.getColumn(name).type }));
|
|
461
|
+
if (this.platform.supportsCreatingFullTextIndex()) {
|
|
462
|
+
this.helper.pushTableQuery(table, this.platform.getFullTextIndexExpression(index.keyName, tableDef.schema, tableDef.name, columns));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
387
465
|
else {
|
|
388
|
-
|
|
466
|
+
// JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
|
|
467
|
+
if (index.columnNames.some(column => column.includes('.'))) {
|
|
468
|
+
const columns = this.platform.getJsonIndexDefinition(index);
|
|
469
|
+
table.index(columns.map(column => this.knex.raw(`(${column})`)), index.keyName, index.type);
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
table.index(index.columnNames, index.keyName, index.type);
|
|
473
|
+
}
|
|
389
474
|
}
|
|
390
475
|
}
|
|
391
476
|
dropIndex(table, index, oldIndexName = index.keyName) {
|
|
392
477
|
if (index.primary) {
|
|
393
478
|
table.dropPrimary(oldIndexName);
|
|
394
479
|
}
|
|
395
|
-
else if (index.unique) {
|
|
480
|
+
else if (index.unique && index.constraint) {
|
|
396
481
|
table.dropUnique(index.columnNames, oldIndexName);
|
|
397
482
|
}
|
|
398
483
|
else {
|
|
@@ -412,9 +497,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
412
497
|
}
|
|
413
498
|
return builder;
|
|
414
499
|
}
|
|
415
|
-
configureColumn(column, col, changedProperties) {
|
|
416
|
-
return this.helper.configureColumn(column, col, this.knex, changedProperties);
|
|
417
|
-
}
|
|
418
500
|
createForeignKeys(table, tableDef, schema) {
|
|
419
501
|
if (!this.helper.supportsSchemaConstraints()) {
|
|
420
502
|
return;
|
|
@@ -433,5 +515,9 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
433
515
|
const tmp = dump.replace(/pragma table_.+/ig, '').replace(/\n\n+/g, '\n').trim();
|
|
434
516
|
return tmp ? tmp + append : '';
|
|
435
517
|
}
|
|
518
|
+
get knex() {
|
|
519
|
+
return this.connection.getKnex();
|
|
520
|
+
}
|
|
436
521
|
}
|
|
437
|
-
exports.
|
|
522
|
+
exports.SqlSchemaGenerator = SqlSchemaGenerator;
|
|
523
|
+
exports.SchemaGenerator = SqlSchemaGenerator;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -12,6 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
12
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
17
|
__exportStar(require("./DatabaseSchema"), exports);
|
|
14
18
|
__exportStar(require("./DatabaseTable"), exports);
|
|
15
|
-
__exportStar(require("./
|
|
19
|
+
__exportStar(require("./SqlSchemaGenerator"), exports);
|
|
16
20
|
__exportStar(require("./SchemaHelper"), exports);
|
|
17
21
|
__exportStar(require("./SchemaComparator"), exports);
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
|
-
import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, QBFilterQuery, QueryOrderMap, Type } from '@mikro-orm/core';
|
|
3
|
-
import type { QueryType } from './query/enums';
|
|
2
|
+
import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type, QueryFlag } from '@mikro-orm/core';
|
|
3
|
+
import type { JoinType, QueryType } from './query/enums';
|
|
4
4
|
import type { DatabaseSchema, DatabaseTable } from './schema';
|
|
5
5
|
export interface Table {
|
|
6
6
|
table_name: string;
|
|
7
7
|
schema_name?: string;
|
|
8
8
|
table_comment?: string;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
10
|
+
export type KnexStringRef = Knex.Ref<string, {
|
|
11
11
|
[alias: string]: string;
|
|
12
12
|
}>;
|
|
13
|
-
|
|
13
|
+
type AnyString = string & {};
|
|
14
|
+
export type Field<T> = AnyString | keyof T | RawQueryFragment | KnexStringRef | Knex.QueryBuilder;
|
|
14
15
|
export interface JoinOptions {
|
|
15
16
|
table: string;
|
|
16
17
|
schema?: string;
|
|
17
|
-
type:
|
|
18
|
+
type: JoinType;
|
|
18
19
|
alias: string;
|
|
19
20
|
ownerAlias: string;
|
|
20
21
|
inverseAlias?: string;
|
|
@@ -24,6 +25,8 @@ export interface JoinOptions {
|
|
|
24
25
|
path?: string;
|
|
25
26
|
prop: EntityProperty;
|
|
26
27
|
cond: Dictionary;
|
|
28
|
+
cond_?: Dictionary;
|
|
29
|
+
subquery?: string;
|
|
27
30
|
}
|
|
28
31
|
export interface Column {
|
|
29
32
|
name: string;
|
|
@@ -37,11 +40,14 @@ export interface Column {
|
|
|
37
40
|
scale?: number;
|
|
38
41
|
default?: string | null;
|
|
39
42
|
comment?: string;
|
|
43
|
+
generated?: string;
|
|
44
|
+
nativeEnumName?: string;
|
|
40
45
|
enumItems?: string[];
|
|
41
46
|
primary?: boolean;
|
|
42
47
|
unique?: boolean;
|
|
43
48
|
/** mysql only */
|
|
44
49
|
extra?: string;
|
|
50
|
+
ignoreSchemaChanges?: ('type' | 'extra')[];
|
|
45
51
|
}
|
|
46
52
|
export interface ForeignKey {
|
|
47
53
|
columnNames: string[];
|
|
@@ -52,20 +58,22 @@ export interface ForeignKey {
|
|
|
52
58
|
updateRule?: string;
|
|
53
59
|
deleteRule?: string;
|
|
54
60
|
}
|
|
55
|
-
export interface
|
|
61
|
+
export interface IndexDef {
|
|
56
62
|
columnNames: string[];
|
|
57
63
|
keyName: string;
|
|
58
64
|
unique: boolean;
|
|
65
|
+
constraint: boolean;
|
|
59
66
|
primary: boolean;
|
|
60
67
|
composite?: boolean;
|
|
61
68
|
expression?: string;
|
|
69
|
+
options?: Dictionary;
|
|
62
70
|
type?: string | Readonly<{
|
|
63
71
|
indexType?: string;
|
|
64
72
|
storageEngineIndexType?: 'hash' | 'btree';
|
|
65
73
|
predicate?: Knex.QueryBuilder;
|
|
66
74
|
}>;
|
|
67
75
|
}
|
|
68
|
-
export interface
|
|
76
|
+
export interface CheckDef<T = unknown> {
|
|
69
77
|
name: string;
|
|
70
78
|
expression: string | CheckCallback<T>;
|
|
71
79
|
definition?: string;
|
|
@@ -81,17 +89,18 @@ export interface TableDifference {
|
|
|
81
89
|
name: string;
|
|
82
90
|
changedComment?: string;
|
|
83
91
|
fromTable: DatabaseTable;
|
|
92
|
+
toTable: DatabaseTable;
|
|
84
93
|
addedColumns: Dictionary<Column>;
|
|
85
94
|
changedColumns: Dictionary<ColumnDifference>;
|
|
86
95
|
removedColumns: Dictionary<Column>;
|
|
87
96
|
renamedColumns: Dictionary<Column>;
|
|
88
|
-
addedIndexes: Dictionary<
|
|
89
|
-
changedIndexes: Dictionary<
|
|
90
|
-
removedIndexes: Dictionary<
|
|
91
|
-
renamedIndexes: Dictionary<
|
|
92
|
-
addedChecks: Dictionary<
|
|
93
|
-
changedChecks: Dictionary<
|
|
94
|
-
removedChecks: Dictionary<
|
|
97
|
+
addedIndexes: Dictionary<IndexDef>;
|
|
98
|
+
changedIndexes: Dictionary<IndexDef>;
|
|
99
|
+
removedIndexes: Dictionary<IndexDef>;
|
|
100
|
+
renamedIndexes: Dictionary<IndexDef>;
|
|
101
|
+
addedChecks: Dictionary<CheckDef>;
|
|
102
|
+
changedChecks: Dictionary<CheckDef>;
|
|
103
|
+
removedChecks: Dictionary<CheckDef>;
|
|
95
104
|
addedForeignKeys: Dictionary<ForeignKey>;
|
|
96
105
|
changedForeignKeys: Dictionary<ForeignKey>;
|
|
97
106
|
removedForeignKeys: Dictionary<ForeignKey>;
|
|
@@ -107,7 +116,7 @@ export interface SchemaDifference {
|
|
|
107
116
|
}
|
|
108
117
|
export interface IQueryBuilder<T> {
|
|
109
118
|
readonly alias: string;
|
|
110
|
-
readonly type
|
|
119
|
+
readonly type?: QueryType;
|
|
111
120
|
_fields?: Field<T>[];
|
|
112
121
|
select(fields: Field<T> | Field<T>[], distinct?: boolean): this;
|
|
113
122
|
addSelect(fields: string | string[]): this;
|
|
@@ -116,10 +125,12 @@ export interface IQueryBuilder<T> {
|
|
|
116
125
|
delete(cond?: QBFilterQuery): this;
|
|
117
126
|
truncate(): this;
|
|
118
127
|
count(field?: string | string[], distinct?: boolean): this;
|
|
119
|
-
join(field: string, alias: string, cond?: QBFilterQuery, type?:
|
|
128
|
+
join(field: string, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string): this;
|
|
129
|
+
innerJoin(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
120
130
|
leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
121
131
|
joinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
122
|
-
leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
132
|
+
leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
|
|
133
|
+
innerJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
|
|
123
134
|
withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
|
|
124
135
|
where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
|
|
125
136
|
where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;
|
|
@@ -130,21 +141,33 @@ export interface IQueryBuilder<T> {
|
|
|
130
141
|
orderBy(orderBy: QueryOrderMap<T>): this;
|
|
131
142
|
groupBy(fields: (string | keyof T) | (string | keyof T)[]): this;
|
|
132
143
|
having(cond?: QBFilterQuery | string, params?: any[]): this;
|
|
133
|
-
getAliasForJoinPath(path: string): string | undefined;
|
|
144
|
+
getAliasForJoinPath(path: string, options?: ICriteriaNodeProcessOptions): string | undefined;
|
|
145
|
+
getJoinForPath(path?: string, options?: ICriteriaNodeProcessOptions): JoinOptions | undefined;
|
|
134
146
|
getNextAlias(entityName?: string): string;
|
|
147
|
+
clone(reset?: boolean): IQueryBuilder<T>;
|
|
148
|
+
setFlag(flag: QueryFlag): this;
|
|
149
|
+
unsetFlag(flag: QueryFlag): this;
|
|
150
|
+
hasFlag(flag: QueryFlag): boolean;
|
|
135
151
|
}
|
|
136
|
-
export interface
|
|
152
|
+
export interface ICriteriaNodeProcessOptions {
|
|
153
|
+
alias?: string;
|
|
154
|
+
matchPopulateJoins?: boolean;
|
|
155
|
+
ignoreBranching?: boolean;
|
|
156
|
+
preferNoBranch?: boolean;
|
|
157
|
+
}
|
|
158
|
+
export interface ICriteriaNode<T extends object> {
|
|
137
159
|
readonly entityName: string;
|
|
138
|
-
readonly parent?: ICriteriaNode | undefined;
|
|
160
|
+
readonly parent?: ICriteriaNode<T> | undefined;
|
|
139
161
|
readonly key?: string | undefined;
|
|
140
162
|
payload: any;
|
|
141
163
|
prop?: EntityProperty;
|
|
142
164
|
index?: number;
|
|
143
|
-
process
|
|
165
|
+
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
144
166
|
shouldInline(payload: any): boolean;
|
|
145
|
-
willAutoJoin
|
|
167
|
+
willAutoJoin(qb: IQueryBuilder<T>, alias?: string): boolean;
|
|
146
168
|
shouldRename(payload: any): boolean;
|
|
147
169
|
renameFieldToPK<T>(qb: IQueryBuilder<T>): string;
|
|
148
170
|
getPath(addIndex?: boolean): string;
|
|
149
171
|
getPivotPath(path: string): string;
|
|
150
172
|
}
|
|
173
|
+
export {};
|