@mikro-orm/knex 7.0.0-dev.27 → 7.0.0-dev.28
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/AbstractSqlDriver.d.ts +1 -1
- package/AbstractSqlDriver.js +14 -4
- package/dialects/mysql/MySqlPlatform.js +2 -1
- package/package.json +3 -3
- package/query/NativeQueryBuilder.js +1 -1
- package/query/QueryBuilder.js +2 -0
- package/query/QueryBuilderHelper.js +2 -2
- package/schema/DatabaseSchema.js +18 -2
- package/schema/SchemaHelper.d.ts +2 -0
- package/schema/SqlSchemaGenerator.d.ts +6 -1
- package/schema/SqlSchemaGenerator.js +22 -0
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -72,7 +72,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
72
72
|
protected buildPopulateOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populateOrderBy: QueryOrderMap<T>[], parentPath: string, explicit: boolean, parentAlias?: string): QueryOrderMap<T>[];
|
|
73
73
|
protected buildJoinedPropsOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options?: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>, parentPath?: string): QueryOrderMap<T>[];
|
|
74
74
|
protected normalizeFields<T extends object>(fields: Field<T>[], prefix?: string): string[];
|
|
75
|
-
protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: Field<T>[]
|
|
75
|
+
protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: Field<T>[]): void;
|
|
76
76
|
protected isPopulated<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>, hint: PopulateOptions<T>, name?: string): boolean;
|
|
77
77
|
protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>): Field<T>[];
|
|
78
78
|
}
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -390,7 +390,12 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
390
390
|
sql += ' ' + data.map(() => `select null as ${this.platform.quoteIdentifier(pks[0])}`).join(' union all ');
|
|
391
391
|
}
|
|
392
392
|
const addParams = (prop, row) => {
|
|
393
|
-
|
|
393
|
+
const rowValue = row[prop.name];
|
|
394
|
+
if (prop.nullable && rowValue === null) {
|
|
395
|
+
params.push(null);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
let value = rowValue ?? prop.default;
|
|
394
399
|
if (prop.kind === ReferenceKind.EMBEDDED && prop.object) {
|
|
395
400
|
if (prop.array && value) {
|
|
396
401
|
value = this.platform.cloneEmbeddable(value);
|
|
@@ -999,6 +1004,11 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
999
1004
|
* @internal
|
|
1000
1005
|
*/
|
|
1001
1006
|
mapPropToFieldNames(qb, prop, tableAlias) {
|
|
1007
|
+
if (prop.kind === ReferenceKind.EMBEDDED && !prop.object) {
|
|
1008
|
+
return Object.values(prop.embeddedProps).flatMap(childProp => {
|
|
1009
|
+
return this.mapPropToFieldNames(qb, childProp, tableAlias);
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1002
1012
|
const aliased = this.platform.quoteIdentifier(`${tableAlias}__${prop.fieldNames[0]}`);
|
|
1003
1013
|
if (prop.customTypes?.some(type => type?.convertToJSValueSQL)) {
|
|
1004
1014
|
return prop.fieldNames.map((col, idx) => {
|
|
@@ -1220,7 +1230,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1220
1230
|
}
|
|
1221
1231
|
return ret;
|
|
1222
1232
|
}
|
|
1223
|
-
processField(meta, prop, field, ret
|
|
1233
|
+
processField(meta, prop, field, ret) {
|
|
1224
1234
|
if (!prop || (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner)) {
|
|
1225
1235
|
return;
|
|
1226
1236
|
}
|
|
@@ -1233,7 +1243,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1233
1243
|
const top = parts.shift();
|
|
1234
1244
|
for (const key of Object.keys(prop.embeddedProps)) {
|
|
1235
1245
|
if (!top || key === top) {
|
|
1236
|
-
this.processField(meta, prop.embeddedProps[key], parts.join('.'), ret
|
|
1246
|
+
this.processField(meta, prop.embeddedProps[key], parts.join('.'), ret);
|
|
1237
1247
|
}
|
|
1238
1248
|
}
|
|
1239
1249
|
return;
|
|
@@ -1275,7 +1285,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1275
1285
|
where: {},
|
|
1276
1286
|
aliasMap: qb.getAliasMap(),
|
|
1277
1287
|
});
|
|
1278
|
-
this.processField(meta, prop, parts.join('.'), ret
|
|
1288
|
+
this.processField(meta, prop, parts.join('.'), ret);
|
|
1279
1289
|
}
|
|
1280
1290
|
if (!options.fields.includes('*') && !options.fields.includes(`${qb.alias}.*`)) {
|
|
1281
1291
|
ret.unshift(...meta.primaryKeys.filter(pk => !options.fields.includes(pk)));
|
|
@@ -81,7 +81,8 @@ export class MySqlPlatform extends AbstractSqlPlatform {
|
|
|
81
81
|
}
|
|
82
82
|
const indexName = super.getIndexName(tableName, columns, type);
|
|
83
83
|
if (indexName.length > 64) {
|
|
84
|
-
|
|
84
|
+
const hashAlgorithm = this.config.get('hashAlgorithm');
|
|
85
|
+
return `${indexName.substring(0, 56 - type.length)}_${Utils.hash(indexName, 5, hashAlgorithm)}_${type}`;
|
|
85
86
|
}
|
|
86
87
|
return indexName;
|
|
87
88
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.28",
|
|
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
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"sqlstring": "2.3.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@mikro-orm/core": "^6.5.
|
|
57
|
+
"@mikro-orm/core": "^6.5.7"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
60
|
+
"@mikro-orm/core": "7.0.0-dev.28"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -261,7 +261,7 @@ export class NativeQueryBuilder {
|
|
|
261
261
|
}
|
|
262
262
|
if (this.options.where?.sql.trim()) {
|
|
263
263
|
this.parts.push(`where ${this.options.where.sql}`);
|
|
264
|
-
this.params.
|
|
264
|
+
this.options.where.params.forEach(p => this.params.push(p));
|
|
265
265
|
}
|
|
266
266
|
if (this.options.groupBy) {
|
|
267
267
|
const fields = this.options.groupBy.map(field => this.quote(field));
|
package/query/QueryBuilder.js
CHANGED
|
@@ -917,6 +917,8 @@ export class QueryBuilder {
|
|
|
917
917
|
aliasMap: this.getAliasMap(),
|
|
918
918
|
aliased: [QueryType.SELECT, QueryType.COUNT].includes(this.type),
|
|
919
919
|
});
|
|
920
|
+
const criteriaNode = CriteriaNodeFactory.createNode(this.metadata, prop.targetMeta.className, cond);
|
|
921
|
+
cond = criteriaNode.process(this, { ignoreBranching: true, alias });
|
|
920
922
|
let aliasedName = `${fromAlias}.${prop.name}#${alias}`;
|
|
921
923
|
path ??= `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? entityName)}.${prop.name}`;
|
|
922
924
|
if (prop.kind === ReferenceKind.ONE_TO_MANY) {
|
|
@@ -358,7 +358,7 @@ export class QueryBuilderHelper {
|
|
|
358
358
|
return;
|
|
359
359
|
}
|
|
360
360
|
parts.push(operator === '$or' ? `(${res.sql})` : res.sql);
|
|
361
|
-
params.push(
|
|
361
|
+
res.params.forEach(p => params.push(p));
|
|
362
362
|
}
|
|
363
363
|
appendQuerySubCondition(type, cond, key) {
|
|
364
364
|
const parts = [];
|
|
@@ -502,7 +502,7 @@ export class QueryBuilderHelper {
|
|
|
502
502
|
params.push(item);
|
|
503
503
|
}
|
|
504
504
|
else {
|
|
505
|
-
params.push(
|
|
505
|
+
value.forEach(v => params.push(v));
|
|
506
506
|
}
|
|
507
507
|
return `(${value.map(() => '?').join(', ')})`;
|
|
508
508
|
}
|
package/schema/DatabaseSchema.js
CHANGED
|
@@ -69,6 +69,7 @@ export class DatabaseSchema {
|
|
|
69
69
|
static fromMetadata(metadata, platform, config, schemaName) {
|
|
70
70
|
const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema'));
|
|
71
71
|
const nativeEnums = {};
|
|
72
|
+
const skipColumns = config.get('schemaGenerator').skipColumns || {};
|
|
72
73
|
for (const meta of metadata) {
|
|
73
74
|
for (const prop of meta.props) {
|
|
74
75
|
if (prop.nativeEnumName) {
|
|
@@ -97,7 +98,7 @@ export class DatabaseSchema {
|
|
|
97
98
|
const table = schema.addTable(meta.collection, this.getSchemaName(meta, config, schemaName));
|
|
98
99
|
table.comment = meta.comment;
|
|
99
100
|
for (const prop of meta.props) {
|
|
100
|
-
if (!this.shouldHaveColumn(meta, prop)) {
|
|
101
|
+
if (!this.shouldHaveColumn(meta, prop, skipColumns)) {
|
|
101
102
|
continue;
|
|
102
103
|
}
|
|
103
104
|
table.addColumnFromProperty(prop, meta, config);
|
|
@@ -129,10 +130,25 @@ export class DatabaseSchema {
|
|
|
129
130
|
return ((takeTables?.some(tableNameToMatch => this.matchName(tableName, tableNameToMatch)) ?? true) &&
|
|
130
131
|
!(skipTables?.some(tableNameToMatch => this.matchName(tableName, tableNameToMatch)) ?? false));
|
|
131
132
|
}
|
|
132
|
-
static shouldHaveColumn(meta, prop) {
|
|
133
|
+
static shouldHaveColumn(meta, prop, skipColumns) {
|
|
133
134
|
if (prop.persist === false || (prop.columnTypes?.length ?? 0) === 0) {
|
|
134
135
|
return false;
|
|
135
136
|
}
|
|
137
|
+
// Check if column should be skipped
|
|
138
|
+
if (skipColumns) {
|
|
139
|
+
const tableName = meta.tableName;
|
|
140
|
+
const tableSchema = meta.schema;
|
|
141
|
+
const fullTableName = tableSchema ? `${tableSchema}.${tableName}` : tableName;
|
|
142
|
+
// Check for skipColumns by table name or fully qualified table name
|
|
143
|
+
const columnsToSkip = skipColumns[tableName] || skipColumns[fullTableName];
|
|
144
|
+
if (columnsToSkip) {
|
|
145
|
+
for (const fieldName of prop.fieldNames) {
|
|
146
|
+
if (columnsToSkip.some(pattern => this.matchName(fieldName, pattern))) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
136
152
|
if (prop.kind === ReferenceKind.EMBEDDED && prop.object) {
|
|
137
153
|
return true;
|
|
138
154
|
}
|
package/schema/SchemaHelper.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ export declare abstract class SchemaHelper {
|
|
|
63
63
|
disableForeignKeys?: boolean;
|
|
64
64
|
createForeignKeyConstraints?: boolean;
|
|
65
65
|
ignoreSchema?: string[];
|
|
66
|
+
skipTables?: (string | RegExp)[];
|
|
67
|
+
skipColumns?: Dictionary<(string | RegExp)[]>;
|
|
66
68
|
managementDbName?: string;
|
|
67
69
|
};
|
|
68
70
|
protected processComment(comment: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractSchemaGenerator, type ClearDatabaseOptions, type CreateSchemaOptions, type DropSchemaOptions, type EnsureDatabaseOptions, type ISchemaGenerator, type MikroORM, type Transaction, type UpdateSchemaOptions } from '@mikro-orm/core';
|
|
1
|
+
import { AbstractSchemaGenerator, type ClearDatabaseOptions, type CreateSchemaOptions, type Dictionary, type DropSchemaOptions, type EnsureDatabaseOptions, type EntityMetadata, type ISchemaGenerator, type MikroORM, type Transaction, type UpdateSchemaOptions } from '@mikro-orm/core';
|
|
2
2
|
import type { SchemaDifference } from '../typings.js';
|
|
3
3
|
import { DatabaseSchema } from './DatabaseSchema.js';
|
|
4
4
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
|
|
@@ -8,6 +8,8 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
8
8
|
disableForeignKeys?: boolean;
|
|
9
9
|
createForeignKeyConstraints?: boolean;
|
|
10
10
|
ignoreSchema?: string[];
|
|
11
|
+
skipTables?: (string | RegExp)[];
|
|
12
|
+
skipColumns?: Dictionary<(string | RegExp)[]>;
|
|
11
13
|
managementDbName?: string;
|
|
12
14
|
};
|
|
13
15
|
protected lastEnsuredDatabase?: string;
|
|
@@ -18,6 +20,7 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
18
20
|
*/
|
|
19
21
|
ensureDatabase(options?: EnsureDatabaseOptions): Promise<boolean>;
|
|
20
22
|
getTargetSchema(schema?: string): DatabaseSchema;
|
|
23
|
+
protected getOrderedMetadata(schema?: string): EntityMetadata[];
|
|
21
24
|
getCreateSchemaSQL(options?: CreateSchemaOptions): Promise<string>;
|
|
22
25
|
dropSchema(options?: DropSchemaOptions): Promise<void>;
|
|
23
26
|
createNamespace(name: string): Promise<void>;
|
|
@@ -54,5 +57,7 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
54
57
|
dropTableIfExists(name: string, schema?: string): Promise<void>;
|
|
55
58
|
private wrapSchema;
|
|
56
59
|
private append;
|
|
60
|
+
private matchName;
|
|
61
|
+
private isTableSkipped;
|
|
57
62
|
}
|
|
58
63
|
export { SqlSchemaGenerator as SchemaGenerator };
|
|
@@ -47,6 +47,15 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
47
47
|
const schemaName = schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
|
|
48
48
|
return DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schemaName);
|
|
49
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
|
+
}
|
|
50
59
|
async getCreateSchemaSQL(options = {}) {
|
|
51
60
|
const toSchema = this.getTargetSchema(options.schema);
|
|
52
61
|
const ret = [];
|
|
@@ -346,6 +355,19 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
346
355
|
append(array, sql, pad) {
|
|
347
356
|
return this.helper.append(array, sql, pad);
|
|
348
357
|
}
|
|
358
|
+
matchName(name, nameToMatch) {
|
|
359
|
+
return typeof nameToMatch === 'string'
|
|
360
|
+
? name.toLocaleLowerCase() === nameToMatch.toLocaleLowerCase()
|
|
361
|
+
: nameToMatch.test(name);
|
|
362
|
+
}
|
|
363
|
+
isTableSkipped(tableName, schemaName) {
|
|
364
|
+
const skipTables = this.options.skipTables;
|
|
365
|
+
if (!skipTables || skipTables.length === 0) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
const fullTableName = schemaName ? `${schemaName}.${tableName}` : tableName;
|
|
369
|
+
return skipTables.some(pattern => this.matchName(tableName, pattern) || this.matchName(fullTableName, pattern));
|
|
370
|
+
}
|
|
349
371
|
}
|
|
350
372
|
// for back compatibility
|
|
351
373
|
export { SqlSchemaGenerator as SchemaGenerator };
|