@mikro-orm/knex 7.0.0-dev.27 → 7.0.0-dev.29

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.
@@ -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>[], populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>): void;
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
  }
@@ -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
- let value = row[prop.name] ?? prop.default;
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, populate, joinedProps, qb) {
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, populate, joinedProps, qb);
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, populate, joinedProps, qb);
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
- return `${indexName.substring(0, 56 - type.length)}_${Utils.hash(indexName, 5)}_${type}`;
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.27",
3
+ "version": "7.0.0-dev.29",
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.4"
57
+ "@mikro-orm/core": "^6.5.7"
58
58
  },
59
59
  "peerDependencies": {
60
- "@mikro-orm/core": "7.0.0-dev.27"
60
+ "@mikro-orm/core": "7.0.0-dev.29"
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.push(...this.options.where.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));
@@ -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(...res.params);
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(...value);
505
+ value.forEach(v => params.push(v));
506
506
  }
507
507
  return `(${value.map(() => '?').join(', ')})`;
508
508
  }
@@ -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
  }
@@ -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 };