@mikro-orm/sql 7.0.0-dev.97 → 7.0.0-dev.98
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 +56 -0
- package/AbstractSqlConnection.js +232 -0
- package/AbstractSqlDriver.d.ts +94 -0
- package/AbstractSqlDriver.js +1387 -0
- package/AbstractSqlPlatform.d.ts +38 -0
- package/AbstractSqlPlatform.js +104 -0
- package/LICENSE +21 -0
- package/PivotCollectionPersister.d.ts +22 -0
- package/PivotCollectionPersister.js +159 -0
- package/README.md +390 -0
- package/SqlEntityManager.d.ts +33 -0
- package/SqlEntityManager.js +44 -0
- package/SqlEntityRepository.d.ts +19 -0
- package/SqlEntityRepository.js +26 -0
- package/dialects/index.d.ts +4 -0
- package/dialects/index.js +4 -0
- package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +14 -0
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +200 -0
- package/dialects/mssql/index.d.ts +1 -0
- package/dialects/mssql/index.js +1 -0
- package/dialects/mysql/MySqlExceptionConverter.d.ts +9 -0
- package/dialects/mysql/MySqlExceptionConverter.js +80 -0
- package/dialects/mysql/MySqlNativeQueryBuilder.d.ts +7 -0
- package/dialects/mysql/MySqlNativeQueryBuilder.js +77 -0
- package/dialects/mysql/MySqlPlatform.d.ts +45 -0
- package/dialects/mysql/MySqlPlatform.js +116 -0
- package/dialects/mysql/MySqlSchemaHelper.d.ts +36 -0
- package/dialects/mysql/MySqlSchemaHelper.js +269 -0
- package/dialects/mysql/index.d.ts +4 -0
- package/dialects/mysql/index.js +4 -0
- package/dialects/postgresql/PostgreSqlNativeQueryBuilder.d.ts +5 -0
- package/dialects/postgresql/PostgreSqlNativeQueryBuilder.js +8 -0
- package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +1 -0
- package/dialects/postgresql/PostgreSqlTableCompiler.js +1 -0
- package/dialects/postgresql/index.d.ts +1 -0
- package/dialects/postgresql/index.js +1 -0
- package/dialects/sqlite/BaseSqliteConnection.d.ts +6 -0
- package/dialects/sqlite/BaseSqliteConnection.js +8 -0
- package/dialects/sqlite/BaseSqlitePlatform.d.ts +70 -0
- package/dialects/sqlite/BaseSqlitePlatform.js +104 -0
- package/dialects/sqlite/SqliteExceptionConverter.d.ts +9 -0
- package/dialects/sqlite/SqliteExceptionConverter.js +54 -0
- package/dialects/sqlite/SqliteNativeQueryBuilder.d.ts +6 -0
- package/dialects/sqlite/SqliteNativeQueryBuilder.js +11 -0
- package/dialects/sqlite/SqliteSchemaHelper.d.ts +38 -0
- package/dialects/sqlite/SqliteSchemaHelper.js +379 -0
- package/dialects/sqlite/index.d.ts +5 -0
- package/dialects/sqlite/index.js +5 -0
- package/index.d.ts +19 -0
- package/index.js +19 -0
- package/package.json +3 -3
- package/plugin/index.d.ts +53 -0
- package/plugin/index.js +42 -0
- package/plugin/transformer.d.ts +115 -0
- package/plugin/transformer.js +883 -0
- package/query/ArrayCriteriaNode.d.ts +11 -0
- package/query/ArrayCriteriaNode.js +24 -0
- package/query/CriteriaNode.d.ts +29 -0
- package/query/CriteriaNode.js +121 -0
- package/query/CriteriaNodeFactory.d.ts +12 -0
- package/query/CriteriaNodeFactory.js +90 -0
- package/query/NativeQueryBuilder.d.ts +108 -0
- package/query/NativeQueryBuilder.js +425 -0
- package/query/ObjectCriteriaNode.d.ts +19 -0
- package/query/ObjectCriteriaNode.js +249 -0
- package/query/QueryBuilder.d.ts +389 -0
- package/query/QueryBuilder.js +1558 -0
- package/query/QueryBuilderHelper.d.ts +73 -0
- package/query/QueryBuilderHelper.js +756 -0
- package/query/ScalarCriteriaNode.d.ts +10 -0
- package/query/ScalarCriteriaNode.js +49 -0
- package/query/enums.d.ts +18 -0
- package/query/enums.js +20 -0
- package/query/index.d.ts +10 -0
- package/query/index.js +10 -0
- package/query/raw.d.ts +59 -0
- package/query/raw.js +68 -0
- package/schema/DatabaseSchema.d.ts +45 -0
- package/schema/DatabaseSchema.js +185 -0
- package/schema/DatabaseTable.d.ts +68 -0
- package/schema/DatabaseTable.js +793 -0
- package/schema/SchemaComparator.d.ts +58 -0
- package/schema/SchemaComparator.js +577 -0
- package/schema/SchemaHelper.d.ts +76 -0
- package/schema/SchemaHelper.js +545 -0
- package/schema/SqlSchemaGenerator.d.ts +65 -0
- package/schema/SqlSchemaGenerator.js +375 -0
- package/schema/index.d.ts +5 -0
- package/schema/index.js +5 -0
- package/typings.d.ts +272 -0
- package/typings.js +1 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { AbstractSchemaGenerator, Utils, } from '@mikro-orm/core';
|
|
2
|
+
import { DatabaseSchema } from './DatabaseSchema.js';
|
|
3
|
+
import { SchemaComparator } from './SchemaComparator.js';
|
|
4
|
+
export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
5
|
+
helper = this.platform.getSchemaHelper();
|
|
6
|
+
options = this.config.get('schemaGenerator');
|
|
7
|
+
lastEnsuredDatabase;
|
|
8
|
+
static register(orm) {
|
|
9
|
+
orm.config.registerExtension('@mikro-orm/schema-generator', () => new SqlSchemaGenerator(orm.em));
|
|
10
|
+
}
|
|
11
|
+
async create(options) {
|
|
12
|
+
await this.ensureDatabase();
|
|
13
|
+
const sql = await this.getCreateSchemaSQL(options);
|
|
14
|
+
await this.execute(sql);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns true if the database was created.
|
|
18
|
+
*/
|
|
19
|
+
async ensureDatabase(options) {
|
|
20
|
+
await this.connection.ensureConnection();
|
|
21
|
+
const dbName = this.config.get('dbName');
|
|
22
|
+
if (this.lastEnsuredDatabase === dbName && !options?.forceCheck) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const exists = await this.helper.databaseExists(this.connection, dbName);
|
|
26
|
+
this.lastEnsuredDatabase = dbName;
|
|
27
|
+
if (!exists) {
|
|
28
|
+
const managementDbName = this.helper.getManagementDbName();
|
|
29
|
+
if (managementDbName) {
|
|
30
|
+
this.config.set('dbName', managementDbName);
|
|
31
|
+
await this.driver.reconnect({ skipOnConnect: true });
|
|
32
|
+
await this.createDatabase(dbName, { skipOnConnect: true });
|
|
33
|
+
}
|
|
34
|
+
if (options?.create) {
|
|
35
|
+
await this.create(options);
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
/* v8 ignore next */
|
|
40
|
+
if (options?.clear) {
|
|
41
|
+
await this.clear({ ...options, clearIdentityMap: false });
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
getTargetSchema(schema) {
|
|
46
|
+
const metadata = this.getOrderedMetadata(schema);
|
|
47
|
+
const schemaName = schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
|
|
48
|
+
return DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schemaName);
|
|
49
|
+
}
|
|
50
|
+
getOrderedMetadata(schema) {
|
|
51
|
+
const metadata = super.getOrderedMetadata(schema);
|
|
52
|
+
// Filter out skipped tables
|
|
53
|
+
return metadata.filter(meta => {
|
|
54
|
+
const tableName = meta.tableName;
|
|
55
|
+
const tableSchema = meta.schema ?? schema ?? this.config.get('schema');
|
|
56
|
+
return !this.isTableSkipped(tableName, tableSchema);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async getCreateSchemaSQL(options = {}) {
|
|
60
|
+
const toSchema = this.getTargetSchema(options.schema);
|
|
61
|
+
const ret = [];
|
|
62
|
+
for (const namespace of toSchema.getNamespaces()) {
|
|
63
|
+
if (namespace === this.platform.getDefaultSchemaName()) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const sql = this.helper.getCreateNamespaceSQL(namespace);
|
|
67
|
+
this.append(ret, sql);
|
|
68
|
+
}
|
|
69
|
+
if (this.platform.supportsNativeEnums()) {
|
|
70
|
+
const created = [];
|
|
71
|
+
for (const [enumName, enumOptions] of Object.entries(toSchema.getNativeEnums())) {
|
|
72
|
+
/* v8 ignore next */
|
|
73
|
+
if (created.includes(enumName)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
created.push(enumName);
|
|
77
|
+
const sql = this.helper.getCreateNativeEnumSQL(enumOptions.name, enumOptions.items, this.getSchemaName(enumOptions, options));
|
|
78
|
+
this.append(ret, sql);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const table of toSchema.getTables()) {
|
|
82
|
+
this.append(ret, this.helper.createTable(table), true);
|
|
83
|
+
}
|
|
84
|
+
if (this.helper.supportsSchemaConstraints()) {
|
|
85
|
+
for (const table of toSchema.getTables()) {
|
|
86
|
+
const fks = Object.values(table.getForeignKeys()).map(fk => this.helper.createForeignKey(table, fk));
|
|
87
|
+
this.append(ret, fks, true);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return this.wrapSchema(ret, options);
|
|
91
|
+
}
|
|
92
|
+
async drop(options = {}) {
|
|
93
|
+
if (options.dropDb) {
|
|
94
|
+
const name = this.config.get('dbName');
|
|
95
|
+
return this.dropDatabase(name);
|
|
96
|
+
}
|
|
97
|
+
const sql = await this.getDropSchemaSQL(options);
|
|
98
|
+
await this.execute(sql);
|
|
99
|
+
}
|
|
100
|
+
async createNamespace(name) {
|
|
101
|
+
const sql = this.helper.getCreateNamespaceSQL(name);
|
|
102
|
+
await this.execute(sql);
|
|
103
|
+
}
|
|
104
|
+
async dropNamespace(name) {
|
|
105
|
+
const sql = this.helper.getDropNamespaceSQL(name);
|
|
106
|
+
await this.execute(sql);
|
|
107
|
+
}
|
|
108
|
+
async clear(options) {
|
|
109
|
+
// truncate by default, so no value is considered as true
|
|
110
|
+
/* v8 ignore next */
|
|
111
|
+
if (options?.truncate === false) {
|
|
112
|
+
return super.clear(options);
|
|
113
|
+
}
|
|
114
|
+
await this.execute(this.helper.disableForeignKeysSQL());
|
|
115
|
+
const schema = options?.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
|
|
116
|
+
for (const meta of this.getOrderedMetadata(schema).reverse()) {
|
|
117
|
+
await this.driver.createQueryBuilder(meta.className, this.em?.getTransactionContext(), 'write', false)
|
|
118
|
+
.withSchema(schema)
|
|
119
|
+
.truncate()
|
|
120
|
+
.execute();
|
|
121
|
+
}
|
|
122
|
+
await this.execute(this.helper.enableForeignKeysSQL());
|
|
123
|
+
if (options?.clearIdentityMap ?? true) {
|
|
124
|
+
this.clearIdentityMap();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async getDropSchemaSQL(options = {}) {
|
|
128
|
+
await this.ensureDatabase();
|
|
129
|
+
const metadata = this.getOrderedMetadata(options.schema).reverse();
|
|
130
|
+
const schemas = this.getTargetSchema(options.schema).getNamespaces();
|
|
131
|
+
const schema = await DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas);
|
|
132
|
+
const ret = [];
|
|
133
|
+
// remove FKs explicitly if we can't use a cascading statement and we don't disable FK checks (we need this for circular relations)
|
|
134
|
+
for (const meta of metadata) {
|
|
135
|
+
if (!this.platform.usesCascadeStatement() && (!this.options.disableForeignKeys || options.dropForeignKeys)) {
|
|
136
|
+
const table = schema.getTable(meta.tableName);
|
|
137
|
+
if (!table) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const foreignKeys = Object.values(table.getForeignKeys());
|
|
141
|
+
for (const fk of foreignKeys) {
|
|
142
|
+
this.append(ret, this.helper.dropForeignKey(table.getShortestName(), fk.constraintName));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const meta of metadata) {
|
|
147
|
+
this.append(ret, this.helper.dropTableIfExists(meta.tableName, this.getSchemaName(meta, options)));
|
|
148
|
+
}
|
|
149
|
+
if (this.platform.supportsNativeEnums()) {
|
|
150
|
+
for (const columnName of Object.keys(schema.getNativeEnums())) {
|
|
151
|
+
const sql = this.helper.getDropNativeEnumSQL(columnName, options.schema ?? this.config.get('schema'));
|
|
152
|
+
this.append(ret, sql);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (options.dropMigrationsTable) {
|
|
156
|
+
this.append(ret, this.helper.dropTableIfExists(this.config.get('migrations').tableName, this.config.get('schema')));
|
|
157
|
+
}
|
|
158
|
+
return this.wrapSchema(ret, options);
|
|
159
|
+
}
|
|
160
|
+
getSchemaName(meta, options) {
|
|
161
|
+
const schemaName = options.schema ?? this.config.get('schema');
|
|
162
|
+
/* v8 ignore next */
|
|
163
|
+
const resolvedName = meta.schema && meta.schema === '*' ? schemaName : (meta.schema ?? schemaName);
|
|
164
|
+
// skip default schema name
|
|
165
|
+
if (resolvedName === this.platform.getDefaultSchemaName()) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
return resolvedName;
|
|
169
|
+
}
|
|
170
|
+
async update(options = {}) {
|
|
171
|
+
const sql = await this.getUpdateSchemaSQL(options);
|
|
172
|
+
await this.execute(sql);
|
|
173
|
+
}
|
|
174
|
+
async getUpdateSchemaSQL(options = {}) {
|
|
175
|
+
await this.ensureDatabase();
|
|
176
|
+
const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
|
|
177
|
+
const comparator = new SchemaComparator(this.platform);
|
|
178
|
+
const diffUp = comparator.compare(fromSchema, toSchema);
|
|
179
|
+
return this.diffToSQL(diffUp, options);
|
|
180
|
+
}
|
|
181
|
+
async getUpdateSchemaMigrationSQL(options = {}) {
|
|
182
|
+
if (!options.fromSchema) {
|
|
183
|
+
await this.ensureDatabase();
|
|
184
|
+
}
|
|
185
|
+
const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
|
|
186
|
+
const comparator = new SchemaComparator(this.platform);
|
|
187
|
+
const diffUp = comparator.compare(fromSchema, toSchema);
|
|
188
|
+
const diffDown = comparator.compare(toSchema, fromSchema, diffUp);
|
|
189
|
+
return {
|
|
190
|
+
up: this.diffToSQL(diffUp, options),
|
|
191
|
+
down: this.platform.supportsDownMigrations() ? this.diffToSQL(diffDown, options) : '',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async prepareSchemaForComparison(options) {
|
|
195
|
+
options.safe ??= false;
|
|
196
|
+
options.dropTables ??= true;
|
|
197
|
+
const toSchema = this.getTargetSchema(options.schema);
|
|
198
|
+
const schemas = toSchema.getNamespaces();
|
|
199
|
+
const fromSchema = options.fromSchema ?? (await DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas, undefined, this.options.skipTables));
|
|
200
|
+
const wildcardSchemaTables = Object.values(this.metadata.getAll()).filter(meta => meta.schema === '*').map(meta => meta.tableName);
|
|
201
|
+
fromSchema.prune(options.schema, wildcardSchemaTables);
|
|
202
|
+
toSchema.prune(options.schema, wildcardSchemaTables);
|
|
203
|
+
return { fromSchema, toSchema };
|
|
204
|
+
}
|
|
205
|
+
diffToSQL(schemaDiff, options) {
|
|
206
|
+
const ret = [];
|
|
207
|
+
globalThis.idx = 0;
|
|
208
|
+
if (this.platform.supportsSchemas()) {
|
|
209
|
+
for (const newNamespace of schemaDiff.newNamespaces) {
|
|
210
|
+
const sql = this.helper.getCreateNamespaceSQL(newNamespace);
|
|
211
|
+
this.append(ret, sql);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (this.platform.supportsNativeEnums()) {
|
|
215
|
+
for (const newNativeEnum of schemaDiff.newNativeEnums) {
|
|
216
|
+
const sql = this.helper.getCreateNativeEnumSQL(newNativeEnum.name, newNativeEnum.items, this.getSchemaName(newNativeEnum, options));
|
|
217
|
+
this.append(ret, sql);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (!options.safe && this.options.createForeignKeyConstraints) {
|
|
221
|
+
for (const orphanedForeignKey of schemaDiff.orphanedForeignKeys) {
|
|
222
|
+
const [schemaName, tableName] = this.helper.splitTableName(orphanedForeignKey.localTableName, true);
|
|
223
|
+
/* v8 ignore next */
|
|
224
|
+
const name = (schemaName ? schemaName + '.' : '') + tableName;
|
|
225
|
+
this.append(ret, this.helper.dropForeignKey(name, orphanedForeignKey.constraintName));
|
|
226
|
+
}
|
|
227
|
+
if (schemaDiff.orphanedForeignKeys.length > 0) {
|
|
228
|
+
ret.push('');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
for (const newTable of Object.values(schemaDiff.newTables)) {
|
|
232
|
+
this.append(ret, this.helper.createTable(newTable, true), true);
|
|
233
|
+
}
|
|
234
|
+
if (this.helper.supportsSchemaConstraints()) {
|
|
235
|
+
for (const newTable of Object.values(schemaDiff.newTables)) {
|
|
236
|
+
const sql = [];
|
|
237
|
+
if (this.options.createForeignKeyConstraints) {
|
|
238
|
+
const fks = Object.values(newTable.getForeignKeys()).map(fk => this.helper.createForeignKey(newTable, fk));
|
|
239
|
+
this.append(sql, fks);
|
|
240
|
+
}
|
|
241
|
+
for (const check of newTable.getChecks()) {
|
|
242
|
+
this.append(sql, this.helper.createCheck(newTable, check));
|
|
243
|
+
}
|
|
244
|
+
this.append(ret, sql, true);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (options.dropTables && !options.safe) {
|
|
248
|
+
for (const table of Object.values(schemaDiff.removedTables)) {
|
|
249
|
+
this.append(ret, this.helper.dropTableIfExists(table.name, table.schema));
|
|
250
|
+
}
|
|
251
|
+
if (Utils.hasObjectKeys(schemaDiff.removedTables)) {
|
|
252
|
+
ret.push('');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
for (const changedTable of Object.values(schemaDiff.changedTables)) {
|
|
256
|
+
this.append(ret, this.preAlterTable(changedTable, options.safe), true);
|
|
257
|
+
}
|
|
258
|
+
for (const changedTable of Object.values(schemaDiff.changedTables)) {
|
|
259
|
+
this.append(ret, this.helper.alterTable(changedTable, options.safe), true);
|
|
260
|
+
}
|
|
261
|
+
for (const changedTable of Object.values(schemaDiff.changedTables)) {
|
|
262
|
+
this.append(ret, this.helper.getPostAlterTable(changedTable, options.safe), true);
|
|
263
|
+
}
|
|
264
|
+
if (!options.safe && this.platform.supportsNativeEnums()) {
|
|
265
|
+
for (const removedNativeEnum of schemaDiff.removedNativeEnums) {
|
|
266
|
+
this.append(ret, this.helper.getDropNativeEnumSQL(removedNativeEnum.name, removedNativeEnum.schema));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (options.dropTables && !options.safe) {
|
|
270
|
+
for (const removedNamespace of schemaDiff.removedNamespaces) {
|
|
271
|
+
const sql = this.helper.getDropNamespaceSQL(removedNamespace);
|
|
272
|
+
this.append(ret, sql);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return this.wrapSchema(ret, options);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* We need to drop foreign keys first for all tables to allow dropping PK constraints.
|
|
279
|
+
*/
|
|
280
|
+
preAlterTable(diff, safe) {
|
|
281
|
+
const ret = [];
|
|
282
|
+
this.append(ret, this.helper.getPreAlterTable(diff, safe));
|
|
283
|
+
for (const foreignKey of Object.values(diff.removedForeignKeys)) {
|
|
284
|
+
ret.push(this.helper.dropForeignKey(diff.toTable.getShortestName(), foreignKey.constraintName));
|
|
285
|
+
}
|
|
286
|
+
for (const foreignKey of Object.values(diff.changedForeignKeys)) {
|
|
287
|
+
ret.push(this.helper.dropForeignKey(diff.toTable.getShortestName(), foreignKey.constraintName));
|
|
288
|
+
}
|
|
289
|
+
return ret;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* creates new database and connects to it
|
|
293
|
+
*/
|
|
294
|
+
async createDatabase(name, options) {
|
|
295
|
+
name ??= this.config.get('dbName');
|
|
296
|
+
const sql = this.helper.getCreateDatabaseSQL('' + this.platform.quoteIdentifier(name));
|
|
297
|
+
if (sql) {
|
|
298
|
+
await this.execute(sql);
|
|
299
|
+
}
|
|
300
|
+
this.config.set('dbName', name);
|
|
301
|
+
await this.driver.reconnect(options);
|
|
302
|
+
}
|
|
303
|
+
async dropDatabase(name) {
|
|
304
|
+
name ??= this.config.get('dbName');
|
|
305
|
+
this.config.set('dbName', this.helper.getManagementDbName());
|
|
306
|
+
await this.driver.reconnect();
|
|
307
|
+
await this.execute(this.helper.getDropDatabaseSQL(name));
|
|
308
|
+
this.config.set('dbName', name);
|
|
309
|
+
}
|
|
310
|
+
async execute(sql, options = {}) {
|
|
311
|
+
options.wrap ??= false;
|
|
312
|
+
const lines = this.wrapSchema(sql, options).split('\n');
|
|
313
|
+
const groups = [];
|
|
314
|
+
let i = 0;
|
|
315
|
+
for (const line of lines) {
|
|
316
|
+
if (line.trim() === '') {
|
|
317
|
+
if (groups[i]?.length > 0) {
|
|
318
|
+
i++;
|
|
319
|
+
}
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
groups[i] ??= [];
|
|
323
|
+
groups[i].push(line.trim());
|
|
324
|
+
}
|
|
325
|
+
if (groups.length === 0) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (this.platform.supportsMultipleStatements()) {
|
|
329
|
+
for (const group of groups) {
|
|
330
|
+
const query = group.join('\n');
|
|
331
|
+
await this.driver.execute(query);
|
|
332
|
+
}
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
await Utils.runSerial(groups.flat(), line => this.driver.execute(line));
|
|
336
|
+
}
|
|
337
|
+
async dropTableIfExists(name, schema) {
|
|
338
|
+
const sql = this.helper.dropTableIfExists(name, schema);
|
|
339
|
+
return this.execute(sql);
|
|
340
|
+
}
|
|
341
|
+
wrapSchema(sql, options) {
|
|
342
|
+
const array = Utils.asArray(sql);
|
|
343
|
+
if (array.length === 0) {
|
|
344
|
+
return '';
|
|
345
|
+
}
|
|
346
|
+
if (array[array.length - 1] === '') {
|
|
347
|
+
array.pop();
|
|
348
|
+
}
|
|
349
|
+
if (options.wrap === false) {
|
|
350
|
+
return array.join('\n') + '\n';
|
|
351
|
+
}
|
|
352
|
+
let ret = this.helper.getSchemaBeginning(this.config.get('charset'), this.options.disableForeignKeys);
|
|
353
|
+
ret += array.join('\n') + '\n';
|
|
354
|
+
ret += this.helper.getSchemaEnd(this.options.disableForeignKeys);
|
|
355
|
+
return ret;
|
|
356
|
+
}
|
|
357
|
+
append(array, sql, pad) {
|
|
358
|
+
return this.helper.append(array, sql, pad);
|
|
359
|
+
}
|
|
360
|
+
matchName(name, nameToMatch) {
|
|
361
|
+
return typeof nameToMatch === 'string'
|
|
362
|
+
? name.toLocaleLowerCase() === nameToMatch.toLocaleLowerCase()
|
|
363
|
+
: nameToMatch.test(name);
|
|
364
|
+
}
|
|
365
|
+
isTableSkipped(tableName, schemaName) {
|
|
366
|
+
const skipTables = this.options.skipTables;
|
|
367
|
+
if (!skipTables || skipTables.length === 0) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
const fullTableName = schemaName ? `${schemaName}.${tableName}` : tableName;
|
|
371
|
+
return skipTables.some(pattern => this.matchName(tableName, pattern) || this.matchName(fullTableName, pattern));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// for back compatibility
|
|
375
|
+
export { SqlSchemaGenerator as SchemaGenerator };
|
package/schema/index.js
ADDED
package/typings.d.ts
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import type { Generated, Kysely } from 'kysely';
|
|
2
|
+
import type { DeferMode, CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type, QueryFlag, AnyEntity, EntityName, EntitySchemaWithMeta, Primary, PrimaryProperty, Opt } from '@mikro-orm/core';
|
|
3
|
+
import type { JoinType, QueryType } from './query/enums.js';
|
|
4
|
+
import type { DatabaseSchema } from './schema/DatabaseSchema.js';
|
|
5
|
+
import type { DatabaseTable } from './schema/DatabaseTable.js';
|
|
6
|
+
import type { QueryBuilder } from './query/QueryBuilder.js';
|
|
7
|
+
import type { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
|
|
8
|
+
import type { MikroKyselyPluginOptions } from './plugin/index.js';
|
|
9
|
+
export interface Table {
|
|
10
|
+
table_name: string;
|
|
11
|
+
schema_name?: string;
|
|
12
|
+
table_comment?: string;
|
|
13
|
+
}
|
|
14
|
+
type AnyString = string & {};
|
|
15
|
+
export type Field<T> = AnyString | keyof T | RawQueryFragment | QueryBuilder | NativeQueryBuilder;
|
|
16
|
+
export interface JoinOptions {
|
|
17
|
+
table: string;
|
|
18
|
+
schema?: string;
|
|
19
|
+
type: JoinType;
|
|
20
|
+
alias: string;
|
|
21
|
+
ownerAlias: string;
|
|
22
|
+
inverseAlias?: string;
|
|
23
|
+
joinColumns?: string[];
|
|
24
|
+
inverseJoinColumns?: string[];
|
|
25
|
+
primaryKeys?: string[];
|
|
26
|
+
path?: string;
|
|
27
|
+
prop: EntityProperty;
|
|
28
|
+
cond: Dictionary;
|
|
29
|
+
cond_?: Dictionary;
|
|
30
|
+
subquery?: string;
|
|
31
|
+
nested?: Set<JoinOptions>;
|
|
32
|
+
parent?: JoinOptions;
|
|
33
|
+
}
|
|
34
|
+
export interface Column {
|
|
35
|
+
name: string;
|
|
36
|
+
type: string;
|
|
37
|
+
mappedType: Type<unknown>;
|
|
38
|
+
unsigned?: boolean;
|
|
39
|
+
autoincrement?: boolean;
|
|
40
|
+
nullable?: boolean;
|
|
41
|
+
length?: number;
|
|
42
|
+
precision?: number;
|
|
43
|
+
scale?: number;
|
|
44
|
+
default?: string | null;
|
|
45
|
+
defaultConstraint?: string;
|
|
46
|
+
comment?: string;
|
|
47
|
+
generated?: string;
|
|
48
|
+
nativeEnumName?: string;
|
|
49
|
+
enumItems?: string[];
|
|
50
|
+
primary?: boolean;
|
|
51
|
+
unique?: boolean;
|
|
52
|
+
/** mysql only */
|
|
53
|
+
extra?: string;
|
|
54
|
+
ignoreSchemaChanges?: ('type' | 'extra' | 'default')[];
|
|
55
|
+
}
|
|
56
|
+
export interface ForeignKey {
|
|
57
|
+
columnNames: string[];
|
|
58
|
+
constraintName: string;
|
|
59
|
+
localTableName: string;
|
|
60
|
+
referencedTableName: string;
|
|
61
|
+
referencedColumnNames: string[];
|
|
62
|
+
updateRule?: string;
|
|
63
|
+
deleteRule?: string;
|
|
64
|
+
deferMode?: DeferMode;
|
|
65
|
+
}
|
|
66
|
+
export interface IndexDef {
|
|
67
|
+
columnNames: string[];
|
|
68
|
+
keyName: string;
|
|
69
|
+
unique: boolean;
|
|
70
|
+
constraint: boolean;
|
|
71
|
+
primary: boolean;
|
|
72
|
+
composite?: boolean;
|
|
73
|
+
expression?: string;
|
|
74
|
+
options?: Dictionary;
|
|
75
|
+
type?: string | Readonly<{
|
|
76
|
+
indexType?: string;
|
|
77
|
+
storageEngineIndexType?: 'hash' | 'btree';
|
|
78
|
+
predicate?: string;
|
|
79
|
+
}>;
|
|
80
|
+
deferMode?: DeferMode | `${DeferMode}`;
|
|
81
|
+
}
|
|
82
|
+
export interface CheckDef<T = unknown> {
|
|
83
|
+
name: string;
|
|
84
|
+
expression: string | CheckCallback<T>;
|
|
85
|
+
definition?: string;
|
|
86
|
+
columnName?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface ColumnDifference {
|
|
89
|
+
oldColumnName: string;
|
|
90
|
+
column: Column;
|
|
91
|
+
fromColumn: Column;
|
|
92
|
+
changedProperties: Set<string>;
|
|
93
|
+
}
|
|
94
|
+
export interface TableDifference {
|
|
95
|
+
name: string;
|
|
96
|
+
changedComment?: string;
|
|
97
|
+
fromTable: DatabaseTable;
|
|
98
|
+
toTable: DatabaseTable;
|
|
99
|
+
addedColumns: Dictionary<Column>;
|
|
100
|
+
changedColumns: Dictionary<ColumnDifference>;
|
|
101
|
+
removedColumns: Dictionary<Column>;
|
|
102
|
+
renamedColumns: Dictionary<Column>;
|
|
103
|
+
addedIndexes: Dictionary<IndexDef>;
|
|
104
|
+
changedIndexes: Dictionary<IndexDef>;
|
|
105
|
+
removedIndexes: Dictionary<IndexDef>;
|
|
106
|
+
renamedIndexes: Dictionary<IndexDef>;
|
|
107
|
+
addedChecks: Dictionary<CheckDef>;
|
|
108
|
+
changedChecks: Dictionary<CheckDef>;
|
|
109
|
+
removedChecks: Dictionary<CheckDef>;
|
|
110
|
+
addedForeignKeys: Dictionary<ForeignKey>;
|
|
111
|
+
changedForeignKeys: Dictionary<ForeignKey>;
|
|
112
|
+
removedForeignKeys: Dictionary<ForeignKey>;
|
|
113
|
+
}
|
|
114
|
+
export interface SchemaDifference {
|
|
115
|
+
newNamespaces: Set<string>;
|
|
116
|
+
newNativeEnums: {
|
|
117
|
+
name: string;
|
|
118
|
+
schema?: string;
|
|
119
|
+
items: string[];
|
|
120
|
+
}[];
|
|
121
|
+
newTables: Dictionary<DatabaseTable>;
|
|
122
|
+
changedTables: Dictionary<TableDifference>;
|
|
123
|
+
removedTables: Dictionary<DatabaseTable>;
|
|
124
|
+
removedNamespaces: Set<string>;
|
|
125
|
+
removedNativeEnums: {
|
|
126
|
+
name: string;
|
|
127
|
+
schema?: string;
|
|
128
|
+
}[];
|
|
129
|
+
orphanedForeignKeys: ForeignKey[];
|
|
130
|
+
fromSchema: DatabaseSchema;
|
|
131
|
+
}
|
|
132
|
+
export interface IQueryBuilder<T> {
|
|
133
|
+
readonly alias: string;
|
|
134
|
+
readonly type: QueryType;
|
|
135
|
+
_fields?: Field<T>[];
|
|
136
|
+
/** @internal */
|
|
137
|
+
helper: any;
|
|
138
|
+
select(fields: Field<T> | Field<T>[], distinct?: boolean): this;
|
|
139
|
+
addSelect(fields: string | string[]): this;
|
|
140
|
+
from<T extends AnyEntity<T> = AnyEntity>(target: EntityName<T> | IQueryBuilder<T>, aliasName?: string): IQueryBuilder<T>;
|
|
141
|
+
insert(data: any): this;
|
|
142
|
+
update(data: any): this;
|
|
143
|
+
delete(cond?: QBFilterQuery): this;
|
|
144
|
+
truncate(): this;
|
|
145
|
+
count(field?: string | string[], distinct?: boolean): this;
|
|
146
|
+
join(field: string, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string): this;
|
|
147
|
+
innerJoin(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
148
|
+
leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
149
|
+
joinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
|
|
150
|
+
leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
|
|
151
|
+
innerJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
|
|
152
|
+
withSubQuery(subQuery: RawQueryFragment | NativeQueryBuilder, alias: string): this;
|
|
153
|
+
where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
|
|
154
|
+
where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;
|
|
155
|
+
andWhere(cond: QBFilterQuery<T>): this;
|
|
156
|
+
andWhere(cond: string, params?: any[]): this;
|
|
157
|
+
orWhere(cond: QBFilterQuery<T>): this;
|
|
158
|
+
orWhere(cond: string, params?: any[]): this;
|
|
159
|
+
orderBy(orderBy: QueryOrderMap<T>): this;
|
|
160
|
+
groupBy(fields: (string | keyof T) | (string | keyof T)[]): this;
|
|
161
|
+
having(cond?: QBFilterQuery | string, params?: any[]): this;
|
|
162
|
+
getAliasForJoinPath(path: string, options?: ICriteriaNodeProcessOptions): string | undefined;
|
|
163
|
+
getJoinForPath(path?: string, options?: ICriteriaNodeProcessOptions): JoinOptions | undefined;
|
|
164
|
+
getNextAlias(entityName?: string): string;
|
|
165
|
+
clone(reset?: boolean): IQueryBuilder<T>;
|
|
166
|
+
setFlag(flag: QueryFlag): this;
|
|
167
|
+
unsetFlag(flag: QueryFlag): this;
|
|
168
|
+
hasFlag(flag: QueryFlag): boolean;
|
|
169
|
+
scheduleFilterCheck(path: string): void;
|
|
170
|
+
}
|
|
171
|
+
export interface ICriteriaNodeProcessOptions {
|
|
172
|
+
alias?: string;
|
|
173
|
+
matchPopulateJoins?: boolean;
|
|
174
|
+
ignoreBranching?: boolean;
|
|
175
|
+
preferNoBranch?: boolean;
|
|
176
|
+
type?: 'orderBy';
|
|
177
|
+
filter?: boolean;
|
|
178
|
+
}
|
|
179
|
+
export interface ICriteriaNode<T extends object> {
|
|
180
|
+
readonly entityName: string;
|
|
181
|
+
readonly parent?: ICriteriaNode<T> | undefined;
|
|
182
|
+
readonly key?: string | undefined;
|
|
183
|
+
readonly strict?: boolean;
|
|
184
|
+
payload: any;
|
|
185
|
+
prop?: EntityProperty;
|
|
186
|
+
index?: number;
|
|
187
|
+
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
188
|
+
shouldInline(payload: any): boolean;
|
|
189
|
+
willAutoJoin(qb: IQueryBuilder<T>, alias?: string, options?: ICriteriaNodeProcessOptions): boolean;
|
|
190
|
+
shouldRename(payload: any): boolean;
|
|
191
|
+
renameFieldToPK<T>(qb: IQueryBuilder<T>, ownerAlias?: string): string;
|
|
192
|
+
getPath(addIndex?: boolean): string;
|
|
193
|
+
getPivotPath(path: string): string;
|
|
194
|
+
}
|
|
195
|
+
export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
|
|
196
|
+
export type InferEntityProperties<Schema> = Schema extends EntitySchemaWithMeta<any, any, any, any, infer Properties> ? Properties : never;
|
|
197
|
+
export type InferKyselyDB<TEntities extends {
|
|
198
|
+
name: string;
|
|
199
|
+
}, TOptions extends MikroKyselyPluginOptions = {}> = MapValueAsTable<MapByName<TEntities>, TOptions>;
|
|
200
|
+
export type InferDBFromKysely<TKysely extends Kysely<any>> = TKysely extends Kysely<infer TDB> ? TDB : never;
|
|
201
|
+
type PreferStringLiteral<TCandidate, TFallback> = [
|
|
202
|
+
TCandidate
|
|
203
|
+
] extends [never] ? TFallback : string extends TCandidate ? TFallback : TCandidate extends string ? TCandidate : TFallback;
|
|
204
|
+
export type MapByName<T extends {
|
|
205
|
+
name: string;
|
|
206
|
+
tableName?: string;
|
|
207
|
+
}> = {
|
|
208
|
+
[P in T as PreferStringLiteral<NonNullable<P['tableName']>, P['name']>]: P;
|
|
209
|
+
};
|
|
210
|
+
export type MapValueAsTable<TMap extends Record<string, any>, TOptions extends MikroKyselyPluginOptions = {}> = {
|
|
211
|
+
[K in keyof TMap as TransformName<K, TOptions['tableNamingStrategy'] extends 'entity' ? 'entity' : 'underscore'>]: InferKyselyTable<TMap[K], TOptions>;
|
|
212
|
+
};
|
|
213
|
+
export type InferKyselyTable<TSchema extends EntitySchemaWithMeta, TOptions extends MikroKyselyPluginOptions = {}> = ExcludeNever<{
|
|
214
|
+
-readonly [K in keyof InferEntityProperties<TSchema> as TransformColumnName<K, TOptions['columnNamingStrategy'] extends 'property' ? 'property' : 'underscore', MaybeReturnType<InferEntityProperties<TSchema>[K]>>]: InferColumnValue<MaybeReturnType<InferEntityProperties<TSchema>[K]>, TOptions['processOnCreateHooks'] extends true ? true : false>;
|
|
215
|
+
}>;
|
|
216
|
+
type TransformName<TName, TNamingStrategy extends 'underscore' | 'entity'> = TNamingStrategy extends 'underscore' ? TName extends string ? SnakeCase<TName> : TName : TName;
|
|
217
|
+
type TransformColumnName<TName, TNamingStrategy extends 'underscore' | 'property', TBuilder> = TNamingStrategy extends 'property' ? TName : TBuilder extends {
|
|
218
|
+
'~options': {
|
|
219
|
+
fieldName: string;
|
|
220
|
+
};
|
|
221
|
+
} ? TBuilder['~options']['fieldName'] : TName extends string ? MaybeJoinColumnName<SnakeCase<TName>, TBuilder> : never;
|
|
222
|
+
type MaybeJoinColumnName<TName extends string, TBuilder> = TBuilder extends {
|
|
223
|
+
'~type'?: {
|
|
224
|
+
value: infer Value;
|
|
225
|
+
};
|
|
226
|
+
'~options': {
|
|
227
|
+
kind: 'm:1';
|
|
228
|
+
};
|
|
229
|
+
} ? PrimaryProperty<Value> extends string ? `${TName}_${SnakeCase<PrimaryProperty<Value>>}` : never : TBuilder extends {
|
|
230
|
+
'~type'?: {
|
|
231
|
+
value: infer Value;
|
|
232
|
+
};
|
|
233
|
+
'~options': {
|
|
234
|
+
kind: '1:1';
|
|
235
|
+
owner: true;
|
|
236
|
+
};
|
|
237
|
+
} ? PrimaryProperty<Value> extends string ? `${TName}_${SnakeCase<PrimaryProperty<Value>>}` : never : TName;
|
|
238
|
+
export type SnakeCase<TName extends string> = TName extends `${infer P1}${infer P2}` ? P2 extends Uncapitalize<P2> ? `${Uncapitalize<P1>}${SnakeCase<P2>}` : `${Uncapitalize<P1>}_${SnakeCase<Uncapitalize<P2>>}` : TName;
|
|
239
|
+
type InferColumnValue<TBuilder, TProcessOnCreate extends boolean> = TBuilder extends {
|
|
240
|
+
'~type'?: {
|
|
241
|
+
value: infer Value;
|
|
242
|
+
};
|
|
243
|
+
'~options': infer TOptions;
|
|
244
|
+
} ? MaybeNever<MaybeGenerated<MaybeJoinKey<Value, TOptions>, TOptions, TProcessOnCreate>, TOptions> : never;
|
|
245
|
+
type MaybeGenerated<TValue, TOptions, TProcessOnCreate extends boolean> = TOptions extends {
|
|
246
|
+
nullable: true;
|
|
247
|
+
} ? (TValue | null) : TOptions extends {
|
|
248
|
+
autoincrement: true;
|
|
249
|
+
} ? Generated<TValue> : TOptions extends {
|
|
250
|
+
default: true;
|
|
251
|
+
} ? Generated<TValue> : TOptions extends {
|
|
252
|
+
defaultRaw: true;
|
|
253
|
+
} ? Generated<TValue> : TProcessOnCreate extends false ? TValue : TOptions extends {
|
|
254
|
+
onCreate: Function;
|
|
255
|
+
} ? Generated<TValue> : TValue;
|
|
256
|
+
type MaybeJoinKey<TValue, TOptions> = TOptions extends {
|
|
257
|
+
kind: 'm:1';
|
|
258
|
+
} ? UnwrapOpt<Primary<TValue>> : TOptions extends {
|
|
259
|
+
kind: '1:1';
|
|
260
|
+
} ? TOptions extends {
|
|
261
|
+
owner: true;
|
|
262
|
+
} ? UnwrapOpt<Primary<TValue>> : never : TValue;
|
|
263
|
+
type UnwrapOpt<TValue> = TValue extends Opt<infer OriginalValue> ? OriginalValue : TValue;
|
|
264
|
+
type MaybeNever<TValue, TOptions> = TOptions extends {
|
|
265
|
+
persist: true;
|
|
266
|
+
} ? never : TOptions extends {
|
|
267
|
+
kind: 'm:n';
|
|
268
|
+
} ? never : TValue;
|
|
269
|
+
type ExcludeNever<TMap extends Record<string, any>> = {
|
|
270
|
+
[K in keyof TMap as TMap[K] extends never ? never : K]: TMap[K];
|
|
271
|
+
};
|
|
272
|
+
export {};
|
package/typings.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|