@mikro-orm/mssql 7.0.0-dev.31 → 7.0.0-dev.311

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.
@@ -1,4 +1,4 @@
1
- import { AbstractSqlConnection, type TransactionEventBroadcaster } from '@mikro-orm/knex';
1
+ import { AbstractSqlConnection, type TransactionEventBroadcaster } from '@mikro-orm/sql';
2
2
  import { type ControlledTransaction, MssqlDialect } from 'kysely';
3
3
  import type { ConnectionConfiguration } from 'tedious';
4
4
  export declare class MsSqlConnection extends AbstractSqlConnection {
@@ -1,4 +1,4 @@
1
- import { AbstractSqlConnection, Utils, } from '@mikro-orm/knex';
1
+ import { AbstractSqlConnection, Utils } from '@mikro-orm/sql';
2
2
  import { MssqlDialect } from 'kysely';
3
3
  import * as Tedious from 'tedious';
4
4
  import * as Tarn from 'tarn';
@@ -45,7 +45,7 @@ export class MsSqlConnection extends AbstractSqlConnection {
45
45
  },
46
46
  server: options.host,
47
47
  };
48
- /* v8 ignore next 6 */
48
+ /* v8 ignore next */
49
49
  if (ret.server.includes('\\')) {
50
50
  const [host, ...name] = ret.server.split('\\');
51
51
  ret.server = host;
@@ -68,7 +68,7 @@ export class MsSqlConnection extends AbstractSqlConnection {
68
68
  return res.rows;
69
69
  }
70
70
  const rowCount = res.rows.length;
71
- const hasEmptyCount = (rowCount === 1) && ('' in res.rows[0]);
71
+ const hasEmptyCount = rowCount === 1 && '' in res.rows[0];
72
72
  const emptyRow = hasEmptyCount && Number(res.rows[0]['']);
73
73
  return {
74
74
  affectedRows: hasEmptyCount ? emptyRow : Number(res.numAffectedRows),
package/MsSqlDriver.d.ts CHANGED
@@ -1,10 +1,13 @@
1
- import { type AnyEntity, type Configuration, type ConnectionType, type EntityDictionary, type LoggingOptions, type NativeInsertUpdateManyOptions, type QueryResult, type Transaction } from '@mikro-orm/core';
2
- import { AbstractSqlDriver, type SqlEntityManager } from '@mikro-orm/knex';
1
+ import { type AnyEntity, type Configuration, type ConnectionType, type EntityDictionary, type LoggingOptions, type NativeInsertUpdateManyOptions, type QueryResult, type Transaction, type Constructor, type EntityName } from '@mikro-orm/core';
2
+ import { AbstractSqlDriver, type SqlEntityManager } from '@mikro-orm/sql';
3
3
  import { MsSqlConnection } from './MsSqlConnection.js';
4
4
  import { MsSqlQueryBuilder } from './MsSqlQueryBuilder.js';
5
+ import { MsSqlMikroORM } from './MsSqlMikroORM.js';
5
6
  export declare class MsSqlDriver extends AbstractSqlDriver<MsSqlConnection> {
6
7
  constructor(config: Configuration);
7
- nativeInsertMany<T extends AnyEntity<T>>(entityName: string, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>): Promise<QueryResult<T>>;
8
- createQueryBuilder<T extends AnyEntity<T>>(entityName: string, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): MsSqlQueryBuilder<T, any, any, any>;
8
+ nativeInsertMany<T extends AnyEntity<T>>(entityName: EntityName<T>, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>): Promise<QueryResult<T>>;
9
+ createQueryBuilder<T extends AnyEntity<T>>(entityName: EntityName<T>, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): MsSqlQueryBuilder<T, any, any, any>;
9
10
  private appendOutputTable;
11
+ /** @inheritDoc */
12
+ getORMClass(): Constructor<MsSqlMikroORM>;
10
13
  }
package/MsSqlDriver.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { QueryFlag, Utils, isRaw, } from '@mikro-orm/core';
2
- import { AbstractSqlDriver } from '@mikro-orm/knex';
2
+ import { AbstractSqlDriver } from '@mikro-orm/sql';
3
3
  import { MsSqlConnection } from './MsSqlConnection.js';
4
4
  import { MsSqlPlatform } from './MsSqlPlatform.js';
5
5
  import { MsSqlQueryBuilder } from './MsSqlQueryBuilder.js';
6
+ import { MsSqlMikroORM } from './MsSqlMikroORM.js';
6
7
  export class MsSqlDriver extends AbstractSqlDriver {
7
8
  constructor(config) {
8
9
  super(config, new MsSqlPlatform(), MsSqlConnection, ['kysely', 'tedious']);
@@ -21,10 +22,12 @@ export class MsSqlDriver extends AbstractSqlDriver {
21
22
  const returningFields = Utils.flatten(returningProps.map(prop => prop.fieldNames));
22
23
  const using2 = `select * from (values ${data.map((x, i) => `(${i})`).join(',')}) v (id) where 1 = 1`;
23
24
  /* v8 ignore next */
24
- const output = returningFields.length > 0 ? `output ${returningFields.map(field => 'inserted.' + this.platform.quoteIdentifier(field)).join(', ')}` : '';
25
+ const output = returningFields.length > 0
26
+ ? `output ${returningFields.map(field => 'inserted.' + this.platform.quoteIdentifier(field)).join(', ')}`
27
+ : '';
25
28
  const sql = `merge into ${tableName} using (${using2}) s on 1 = 0 when not matched then insert default values ${output};`;
26
29
  const res = await this.execute(sql, [], 'run', options.ctx);
27
- const pks = this.getPrimaryKeyFields(entityName);
30
+ const pks = this.getPrimaryKeyFields(meta);
28
31
  if (pks.length === 1) {
29
32
  res.row ??= {};
30
33
  res.rows ??= [];
@@ -32,7 +35,8 @@ export class MsSqlDriver extends AbstractSqlDriver {
32
35
  }
33
36
  return res;
34
37
  }
35
- if (props.some(prop => prop.autoincrement)) {
38
+ // For TPT child entities, the parent table owns the identity column, not the child table
39
+ if (props.some(prop => prop.autoincrement && (!meta.ownProps || meta.ownProps.includes(prop)))) {
36
40
  return super.nativeInsertMany(entityName, data, options, sql => {
37
41
  return `set identity_insert ${tableName} on; ${sql}; set identity_insert ${tableName} off`;
38
42
  });
@@ -41,7 +45,9 @@ export class MsSqlDriver extends AbstractSqlDriver {
41
45
  }
42
46
  createQueryBuilder(entityName, ctx, preferredConnectionType, convertCustomTypes, loggerContext, alias, em) {
43
47
  // do not compute the connectionType if EM is provided as it will be computed from it in the QB later on
44
- const connectionType = em ? preferredConnectionType : this.resolveConnectionType({ ctx, connectionType: preferredConnectionType });
48
+ const connectionType = em
49
+ ? preferredConnectionType
50
+ : this.resolveConnectionType({ ctx, connectionType: preferredConnectionType });
45
51
  const qb = new MsSqlQueryBuilder(entityName, this.metadata, this, ctx, alias, connectionType, em, loggerContext);
46
52
  if (!convertCustomTypes) {
47
53
  qb.unsetFlag(QueryFlag.CONVERT_CUSTOM_TYPES);
@@ -51,17 +57,15 @@ export class MsSqlDriver extends AbstractSqlDriver {
51
57
  appendOutputTable(entityName, data, sql) {
52
58
  const meta = this.metadata.get(entityName);
53
59
  const returningProps = meta.props
54
- .filter(prop => prop.persist !== false && prop.defaultRaw || prop.autoincrement || prop.generated)
60
+ .filter(prop => (prop.persist !== false && prop.defaultRaw) || prop.autoincrement || prop.generated)
55
61
  .filter(prop => !(prop.name in data[0]) || isRaw(data[0][prop.name]));
56
62
  const returningFields = Utils.flatten(returningProps.map(prop => prop.fieldNames));
57
- /* v8 ignore next 3 */
63
+ /* v8 ignore next */
58
64
  if (returningFields.length === 0) {
59
65
  return sql;
60
66
  }
61
67
  const tableName = this.getTableName(meta, {}, true);
62
- const selections = returningFields
63
- .map((field) => `[t].${this.platform.quoteIdentifier(field)}`)
64
- .join(',');
68
+ const selections = returningFields.map((field) => `[t].${this.platform.quoteIdentifier(field)}`).join(',');
65
69
  const position = sql.indexOf(' values ');
66
70
  const sqlBeforeValues = sql.substring(0, position);
67
71
  const sqlAfterValues = sql.substring(position + 1);
@@ -71,4 +75,8 @@ export class MsSqlDriver extends AbstractSqlDriver {
71
75
  outputSql += `drop table #out`;
72
76
  return outputSql;
73
77
  }
78
+ /** @inheritDoc */
79
+ getORMClass() {
80
+ return MsSqlMikroORM;
81
+ }
74
82
  }
@@ -1,8 +1,8 @@
1
1
  import { ExceptionConverter, type Dictionary, type DriverException } from '@mikro-orm/core';
2
2
  export declare class MsSqlExceptionConverter extends ExceptionConverter {
3
3
  /**
4
- * @link https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-511-database-engine-error?view=sql-server-ver15
5
- * @link https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractPostgreSQLDriver.php
4
+ * @see https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-511-database-engine-error?view=sql-server-ver15
5
+ * @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractPostgreSQLDriver.php
6
6
  */
7
7
  convertException(exception: Error & Dictionary): DriverException;
8
8
  }
@@ -1,13 +1,16 @@
1
1
  import { ExceptionConverter, InvalidFieldNameException, NonUniqueFieldNameException, NotNullConstraintViolationException, SyntaxErrorException, TableExistsException, TableNotFoundException, UniqueConstraintViolationException, } from '@mikro-orm/core';
2
2
  export class MsSqlExceptionConverter extends ExceptionConverter {
3
3
  /**
4
- * @link https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-511-database-engine-error?view=sql-server-ver15
5
- * @link https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractPostgreSQLDriver.php
4
+ * @see https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-511-database-engine-error?view=sql-server-ver15
5
+ * @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractPostgreSQLDriver.php
6
6
  */
7
7
  convertException(exception) {
8
8
  let errno = exception.number;
9
- /* v8 ignore next 5 */
10
- if ('errors' in exception && Array.isArray(exception.errors) && typeof exception.errors[0] === 'object' && 'message' in exception.errors[0]) {
9
+ /* v8 ignore next */
10
+ if ('errors' in exception &&
11
+ Array.isArray(exception.errors) &&
12
+ typeof exception.errors[0] === 'object' &&
13
+ 'message' in exception.errors[0]) {
11
14
  exception.message += '\n' + exception.errors.map(e => e.message).join('\n');
12
15
  errno ??= exception.errors[0].number;
13
16
  exception.lineNumber ??= exception.errors[0].lineNumber;
@@ -1,19 +1,18 @@
1
- import { MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from '@mikro-orm/core';
1
+ import { type AnyEntity, type EntityClass, type EntitySchema, MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from '@mikro-orm/core';
2
+ import type { SqlEntityManager } from '@mikro-orm/sql';
2
3
  import { MsSqlDriver } from './MsSqlDriver.js';
3
- import type { SqlEntityManager } from '@mikro-orm/knex';
4
+ export type MsSqlOptions<EM extends SqlEntityManager<MsSqlDriver> = SqlEntityManager<MsSqlDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> = Options<MsSqlDriver, EM, Entities>;
5
+ export declare function defineMsSqlConfig<EM extends SqlEntityManager<MsSqlDriver> = SqlEntityManager<MsSqlDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<MsSqlDriver, EM, Entities>): Options<MsSqlDriver, EM, Entities>;
4
6
  /**
5
7
  * @inheritDoc
6
8
  */
7
- export declare class MsSqlMikroORM<EM extends EntityManager = SqlEntityManager> extends MikroORM<MsSqlDriver, EM> {
8
- private static DRIVER;
9
+ export declare class MsSqlMikroORM<EM extends SqlEntityManager<MsSqlDriver> = SqlEntityManager<MsSqlDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> extends MikroORM<MsSqlDriver, EM, Entities> {
9
10
  /**
10
11
  * @inheritDoc
11
12
  */
12
- static init<D extends IDatabaseDriver = MsSqlDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options?: Options<D, EM>): Promise<MikroORM<D, EM>>;
13
+ static init<D extends IDatabaseDriver = MsSqlDriver, EM extends EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities>): Promise<MikroORM<D, EM, Entities>>;
13
14
  /**
14
15
  * @inheritDoc
15
16
  */
16
- static initSync<D extends IDatabaseDriver = MsSqlDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options: Options<D, EM>): MikroORM<D, EM>;
17
+ constructor(options: Options<MsSqlDriver, EM, Entities>);
17
18
  }
18
- export type MsSqlOptions = Options<MsSqlDriver>;
19
- export declare function defineMsSqlConfig(options: MsSqlOptions): Options<MsSqlDriver, SqlEntityManager<MsSqlDriver> & EntityManager<IDatabaseDriver<import("@mikro-orm/core").Connection>>>;
package/MsSqlMikroORM.js CHANGED
@@ -1,24 +1,22 @@
1
1
  import { defineConfig, MikroORM, } from '@mikro-orm/core';
2
2
  import { MsSqlDriver } from './MsSqlDriver.js';
3
+ export function defineMsSqlConfig(options) {
4
+ return defineConfig({ driver: MsSqlDriver, ...options });
5
+ }
3
6
  /**
4
7
  * @inheritDoc
5
8
  */
6
9
  export class MsSqlMikroORM extends MikroORM {
7
- static DRIVER = MsSqlDriver;
8
10
  /**
9
11
  * @inheritDoc
10
12
  */
11
13
  static async init(options) {
12
- return super.init(options);
14
+ return super.init(defineMsSqlConfig(options));
13
15
  }
14
16
  /**
15
17
  * @inheritDoc
16
18
  */
17
- static initSync(options) {
18
- return super.initSync(options);
19
+ constructor(options) {
20
+ super(defineMsSqlConfig(options));
19
21
  }
20
22
  }
21
- /* v8 ignore next 3 */
22
- export function defineMsSqlConfig(options) {
23
- return defineConfig({ driver: MsSqlDriver, ...options });
24
- }
@@ -1,12 +1,13 @@
1
- import { AbstractSqlPlatform, type EntityMetadata, type IDatabaseDriver, type EntityManager, type MikroORM, Type, type Primary, type IPrimaryKey, QueryOrder, MsSqlNativeQueryBuilder } from '@mikro-orm/knex';
1
+ import { AbstractSqlPlatform, type EntityManager, type EntityMetadata, type IDatabaseDriver, type IPrimaryKey, type MikroORM, MsSqlNativeQueryBuilder, type Primary, QueryOrder, RawQueryFragment, Type } from '@mikro-orm/sql';
2
2
  import { MsSqlSchemaHelper } from './MsSqlSchemaHelper.js';
3
3
  import { MsSqlExceptionConverter } from './MsSqlExceptionConverter.js';
4
4
  import { MsSqlSchemaGenerator } from './MsSqlSchemaGenerator.js';
5
+ import type { MsSqlDriver } from './MsSqlDriver.js';
5
6
  export declare class MsSqlPlatform extends AbstractSqlPlatform {
6
7
  protected readonly schemaHelper: MsSqlSchemaHelper;
7
8
  protected readonly exceptionConverter: MsSqlExceptionConverter;
8
9
  /** @inheritDoc */
9
- lookupExtensions(orm: MikroORM): void;
10
+ lookupExtensions(orm: MikroORM<MsSqlDriver>): void;
10
11
  /** @inheritDoc */
11
12
  init(orm: MikroORM): void;
12
13
  getRollbackToSavepointSQL(savepointName: string): string;
@@ -50,7 +51,7 @@ export declare class MsSqlPlatform extends AbstractSqlPlatform {
50
51
  length?: number;
51
52
  }): string;
52
53
  validateMetadata(meta: EntityMetadata): void;
53
- getSearchJsonPropertyKey(path: string[], type: string, aliased: boolean, value?: unknown): string;
54
+ getSearchJsonPropertyKey(path: string[], type: string, aliased: boolean, value?: unknown): string | RawQueryFragment;
54
55
  normalizePrimaryKey<T extends number | string = number | string>(data: Primary<T> | IPrimaryKey | string): T;
55
56
  usesEnumCheckConstraints(): boolean;
56
57
  supportsMultipleCascadePaths(): boolean;
@@ -61,6 +62,8 @@ export declare class MsSqlPlatform extends AbstractSqlPlatform {
61
62
  escape(value: any): string;
62
63
  getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): MsSqlSchemaGenerator;
63
64
  allowsComparingTuples(): boolean;
64
- getOrderByExpression(column: string, direction: QueryOrder): string[];
65
+ /** @internal MSSQL collation names are not quoted. */
66
+ quoteCollation(collation: string): string;
67
+ getOrderByExpression(column: string, direction: QueryOrder, collation?: string): string[];
65
68
  getDefaultClientUrl(): string;
66
69
  }
package/MsSqlPlatform.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AbstractSqlPlatform, raw, Type, Utils, ALIAS_REPLACEMENT, DoubleType, FloatType, QueryOrder, RawQueryFragment, MsSqlNativeQueryBuilder, } from '@mikro-orm/knex';
1
+ import { AbstractSqlPlatform, ALIAS_REPLACEMENT, DoubleType, FloatType, MsSqlNativeQueryBuilder, QueryOrder, raw, RawQueryFragment, Type, } from '@mikro-orm/sql';
2
2
  // @ts-expect-error no types available
3
3
  import SqlString from 'tsqlstring';
4
4
  import { MsSqlSchemaHelper } from './MsSqlSchemaHelper.js';
@@ -33,7 +33,7 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
33
33
  return true;
34
34
  }
35
35
  convertDateToJSValue(value) {
36
- /* v8 ignore next 3 */
36
+ /* v8 ignore next */
37
37
  if (typeof value === 'string') {
38
38
  return value;
39
39
  }
@@ -83,7 +83,7 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
83
83
  return super.getVarcharTypeDeclarationSQL(column);
84
84
  }
85
85
  getEnumTypeDeclarationSQL(column) {
86
- if (column.items?.every(item => Utils.isString(item))) {
86
+ if (column.items?.every(item => typeof item === 'string')) {
87
87
  return Type.getType(UnicodeStringType).getColumnType({ length: 100, ...column }, this);
88
88
  }
89
89
  /* v8 ignore next */
@@ -101,7 +101,7 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
101
101
  }
102
102
  getDefaultMappedType(type) {
103
103
  if (type.startsWith('float')) {
104
- const len = type.match(/float\((\d+)\)/)?.[1] ?? 24;
104
+ const len = /float\((\d+)\)/.exec(type)?.[1] ?? 24;
105
105
  return +len > 24 ? Type.getType(DoubleType) : Type.getType(FloatType);
106
106
  }
107
107
  const normalizedType = this.extractSimpleType(type);
@@ -130,9 +130,9 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
130
130
  }
131
131
  validateMetadata(meta) {
132
132
  for (const prop of meta.props) {
133
- if ((prop.runtimeType === 'string' || ['string', 'nvarchar'].includes(prop.type))
134
- && !['uuid'].includes(prop.type)
135
- && !prop.columnTypes[0].startsWith('varchar')) {
133
+ if ((prop.runtimeType === 'string' || ['string', 'nvarchar'].includes(prop.type)) &&
134
+ !['uuid'].includes(prop.type) &&
135
+ !prop.columnTypes[0].startsWith('varchar')) {
136
136
  prop.customType ??= new UnicodeStringType();
137
137
  prop.customType.prop = prop;
138
138
  prop.customType.platform = this;
@@ -148,15 +148,15 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
148
148
  boolean: 'bit',
149
149
  };
150
150
  const cast = (key) => raw(type in types ? `cast(${key} as ${types[type]})` : key);
151
- const quoteKey = (key) => key.match(/^[a-z]\w*$/i) ? key : `"${key}"`;
152
- /* v8 ignore next 3 */
151
+ const quoteKey = (key) => (/^[a-z]\w*$/i.exec(key) ? key : `"${key}"`);
152
+ /* v8 ignore next */
153
153
  if (path.length === 0) {
154
154
  return cast(`json_value(${root}, '$.${b.map(quoteKey).join('.')}')`);
155
155
  }
156
156
  return cast(`json_value(${root}, '$.${b.map(quoteKey).join('.')}')`);
157
157
  }
158
158
  normalizePrimaryKey(data) {
159
- /* v8 ignore next 3 */
159
+ /* v8 ignore next */
160
160
  if (data instanceof UnicodeString) {
161
161
  return data.value;
162
162
  }
@@ -189,25 +189,31 @@ export class MsSqlPlatform extends AbstractSqlPlatform {
189
189
  }
190
190
  return SqlString.escape(value);
191
191
  }
192
- /* v8 ignore next 3: kept for type inference only */
192
+ /* v8 ignore next: kept for type inference only */
193
193
  getSchemaGenerator(driver, em) {
194
194
  return new MsSqlSchemaGenerator(em ?? driver);
195
195
  }
196
196
  allowsComparingTuples() {
197
197
  return false;
198
198
  }
199
- getOrderByExpression(column, direction) {
199
+ /** @internal MSSQL collation names are not quoted. */
200
+ quoteCollation(collation) {
201
+ this.validateCollationName(collation);
202
+ return collation;
203
+ }
204
+ getOrderByExpression(column, direction, collation) {
205
+ const col = collation ? `${column} collate ${this.quoteCollation(collation)}` : column;
200
206
  switch (direction.toUpperCase()) {
201
207
  case QueryOrder.ASC_NULLS_FIRST:
202
- return [`case when ${column} is null then 0 else 1 end, ${column} asc`];
208
+ return [`case when ${column} is null then 0 else 1 end, ${col} asc`];
203
209
  case QueryOrder.ASC_NULLS_LAST:
204
- return [`case when ${column} is null then 1 else 0 end, ${column} asc`];
210
+ return [`case when ${column} is null then 1 else 0 end, ${col} asc`];
205
211
  case QueryOrder.DESC_NULLS_FIRST:
206
- return [`case when ${column} is null then 0 else 1 end, ${column} desc`];
212
+ return [`case when ${column} is null then 0 else 1 end, ${col} desc`];
207
213
  case QueryOrder.DESC_NULLS_LAST:
208
- return [`case when ${column} is null then 1 else 0 end, ${column} desc`];
214
+ return [`case when ${column} is null then 1 else 0 end, ${col} desc`];
209
215
  default:
210
- return [`${column} ${direction.toLowerCase()}`];
216
+ return [`${col} ${direction.toLowerCase()}`];
211
217
  }
212
218
  }
213
219
  getDefaultClientUrl() {
@@ -1,6 +1,6 @@
1
1
  import { type AnyEntity, type RequiredEntityData } from '@mikro-orm/core';
2
- import { type InsertQueryBuilder, QueryBuilder } from '@mikro-orm/knex';
2
+ import { type InsertQueryBuilder, QueryBuilder } from '@mikro-orm/sql';
3
3
  export declare class MsSqlQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never> extends QueryBuilder<Entity, RootAlias, Hint, Context> {
4
- insert(data: RequiredEntityData<Entity> | RequiredEntityData<Entity>[]): InsertQueryBuilder<Entity>;
4
+ insert(data: RequiredEntityData<Entity> | RequiredEntityData<Entity>[]): InsertQueryBuilder<Entity, RootAlias, Context>;
5
5
  private checkIdentityInsert;
6
6
  }
@@ -1,10 +1,10 @@
1
1
  import { QueryFlag, Utils } from '@mikro-orm/core';
2
- import { QueryBuilder } from '@mikro-orm/knex';
2
+ import { QueryBuilder } from '@mikro-orm/sql';
3
3
  export class MsSqlQueryBuilder extends QueryBuilder {
4
4
  insert(data) {
5
5
  this.checkIdentityInsert(data);
6
6
  if (!this.flags.has(QueryFlag.IDENTITY_INSERT) && this.metadata.has(this.mainAlias.entityName)) {
7
- const meta = this.metadata.find(this.mainAlias.entityName);
7
+ const meta = this.mainAlias.meta;
8
8
  if (meta.hasTriggers) {
9
9
  this.setFlag(QueryFlag.OUTPUT_TABLE);
10
10
  }
@@ -12,11 +12,8 @@ export class MsSqlQueryBuilder extends QueryBuilder {
12
12
  return super.insert(data);
13
13
  }
14
14
  checkIdentityInsert(data) {
15
- const meta = this.metadata.find(this.mainAlias.entityName);
16
- if (!meta) {
17
- return;
18
- }
19
- const dataKeys = Utils.unique(Utils.asArray(data).flatMap(Object.keys));
15
+ const meta = this.mainAlias.meta;
16
+ const dataKeys = Utils.unique(Utils.asArray(data).flatMap(d => Utils.keys(d)));
20
17
  const hasAutoincrement = dataKeys.some(x => meta.properties[x]?.autoincrement);
21
18
  if (hasAutoincrement) {
22
19
  this.setFlag(QueryFlag.IDENTITY_INSERT);
@@ -1,6 +1,7 @@
1
- import { type ClearDatabaseOptions, type DropSchemaOptions, type MikroORM, SchemaGenerator } from '@mikro-orm/knex';
1
+ import { type ClearDatabaseOptions, type DropSchemaOptions, type MikroORM, SchemaGenerator } from '@mikro-orm/sql';
2
+ import type { MsSqlDriver } from './MsSqlDriver.js';
2
3
  export declare class MsSqlSchemaGenerator extends SchemaGenerator {
3
- static register(orm: MikroORM): void;
4
- clearDatabase(options?: ClearDatabaseOptions): Promise<void>;
4
+ static register(orm: MikroORM<MsSqlDriver>): void;
5
+ clear(options?: ClearDatabaseOptions): Promise<void>;
5
6
  getDropSchemaSQL(options?: Omit<DropSchemaOptions, 'dropDb'>): Promise<string>;
6
7
  }
@@ -1,17 +1,17 @@
1
- import { SchemaGenerator } from '@mikro-orm/knex';
1
+ import { SchemaGenerator } from '@mikro-orm/sql';
2
2
  export class MsSqlSchemaGenerator extends SchemaGenerator {
3
3
  static register(orm) {
4
4
  orm.config.registerExtension('@mikro-orm/schema-generator', () => new MsSqlSchemaGenerator(orm.em));
5
5
  }
6
- async clearDatabase(options) {
6
+ async clear(options) {
7
7
  // truncate by default, so no value is considered as true
8
- /* v8 ignore next 3 */
8
+ /* v8 ignore next */
9
9
  if (options?.truncate === false) {
10
- return super.clearDatabase(options);
10
+ return super.clear(options);
11
11
  }
12
12
  // https://stackoverflow.com/questions/253849/cannot-truncate-table-because-it-is-being-referenced-by-a-foreign-key-constraint
13
13
  for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
14
- const res = await this.driver.nativeDelete(meta.className, {}, options);
14
+ const res = await this.driver.nativeDelete(meta.class, {}, options);
15
15
  if (meta.getPrimaryProps().some(pk => pk.autoincrement)) {
16
16
  const tableName = this.driver.getTableName(meta, { schema: options?.schema }, false);
17
17
  await this.execute(`dbcc checkident ('${tableName}', reseed, ${res.affectedRows > 0 ? 0 : 1})`, {
@@ -1,4 +1,4 @@
1
- import { type AbstractSqlConnection, type CheckDef, type Column, type DatabaseSchema, type DatabaseTable, type Dictionary, type ForeignKey, type IndexDef, SchemaHelper, type Table, type TableDifference, type Type } from '@mikro-orm/knex';
1
+ import { type AbstractSqlConnection, type CheckDef, type Column, type DatabaseSchema, type DatabaseTable, type Dictionary, type ForeignKey, type IndexDef, SchemaHelper, type Table, type TableDifference, type Type } from '@mikro-orm/sql';
2
2
  export declare class MsSqlSchemaHelper extends SchemaHelper {
3
3
  static readonly DEFAULT_VALUES: {
4
4
  true: string[];
@@ -10,6 +10,8 @@ export declare class MsSqlSchemaHelper extends SchemaHelper {
10
10
  enableForeignKeysSQL(): string;
11
11
  getDatabaseExistsSQL(name: string): string;
12
12
  getListTablesSQL(): string;
13
+ getListViewsSQL(): string;
14
+ loadViews(schema: DatabaseSchema, connection: AbstractSqlConnection): Promise<void>;
13
15
  getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
14
16
  normalizeDefaultValue(defaultValue: string, length: number, defaultValues?: Dictionary<string[]>, stripQuotes?: boolean): string | number;
15
17
  getAllColumns(connection: AbstractSqlConnection, tablesBySchemas: Map<string | undefined, Table[]>): Promise<Dictionary<Column[]>>;
@@ -32,9 +34,18 @@ export declare class MsSqlSchemaHelper extends SchemaHelper {
32
34
  createTableColumn(column: Column, table: DatabaseTable, changedProperties?: Set<string>): string | undefined;
33
35
  alterTableColumn(column: Column, table: DatabaseTable, changedProperties: Set<string>): string[];
34
36
  getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
37
+ /**
38
+ * Build the column list for a MSSQL index.
39
+ */
40
+ protected getIndexColumns(index: IndexDef): string;
41
+ /**
42
+ * Get MSSQL-specific index WITH options like fill factor.
43
+ */
44
+ private getMsSqlIndexSuffix;
35
45
  createIndex(index: IndexDef, table: DatabaseTable, createPrimary?: boolean): string;
36
46
  dropForeignKey(tableName: string, constraintName: string): string;
37
47
  dropTableIfExists(name: string, schema?: string): string;
48
+ dropViewIfExists(name: string, schema?: string): string;
38
49
  getAddColumnsSQL(table: DatabaseTable, columns: Column[]): string[];
39
50
  appendComments(table: DatabaseTable): string[];
40
51
  inferLengthFromColumnType(type: string): number | undefined;