@mikro-orm/knex 6.1.13-dev.17 → 6.1.13-dev.19
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.js +7 -1
- package/AbstractSqlDriver.js +3 -5
- package/package.json +2 -2
- package/query/QueryBuilder.js +13 -10
- package/schema/SchemaComparator.js +7 -0
- package/schema/SchemaHelper.d.ts +1 -0
- package/schema/SchemaHelper.js +8 -2
- package/schema/SqlSchemaGenerator.d.ts +3 -2
- package/schema/SqlSchemaGenerator.js +25 -12
package/AbstractSqlConnection.js
CHANGED
|
@@ -125,7 +125,13 @@ class AbstractSqlConnection extends core_1.Connection {
|
|
|
125
125
|
*/
|
|
126
126
|
async loadFile(path) {
|
|
127
127
|
const buf = await (0, fs_extra_1.readFile)(path);
|
|
128
|
-
|
|
128
|
+
try {
|
|
129
|
+
await this.getKnex().raw(buf.toString());
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
/* istanbul ignore next */
|
|
133
|
+
throw this.platform.getExceptionConverter().convertException(e);
|
|
134
|
+
}
|
|
129
135
|
}
|
|
130
136
|
createKnexClient(type) {
|
|
131
137
|
const driverOptions = this.config.get('driverOptions');
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -943,9 +943,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
943
943
|
}
|
|
944
944
|
if (tableAlias) {
|
|
945
945
|
return prop.fieldNames.map(fieldName => {
|
|
946
|
-
|
|
947
|
-
const alias = this.platform.quoteIdentifier(`${tableAlias}__${fieldName}`);
|
|
948
|
-
return (0, core_1.raw)(`${name} as ${alias}`);
|
|
946
|
+
return `${tableAlias}.${fieldName} as ${tableAlias}__${fieldName}`;
|
|
949
947
|
});
|
|
950
948
|
}
|
|
951
949
|
return prop.fieldNames;
|
|
@@ -963,10 +961,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
963
961
|
if (args.ctx) {
|
|
964
962
|
return 'write';
|
|
965
963
|
}
|
|
966
|
-
|
|
964
|
+
if (args.connectionType) {
|
|
967
965
|
return args.connectionType;
|
|
968
966
|
}
|
|
969
|
-
|
|
967
|
+
if (this.config.get('preferReadReplicas')) {
|
|
970
968
|
return 'read';
|
|
971
969
|
}
|
|
972
970
|
return 'write';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.1.13-dev.
|
|
3
|
+
"version": "6.1.13-dev.19",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -66,6 +66,6 @@
|
|
|
66
66
|
"@mikro-orm/core": "^6.1.12"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.1.13-dev.
|
|
69
|
+
"@mikro-orm/core": "6.1.13-dev.19"
|
|
70
70
|
}
|
|
71
71
|
}
|
package/query/QueryBuilder.js
CHANGED
|
@@ -652,8 +652,8 @@ class QueryBuilder {
|
|
|
652
652
|
(0, core_1.helper)(entity).__serializationContext.populate ??= hint;
|
|
653
653
|
hint.forEach(hint => {
|
|
654
654
|
const [propName] = hint.field.split(':', 2);
|
|
655
|
-
const value = entity[propName];
|
|
656
|
-
if (core_1.Utils.isEntity(value
|
|
655
|
+
const value = core_1.Reference.unwrapReference(entity[propName]);
|
|
656
|
+
if (core_1.Utils.isEntity(value)) {
|
|
657
657
|
(0, core_1.helper)(value).populated();
|
|
658
658
|
propagatePopulateHint(value, hint.children ?? []);
|
|
659
659
|
}
|
|
@@ -954,15 +954,19 @@ class QueryBuilder {
|
|
|
954
954
|
/* istanbul ignore next */
|
|
955
955
|
const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false) ?? [];
|
|
956
956
|
if (this.flags.has(core_1.QueryFlag.CONVERT_CUSTOM_TYPES) && (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) && requiresSQLConversion.length > 0) {
|
|
957
|
-
|
|
957
|
+
for (const p of requiresSQLConversion) {
|
|
958
|
+
ret.push(this.helper.mapper(p.name, this.type));
|
|
959
|
+
}
|
|
958
960
|
}
|
|
959
|
-
Object.keys(this._populateMap)
|
|
960
|
-
if (
|
|
961
|
+
for (const f of Object.keys(this._populateMap)) {
|
|
962
|
+
if (type === 'where') {
|
|
961
963
|
const cols = this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[f]);
|
|
962
|
-
|
|
964
|
+
for (const col of cols) {
|
|
965
|
+
ret.push(col);
|
|
966
|
+
}
|
|
963
967
|
}
|
|
964
|
-
}
|
|
965
|
-
return ret;
|
|
968
|
+
}
|
|
969
|
+
return core_1.Utils.unique(ret);
|
|
966
970
|
}
|
|
967
971
|
init(type, data, cond) {
|
|
968
972
|
this.ensureNotFinalized();
|
|
@@ -1204,8 +1208,7 @@ class QueryBuilder {
|
|
|
1204
1208
|
// not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
|
|
1205
1209
|
return field.sql.includes(prop);
|
|
1206
1210
|
}
|
|
1207
|
-
|
|
1208
|
-
return field.toString().includes(prop);
|
|
1211
|
+
return false;
|
|
1209
1212
|
});
|
|
1210
1213
|
if (field instanceof core_1.RawQueryFragment) {
|
|
1211
1214
|
knexQuery.select(this.platform.formatQuery(field.sql, field.params));
|
|
@@ -273,12 +273,19 @@ class SchemaComparator {
|
|
|
273
273
|
*/
|
|
274
274
|
detectColumnRenamings(tableDifferences, inverseTableDiff) {
|
|
275
275
|
const renameCandidates = {};
|
|
276
|
+
const oldFKs = Object.values(tableDifferences.fromTable.getForeignKeys());
|
|
277
|
+
const newFKs = Object.values(tableDifferences.toTable.getForeignKeys());
|
|
276
278
|
for (const addedColumn of Object.values(tableDifferences.addedColumns)) {
|
|
277
279
|
for (const removedColumn of Object.values(tableDifferences.removedColumns)) {
|
|
278
280
|
const diff = this.diffColumn(addedColumn, removedColumn);
|
|
279
281
|
if (diff.size !== 0) {
|
|
280
282
|
continue;
|
|
281
283
|
}
|
|
284
|
+
const wasFK = oldFKs.some(fk => fk.columnNames.includes(removedColumn.name));
|
|
285
|
+
const isFK = newFKs.some(fk => fk.columnNames.includes(addedColumn.name));
|
|
286
|
+
if (wasFK !== isFK) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
282
289
|
const renamedColumn = inverseTableDiff?.renamedColumns[addedColumn.name];
|
|
283
290
|
if (renamedColumn && renamedColumn?.name !== removedColumn.name) {
|
|
284
291
|
continue;
|
package/schema/SchemaHelper.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare abstract class SchemaHelper {
|
|
|
27
27
|
getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
|
|
28
28
|
getDropIndexSQL(tableName: string, index: IndexDef): string;
|
|
29
29
|
getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string;
|
|
30
|
+
getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
|
|
30
31
|
hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
|
|
31
32
|
createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder;
|
|
32
33
|
configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
|
package/schema/SchemaHelper.js
CHANGED
|
@@ -99,6 +99,11 @@ class SchemaHelper {
|
|
|
99
99
|
getRenameIndexSQL(tableName, index, oldIndexName) {
|
|
100
100
|
return [this.getDropIndexSQL(tableName, { ...index, keyName: oldIndexName }), this.getCreateIndexSQL(tableName, index)].join(';\n');
|
|
101
101
|
}
|
|
102
|
+
getDropColumnsSQL(tableName, columns, schemaName) {
|
|
103
|
+
const name = this.platform.quoteIdentifier((schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName);
|
|
104
|
+
const drops = columns.map(column => `drop column ${this.platform.quoteIdentifier(column.name)}`).join(', ');
|
|
105
|
+
return `alter table ${name} ${drops}`;
|
|
106
|
+
}
|
|
102
107
|
hasNonDefaultPrimaryKeyName(table) {
|
|
103
108
|
const pkIndex = table.getPrimaryKey();
|
|
104
109
|
if (!pkIndex || !this.platform.supportsCustomPrimaryKeyNames()) {
|
|
@@ -221,10 +226,11 @@ class SchemaHelper {
|
|
|
221
226
|
return norm[0].replace('(?)', length != null ? `(${length})` : '');
|
|
222
227
|
}
|
|
223
228
|
getCreateDatabaseSQL(name) {
|
|
224
|
-
|
|
229
|
+
// two line breaks to force separate execution
|
|
230
|
+
return `create database ${name};\n\nuse ${name}`;
|
|
225
231
|
}
|
|
226
232
|
getDropDatabaseSQL(name) {
|
|
227
|
-
return `drop database if exists ${name}`;
|
|
233
|
+
return `drop database if exists ${this.platform.quoteIdentifier(name)}`;
|
|
228
234
|
}
|
|
229
235
|
getDatabaseExistsSQL(name) {
|
|
230
236
|
return `select 1 from information_schema.schemata where schema_name = '${name}'`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractSchemaGenerator, type
|
|
1
|
+
import { AbstractSchemaGenerator, type ClearDatabaseOptions, type CreateSchemaOptions, type DropSchemaOptions, type EnsureDatabaseOptions, type ISchemaGenerator, type MikroORM, type Transaction, type UpdateSchemaOptions } from '@mikro-orm/core';
|
|
2
2
|
import type { SchemaDifference } from '../typings';
|
|
3
3
|
import { DatabaseSchema } from './DatabaseSchema';
|
|
4
4
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
@@ -43,10 +43,11 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
43
43
|
/**
|
|
44
44
|
* creates new database and connects to it
|
|
45
45
|
*/
|
|
46
|
-
createDatabase(name
|
|
46
|
+
createDatabase(name?: string): Promise<void>;
|
|
47
47
|
dropDatabase(name?: string): Promise<void>;
|
|
48
48
|
execute(sql: string, options?: {
|
|
49
49
|
wrap?: boolean;
|
|
50
|
+
ctx?: Transaction;
|
|
50
51
|
}): Promise<void>;
|
|
51
52
|
private wrapSchema;
|
|
52
53
|
private createSchemaBuilder;
|
|
@@ -118,7 +118,7 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
118
118
|
// remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
|
|
119
119
|
for (const meta of metadata) {
|
|
120
120
|
const table = schema.getTable(meta.tableName);
|
|
121
|
-
if (!this.platform.usesCascadeStatement() && table && !wrap) {
|
|
121
|
+
if (!this.platform.usesCascadeStatement() && table && (!wrap || options.dropForeignKeys)) {
|
|
122
122
|
for (const fk of Object.values(table.getForeignKeys())) {
|
|
123
123
|
const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
|
|
124
124
|
tbl.dropForeign(fk.columnNames, fk.constraintName);
|
|
@@ -341,10 +341,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
341
341
|
this.dropCheck(table, check);
|
|
342
342
|
}
|
|
343
343
|
/* istanbul ignore else */
|
|
344
|
-
if (!safe) {
|
|
345
|
-
|
|
346
|
-
this.helper.pushTableQuery(table, `alter table ${this.platform.quoteIdentifier(tableName)} drop column ${this.platform.quoteIdentifier(column.name)}`);
|
|
347
|
-
}
|
|
344
|
+
if (!safe && Object.values(diff.removedColumns).length > 0) {
|
|
345
|
+
this.helper.pushTableQuery(table, this.helper.getDropColumnsSQL(tableName, Object.values(diff.removedColumns), schemaName));
|
|
348
346
|
}
|
|
349
347
|
}));
|
|
350
348
|
ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
|
|
@@ -421,9 +419,10 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
421
419
|
* creates new database and connects to it
|
|
422
420
|
*/
|
|
423
421
|
async createDatabase(name) {
|
|
422
|
+
name ??= this.config.get('dbName');
|
|
424
423
|
const sql = this.helper.getCreateDatabaseSQL('' + this.knex.ref(name));
|
|
425
424
|
if (sql) {
|
|
426
|
-
await this.
|
|
425
|
+
await this.execute(sql);
|
|
427
426
|
}
|
|
428
427
|
this.config.set('dbName', name);
|
|
429
428
|
await this.driver.reconnect();
|
|
@@ -432,20 +431,34 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
432
431
|
name ??= this.config.get('dbName');
|
|
433
432
|
this.config.set('dbName', this.helper.getManagementDbName());
|
|
434
433
|
await this.driver.reconnect();
|
|
435
|
-
await this.
|
|
434
|
+
await this.execute(this.helper.getDropDatabaseSQL(name));
|
|
436
435
|
}
|
|
437
436
|
async execute(sql, options = {}) {
|
|
438
437
|
options.wrap ??= false;
|
|
439
|
-
const lines = this.wrapSchema(sql, options).split('\n')
|
|
440
|
-
|
|
438
|
+
const lines = this.wrapSchema(sql, options).split('\n');
|
|
439
|
+
const groups = [];
|
|
440
|
+
let i = 0;
|
|
441
|
+
for (const line of lines) {
|
|
442
|
+
if (line.trim() === '') {
|
|
443
|
+
if (groups[i]?.length > 0) {
|
|
444
|
+
i++;
|
|
445
|
+
}
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
groups[i] ??= [];
|
|
449
|
+
groups[i].push(line.trim());
|
|
450
|
+
}
|
|
451
|
+
if (groups.length === 0) {
|
|
441
452
|
return;
|
|
442
453
|
}
|
|
443
454
|
if (this.platform.supportsMultipleStatements()) {
|
|
444
|
-
const
|
|
445
|
-
|
|
455
|
+
for (const group of groups) {
|
|
456
|
+
const query = group.join('\n');
|
|
457
|
+
await this.driver.execute(query);
|
|
458
|
+
}
|
|
446
459
|
return;
|
|
447
460
|
}
|
|
448
|
-
await core_1.Utils.runSerial(
|
|
461
|
+
await core_1.Utils.runSerial(groups.flat(), line => this.driver.execute(line));
|
|
449
462
|
}
|
|
450
463
|
wrapSchema(sql, options) {
|
|
451
464
|
options.wrap ??= this.options.disableForeignKeys;
|