@mikro-orm/knex 6.2.10-dev.1 → 6.2.10-dev.100

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,7 +1,6 @@
1
- /// <reference types="node" />
2
1
  import { inspect } from 'util';
3
2
  import type { Knex } from 'knex';
4
- import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityMetadata, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryOrderMap, type QueryResult, type RequiredEntityData } from '@mikro-orm/core';
3
+ import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryOrderMap, type QueryResult, RawQueryFragment, type RequiredEntityData, type ExpandProperty } from '@mikro-orm/core';
5
4
  import { JoinType, QueryType } from './enums';
6
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
7
6
  import { type Alias, QueryBuilderHelper } from './QueryBuilderHelper';
@@ -12,6 +11,26 @@ export interface ExecuteOptions {
12
11
  mapResults?: boolean;
13
12
  mergeResults?: boolean;
14
13
  }
14
+ type AnyString = string & {};
15
+ type Compute<T> = {
16
+ [K in keyof T]: T[K];
17
+ } & {};
18
+ type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False;
19
+ type GetAlias<T extends string> = T extends `${infer A}.${string}` ? A : never;
20
+ type GetPropName<T extends string> = T extends `${string}.${infer P}` ? P : T;
21
+ type AppendToHint<Parent extends string, Child extends string> = `${Parent}.${Child}`;
22
+ type AddToContext<Type extends object, Context, Field extends string, Alias extends string, Select extends boolean> = {
23
+ [K in Alias]: [GetPath<Context, Field>, K, ExpandProperty<Type[GetPropName<Field> & keyof Type]>, Select];
24
+ };
25
+ type GetPath<Context, Field extends string> = GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? GetPropName<Field> : Alias extends keyof Context ? Context[Alias] extends [infer Path, ...any[]] ? AppendToHint<Path & string, GetPropName<Field>> : GetPropName<Field> : GetPropName<Field> : GetPropName<Field>;
26
+ type GetType<Type extends object, Context, Field extends string> = GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? Type : Alias extends keyof Context ? Context[Alias] extends [string, string, infer PropType] ? PropType & object : Type : Type : Type;
27
+ type AddToHint<RootAlias, Context, Field extends string, Select extends boolean = false> = Select extends true ? GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? GetPropName<Field> : Alias extends RootAlias ? GetPropName<Field> : Alias extends keyof Context ? Context[Alias] extends [infer Path, ...any[]] ? AppendToHint<Path & string, GetPropName<Field>> : GetPropName<Field> : GetPropName<Field> : GetPropName<Field> : never;
28
+ export type ModifyHint<RootAlias, Context, Hint extends string, Field extends string, Select extends boolean = false> = Hint | AddToHint<RootAlias, Context, Field, Select>;
29
+ export type ModifyContext<Entity extends object, Context, Field extends string, Alias extends string, Select extends boolean = false> = Compute<IsNever<Context> extends true ? AddToContext<GetType<Entity, object, Field>, object, Field, Alias, Select> : Context & AddToContext<GetType<Entity, Context, Field>, Context, Field, Alias, Select>>;
30
+ type EntityRelations<T> = EntityKey<T, true>;
31
+ type AddAliasesFromContext<Context> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, infer Type, any] ? `${Alias & string}.${EntityRelations<Type & {}>}` : never : never : never;
32
+ export type QBField<Entity, RootAlias extends string, Context> = (EntityRelations<Entity> | `${RootAlias}.${EntityRelations<Entity>}` | AddAliasesFromContext<Context>) & {} | AnyString;
33
+ export type QBField2<Entity, RootAlias extends string, Context> = (EntityKey<Entity> | `${RootAlias}.${EntityKey<Entity>}` | AddAliasesFromContext<Context>) & {} | AnyString;
15
34
  /**
16
35
  * SQL query builder with fluent interface.
17
36
  *
@@ -31,26 +50,26 @@ export interface ExecuteOptions {
31
50
  * const publisher = await qb.getSingleResult();
32
51
  * ```
33
52
  */
34
- export declare class QueryBuilder<T extends object = AnyEntity> {
53
+ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never> {
35
54
  protected readonly metadata: MetadataStorage;
36
55
  protected readonly driver: AbstractSqlDriver;
37
- protected readonly context?: Knex.Transaction<any, any[]> | undefined;
56
+ protected readonly context?: Knex.Transaction | undefined;
38
57
  protected connectionType?: ConnectionType | undefined;
39
- protected em?: SqlEntityManager<AbstractSqlDriver<import("..").AbstractSqlConnection, AbstractSqlPlatform>> | undefined;
58
+ protected em?: SqlEntityManager | undefined;
40
59
  protected loggerContext?: (LoggingOptions & Dictionary) | undefined;
41
- get mainAlias(): Alias<T>;
60
+ get mainAlias(): Alias<Entity>;
42
61
  get alias(): string;
43
62
  get helper(): QueryBuilderHelper;
44
63
  /** @internal */
45
64
  type?: QueryType;
46
65
  /** @internal */
47
- _fields?: Field<T>[];
66
+ _fields?: Field<Entity>[];
48
67
  /** @internal */
49
- _populate: PopulateOptions<T>[];
68
+ _populate: PopulateOptions<Entity>[];
50
69
  /** @internal */
51
- _populateWhere?: ObjectQuery<T> | PopulateHint | `${PopulateHint}`;
70
+ _populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
52
71
  /** @internal */
53
- __populateWhere?: ObjectQuery<T> | PopulateHint | `${PopulateHint}`;
72
+ __populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
54
73
  /** @internal */
55
74
  _populateMap: Dictionary<string>;
56
75
  /** @internal */
@@ -63,15 +82,15 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
63
82
  protected _schema?: string;
64
83
  protected _cond: Dictionary;
65
84
  protected _data: Dictionary;
66
- protected _orderBy: QueryOrderMap<T>[];
67
- protected _groupBy: Field<T>[];
85
+ protected _orderBy: QueryOrderMap<Entity>[];
86
+ protected _groupBy: Field<Entity>[];
68
87
  protected _having: Dictionary;
69
- protected _returning?: Field<T>[];
88
+ protected _returning?: Field<Entity>[];
70
89
  protected _onConflict?: {
71
- fields: string[];
90
+ fields: string[] | RawQueryFragment;
72
91
  ignore?: boolean;
73
- merge?: EntityData<T> | Field<T>[];
74
- where?: QBFilterQuery<T>;
92
+ merge?: EntityData<Entity> | Field<Entity>[];
93
+ where?: QBFilterQuery<Entity>;
75
94
  }[];
76
95
  protected _limit?: number;
77
96
  protected _offset?: number;
@@ -85,62 +104,62 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
85
104
  protected lockMode?: LockMode;
86
105
  protected lockTables?: string[];
87
106
  protected subQueries: Dictionary<string>;
88
- protected _mainAlias?: Alias<T>;
107
+ protected _mainAlias?: Alias<Entity>;
89
108
  protected _aliases: Dictionary<Alias<any>>;
90
109
  protected _helper?: QueryBuilderHelper;
91
110
  protected _query?: {
92
111
  sql?: string;
93
112
  _sql?: Knex.Sql;
94
113
  params?: readonly unknown[];
95
- qb: Knex.QueryBuilder<T>;
114
+ qb: Knex.QueryBuilder<Entity>;
96
115
  };
97
116
  protected readonly platform: AbstractSqlPlatform;
98
117
  protected readonly knex: Knex;
99
118
  /**
100
119
  * @internal
101
120
  */
102
- constructor(entityName: EntityName<T> | QueryBuilder<T>, metadata: MetadataStorage, driver: AbstractSqlDriver, context?: Knex.Transaction<any, any[]> | undefined, alias?: string, connectionType?: ConnectionType | undefined, em?: SqlEntityManager<AbstractSqlDriver<import("..").AbstractSqlConnection, AbstractSqlPlatform>> | undefined, loggerContext?: (LoggingOptions & Dictionary) | undefined);
103
- select(fields: Field<T> | Field<T>[], distinct?: boolean): SelectQueryBuilder<T>;
104
- addSelect(fields: Field<T> | Field<T>[]): SelectQueryBuilder<T>;
105
- distinct(): SelectQueryBuilder<T>;
121
+ constructor(entityName: EntityName<Entity> | QueryBuilder<Entity, any, any>, metadata: MetadataStorage, driver: AbstractSqlDriver, context?: Knex.Transaction | undefined, alias?: string, connectionType?: ConnectionType | undefined, em?: SqlEntityManager | undefined, loggerContext?: (LoggingOptions & Dictionary) | undefined);
122
+ select(fields: Field<Entity> | Field<Entity>[], distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
123
+ addSelect(fields: Field<Entity> | Field<Entity>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
124
+ distinct(): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
106
125
  /** postgres only */
107
- distinctOn(fields: string | string[]): SelectQueryBuilder<T>;
108
- insert(data: RequiredEntityData<T> | RequiredEntityData<T>[]): InsertQueryBuilder<T>;
109
- update(data: EntityData<T>): UpdateQueryBuilder<T>;
110
- delete(cond?: QBFilterQuery): DeleteQueryBuilder<T>;
111
- truncate(): TruncateQueryBuilder<T>;
112
- count(field?: string | string[], distinct?: boolean): CountQueryBuilder<T>;
113
- join(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string, schema?: string): this;
114
- innerJoin(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
115
- innerJoinLateral(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
116
- leftJoin(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
117
- leftJoinLateral(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
118
- joinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string, fields?: string[], schema?: string): SelectQueryBuilder<T>;
119
- leftJoinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
120
- leftJoinLateralAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
121
- innerJoinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
122
- innerJoinLateralAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
123
- protected getFieldsForJoinedLoad(prop: EntityProperty<T>, alias: string, explicitFields?: string[]): Field<T>[];
126
+ distinctOn(fields: string | string[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
127
+ insert(data: RequiredEntityData<Entity> | RequiredEntityData<Entity>[]): InsertQueryBuilder<Entity>;
128
+ update(data: EntityData<Entity>): UpdateQueryBuilder<Entity>;
129
+ delete(cond?: QBFilterQuery): DeleteQueryBuilder<Entity>;
130
+ truncate(): TruncateQueryBuilder<Entity>;
131
+ count(field?: string | string[], distinct?: boolean): CountQueryBuilder<Entity>;
132
+ join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | Knex.QueryBuilder | QueryBuilder<any>, alias: Alias, cond?: QBFilterQuery, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>>;
133
+ innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | Knex.QueryBuilder | QueryBuilder<any>, alias: Alias, cond?: QBFilterQuery, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>>;
134
+ innerJoinLateral(field: Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
135
+ leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | Knex.QueryBuilder | QueryBuilder<any>, alias: Alias, cond?: QBFilterQuery, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>>;
136
+ leftJoinLateral(field: Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
137
+ joinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | [field: Field, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: Alias, cond?: QBFilterQuery, type?: JoinType, path?: string, fields?: string[], schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>>;
138
+ leftJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | [field: Field, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: Alias, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>>;
139
+ leftJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: [field: Field, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: Alias, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>>;
140
+ innerJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field | [field: Field, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: Alias, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>>;
141
+ innerJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: [field: Field, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: Alias, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>>;
142
+ protected getFieldsForJoinedLoad(prop: EntityProperty<Entity>, alias: string, explicitFields?: string[]): Field<Entity>[];
124
143
  withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
125
- where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
144
+ where(cond: QBFilterQuery<Entity>, operator?: keyof typeof GroupOperator): this;
126
145
  where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;
127
- andWhere(cond: QBFilterQuery<T>): this;
146
+ andWhere(cond: QBFilterQuery<Entity>): this;
128
147
  andWhere(cond: string, params?: any[]): this;
129
- orWhere(cond: QBFilterQuery<T>): this;
148
+ orWhere(cond: QBFilterQuery<Entity>): this;
130
149
  orWhere(cond: string, params?: any[]): this;
131
- orderBy(orderBy: QBQueryOrderMap<T> | QBQueryOrderMap<T>[]): SelectQueryBuilder<T>;
132
- groupBy(fields: (string | keyof T) | readonly (string | keyof T)[]): SelectQueryBuilder<T>;
133
- having(cond?: QBFilterQuery | string, params?: any[]): SelectQueryBuilder<T>;
134
- onConflict(fields?: Field<T> | Field<T>[]): InsertQueryBuilder<T>;
150
+ orderBy(orderBy: QBQueryOrderMap<Entity> | QBQueryOrderMap<Entity>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
151
+ groupBy(fields: (string | keyof Entity) | readonly (string | keyof Entity)[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
152
+ having(cond?: QBFilterQuery | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
153
+ onConflict(fields?: Field<Entity> | Field<Entity>[]): InsertQueryBuilder<Entity>;
135
154
  ignore(): this;
136
- merge(data?: EntityData<T> | Field<T>[]): this;
137
- returning(fields?: Field<T> | Field<T>[]): this;
155
+ merge(data?: EntityData<Entity> | Field<Entity>[]): this;
156
+ returning(fields?: Field<Entity> | Field<Entity>[]): this;
138
157
  /**
139
158
  * @internal
140
159
  */
141
- populate(populate: PopulateOptions<T>[], populateWhere?: ObjectQuery<T> | PopulateHint | `${PopulateHint}`): this;
142
- limit(limit?: number, offset?: number): SelectQueryBuilder<T>;
143
- offset(offset?: number): SelectQueryBuilder<T>;
160
+ populate(populate: PopulateOptions<Entity>[], populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`): this;
161
+ limit(limit?: number, offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
162
+ offset(offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
144
163
  withSchema(schema?: string): this;
145
164
  setLockMode(mode?: LockMode, tables?: string[]): this;
146
165
  setFlushMode(flushMode?: FlushMode): this;
@@ -166,8 +185,8 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
166
185
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
167
186
  * Allows setting a main string alias of the selection data.
168
187
  */
169
- from<T extends AnyEntity<T> = AnyEntity>(target: QueryBuilder<T>, aliasName?: string): SelectQueryBuilder<T>;
170
- from<T extends AnyEntity<T> = AnyEntity>(target: EntityName<T>): SelectQueryBuilder<T>;
188
+ from<Entity extends AnyEntity<Entity> = AnyEntity>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
189
+ from<Entity extends AnyEntity<Entity> = AnyEntity>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
171
190
  getKnexQuery(processVirtualEntity?: boolean): Knex.QueryBuilder;
172
191
  /**
173
192
  * @internal
@@ -214,15 +233,15 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
214
233
  /**
215
234
  * Alias for `qb.getResultList()`
216
235
  */
217
- getResult(): Promise<T[]>;
236
+ getResult(): Promise<Loaded<Entity, Hint>[]>;
218
237
  /**
219
238
  * Executes the query, returning array of results
220
239
  */
221
- getResultList(limit?: number): Promise<T[]>;
240
+ getResultList(limit?: number): Promise<Loaded<Entity, Hint>[]>;
222
241
  /**
223
242
  * Executes the query, returning the first result or null
224
243
  */
225
- getSingleResult(): Promise<T | null>;
244
+ getSingleResult(): Promise<Entity | null>;
226
245
  /**
227
246
  * Executes count query (without offset and limit), returning total count of results
228
247
  */
@@ -230,17 +249,17 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
230
249
  /**
231
250
  * Executes the query, returning both array of results and total count query (without offset and limit).
232
251
  */
233
- getResultAndCount(): Promise<[T[], number]>;
252
+ getResultAndCount(): Promise<[Entity[], number]>;
234
253
  /**
235
254
  * Provides promise-like interface so we can await the QB instance.
236
255
  */
237
- then<TResult1 = any, TResult2 = never>(onfulfilled?: ((value: any) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<T[] | number | QueryResult<T>>;
256
+ then<TResult1 = any, TResult2 = never>(onfulfilled?: ((value: any) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<Loaded<Entity, Hint>[] | number | QueryResult<Entity>>;
238
257
  /**
239
258
  * Returns knex instance with sub-query aliased with given alias.
240
259
  * You can provide `EntityName.propName` as alias, then the field name will be used based on the metadata
241
260
  */
242
261
  as(alias: string): Knex.QueryBuilder;
243
- clone(reset?: boolean | string[]): QueryBuilder<T>;
262
+ clone(reset?: boolean | string[]): QueryBuilder<Entity>;
244
263
  getKnex(processVirtualEntity?: boolean): Knex.QueryBuilder;
245
264
  /**
246
265
  * Sets logger context for this query builder.
@@ -272,31 +291,31 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
272
291
  /** @ignore */
273
292
  [inspect.custom](depth?: number): string;
274
293
  }
275
- export interface RunQueryBuilder<T extends object> extends Omit<QueryBuilder<T>, 'getResult' | 'getSingleResult' | 'getResultList' | 'where'> {
276
- where(cond: QBFilterQuery<T> | string, params?: keyof typeof GroupOperator | any[], operator?: keyof typeof GroupOperator): this;
277
- execute<U = QueryResult<T>>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<U>;
278
- then<TResult1 = QueryResult<T>, TResult2 = never>(onfulfilled?: ((value: QueryResult<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<QueryResult<T>>;
294
+ export interface RunQueryBuilder<Entity extends object> extends Omit<QueryBuilder<Entity, any, any>, 'getResult' | 'getSingleResult' | 'getResultList' | 'where'> {
295
+ where(cond: QBFilterQuery<Entity> | string, params?: keyof typeof GroupOperator | any[], operator?: keyof typeof GroupOperator): this;
296
+ execute<Result = QueryResult<Entity>>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
297
+ then<TResult1 = QueryResult<Entity>, TResult2 = never>(onfulfilled?: ((value: QueryResult<Entity>) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<QueryResult<Entity>>;
279
298
  }
280
- export interface SelectQueryBuilder<T extends object> extends QueryBuilder<T> {
281
- execute<U = T[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<U>;
282
- execute<U = T[]>(method: 'all', mapResults?: boolean): Promise<U>;
283
- execute<U = T>(method: 'get', mapResults?: boolean): Promise<U>;
284
- execute<U = QueryResult<T>>(method: 'run', mapResults?: boolean): Promise<U>;
285
- then<TResult1 = T[], TResult2 = never>(onfulfilled?: ((value: T[]) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<T[]>;
299
+ export interface SelectQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never> extends QueryBuilder<Entity, RootAlias, Hint, Context> {
300
+ execute<Result = Entity[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
301
+ execute<Result = Entity[]>(method: 'all', mapResults?: boolean): Promise<Result>;
302
+ execute<Result = Entity>(method: 'get', mapResults?: boolean): Promise<Result>;
303
+ execute<Result = QueryResult<Entity>>(method: 'run', mapResults?: boolean): Promise<Result>;
304
+ then<TResult1 = Entity[], TResult2 = never>(onfulfilled?: ((value: Loaded<Entity, Hint>[]) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<Loaded<Entity, Hint>[]>;
286
305
  }
287
- export interface CountQueryBuilder<T extends object> extends QueryBuilder<T> {
288
- execute<U = {
306
+ export interface CountQueryBuilder<Entity extends object> extends QueryBuilder<Entity, any, any> {
307
+ execute<Result = {
289
308
  count: number;
290
- }[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<U>;
291
- execute<U = {
309
+ }[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
310
+ execute<Result = {
292
311
  count: number;
293
- }[]>(method: 'all', mapResults?: boolean): Promise<U>;
294
- execute<U = {
312
+ }[]>(method: 'all', mapResults?: boolean): Promise<Result>;
313
+ execute<Result = {
295
314
  count: number;
296
- }>(method: 'get', mapResults?: boolean): Promise<U>;
297
- execute<U = QueryResult<{
315
+ }>(method: 'get', mapResults?: boolean): Promise<Result>;
316
+ execute<Result = QueryResult<{
298
317
  count: number;
299
- }>>(method: 'run', mapResults?: boolean): Promise<U>;
318
+ }>>(method: 'run', mapResults?: boolean): Promise<Result>;
300
319
  then<TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<number>;
301
320
  }
302
321
  export interface InsertQueryBuilder<T extends object> extends RunQueryBuilder<T> {
@@ -307,3 +326,4 @@ export interface DeleteQueryBuilder<T extends object> extends RunQueryBuilder<T>
307
326
  }
308
327
  export interface TruncateQueryBuilder<T extends object> extends RunQueryBuilder<T> {
309
328
  }
329
+ export {};
@@ -348,11 +348,13 @@ class QueryBuilder {
348
348
  this.ensureNotFinalized();
349
349
  this._onConflict ??= [];
350
350
  this._onConflict.push({
351
- fields: core_1.Utils.asArray(fields).flatMap(f => {
352
- const key = f.toString();
353
- /* istanbul ignore next */
354
- return meta.properties[key]?.fieldNames ?? [key];
355
- }),
351
+ fields: core_1.Utils.isRawSql(fields)
352
+ ? fields
353
+ : core_1.Utils.asArray(fields).flatMap(f => {
354
+ const key = f.toString();
355
+ /* istanbul ignore next */
356
+ return meta.properties[key]?.fieldNames ?? [key];
357
+ }),
356
358
  });
357
359
  return this;
358
360
  }
@@ -1222,7 +1224,7 @@ class QueryBuilder {
1222
1224
  const prop = this.helper.getProperty(f, a);
1223
1225
  const type = this.platform.castColumn(prop);
1224
1226
  const fieldName = this.helper.mapper(field, this.type, undefined, null);
1225
- if (!prop?.persist && !prop?.formula && !pks.includes(fieldName)) {
1227
+ if (!prop?.persist && !prop?.formula && !prop?.hasConvertToJSValueSQL && !pks.includes(fieldName)) {
1226
1228
  addToSelect.push(fieldName);
1227
1229
  }
1228
1230
  const key = (0, core_1.raw)(`min(${this.knex.ref(fieldName)}${type})`);
@@ -1245,8 +1247,10 @@ class QueryBuilder {
1245
1247
  }
1246
1248
  return false;
1247
1249
  });
1250
+ /* istanbul ignore next */
1248
1251
  if (field instanceof core_1.RawQueryFragment) {
1249
- knexQuery.select(this.platform.formatQuery(field.sql, field.params));
1252
+ const sql = this.platform.formatQuery(field.sql, field.params);
1253
+ knexQuery.select(this.knex.raw(sql));
1250
1254
  }
1251
1255
  else if (field) {
1252
1256
  knexQuery.select(field);
@@ -1,5 +1,5 @@
1
1
  import type { Knex } from 'knex';
2
- import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery } from '@mikro-orm/core';
2
+ import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, RawQueryFragment } from '@mikro-orm/core';
3
3
  import { JoinType, QueryType } from './enums';
4
4
  import type { Field, JoinOptions } from '../typings';
5
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
@@ -34,7 +34,7 @@ export declare class QueryBuilderHelper {
34
34
  isSimpleRegExp(re: any): re is RegExp;
35
35
  getRegExpParam(re: RegExp): string;
36
36
  appendOnConflictClause<T>(type: QueryType, onConflict: {
37
- fields: string[];
37
+ fields: string[] | RawQueryFragment;
38
38
  ignore?: boolean;
39
39
  merge?: EntityData<T> | Field<T>[];
40
40
  where?: QBFilterQuery<T>;
@@ -67,7 +67,8 @@ class QueryBuilderHelper {
67
67
  }
68
68
  const rawField = core_1.RawQueryFragment.getKnownFragment(field);
69
69
  if (rawField) {
70
- return this.knex.raw(rawField.sql, rawField.params);
70
+ // sometimes knex is confusing the binding positions, we need to interpolate early
71
+ return this.knex.raw(this.platform.formatQuery(rawField.sql, rawField.params));
71
72
  }
72
73
  const [a, f] = this.splitField(field);
73
74
  const prop = this.getProperty(f, a);
@@ -194,7 +195,8 @@ class QueryBuilderHelper {
194
195
  join.primaryKeys.forEach((primaryKey, idx) => {
195
196
  const right = `${join.alias}.${join.joinColumns[idx]}`;
196
197
  if (join.prop.formula) {
197
- const left = join.prop.formula(join.ownerAlias);
198
+ const alias = this.platform.quoteIdentifier(join.ownerAlias);
199
+ const left = join.prop.formula(alias);
198
200
  conditions.push(`${left} = ${this.knex.ref(right)}`);
199
201
  return;
200
202
  }
@@ -352,7 +354,16 @@ class QueryBuilderHelper {
352
354
  }
353
355
  appendOnConflictClause(type, onConflict, qb) {
354
356
  onConflict.forEach(item => {
355
- const sub = item.fields.length > 0 ? qb.onConflict(item.fields) : qb.onConflict();
357
+ let sub;
358
+ if (core_1.Utils.isRawSql(item.fields)) {
359
+ sub = qb.onConflict(this.knex.raw(item.fields.sql, item.fields.params));
360
+ }
361
+ else if (item.fields.length > 0) {
362
+ sub = qb.onConflict(item.fields);
363
+ }
364
+ else {
365
+ sub = qb.onConflict();
366
+ }
356
367
  core_1.Utils.runIfNotEmpty(() => sub.ignore(), item.ignore);
357
368
  core_1.Utils.runIfNotEmpty(() => {
358
369
  let mergeParam = item.merge;
@@ -442,6 +453,9 @@ class QueryBuilderHelper {
442
453
  const tmp = value[op].length === 1 && core_1.Utils.isPlainObject(value[op][0]) ? fields.map(f => value[op][0][f]) : value[op];
443
454
  value[op] = this.knex.raw(`(${fields.map(() => '?').join(', ')})`, tmp);
444
455
  }
456
+ if (value[op] instanceof core_1.RawQueryFragment) {
457
+ value[op] = this.knex.raw(value[op].sql, value[op].params);
458
+ }
445
459
  if (this.subQueries[key]) {
446
460
  return void qb[m](this.knex.raw(`(${this.subQueries[key]})`), replacement, value[op]);
447
461
  }
@@ -1,4 +1,4 @@
1
- import { type Configuration, type Dictionary, type EntityMetadata, type EntityProperty, type NamingStrategy } from '@mikro-orm/core';
1
+ import { type Configuration, type DeferMode, type Dictionary, type EntityMetadata, type EntityProperty, type NamingStrategy } from '@mikro-orm/core';
2
2
  import type { SchemaHelper } from './SchemaHelper';
3
3
  import type { CheckDef, Column, ForeignKey, IndexDef } from '../typings';
4
4
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
@@ -25,7 +25,7 @@ export declare class DatabaseTable {
25
25
  removeColumn(name: string): void;
26
26
  getIndexes(): IndexDef[];
27
27
  getChecks(): CheckDef[];
28
- init(cols: Column[], indexes: IndexDef[] | undefined, checks: CheckDef<unknown>[] | undefined, pks: string[], fks?: Dictionary<ForeignKey>, enums?: Dictionary<string[]>): void;
28
+ init(cols: Column[], indexes: IndexDef[] | undefined, checks: CheckDef[] | undefined, pks: string[], fks?: Dictionary<ForeignKey>, enums?: Dictionary<string[]>): void;
29
29
  addColumn(column: Column): void;
30
30
  addColumnFromProperty(prop: EntityProperty, meta: EntityMetadata, config: Configuration): void;
31
31
  private getIndexName;
@@ -58,6 +58,7 @@ export declare class DatabaseTable {
58
58
  name?: string;
59
59
  type?: string;
60
60
  expression?: string;
61
+ deferMode?: DeferMode;
61
62
  options?: Dictionary;
62
63
  }, type: 'index' | 'unique' | 'primary'): void;
63
64
  addCheck(check: CheckDef): void;
@@ -70,17 +70,11 @@ class DatabaseTable {
70
70
  prop.length = undefined;
71
71
  }
72
72
  }
73
- if (mappedType instanceof core_1.DateTimeType || mappedType instanceof core_1.IntervalType) {
74
- const match = prop.columnTypes[idx].match(/\w+\((\d+)\)/);
75
- if (match) {
76
- prop.length ??= +match[1];
77
- }
78
- else {
79
- prop.length ??= this.platform.getDefaultDateTimeLength();
80
- }
81
- }
82
73
  if (prop.length == null && prop.columnTypes[idx]) {
83
74
  prop.length = this.platform.getSchemaHelper().inferLengthFromColumnType(prop.columnTypes[idx]);
75
+ if (typeof mappedType.getDefaultLength !== 'undefined') {
76
+ prop.length ??= mappedType.getDefaultLength(this.platform);
77
+ }
84
78
  }
85
79
  const primary = !meta.compositePK && !!prop.primary && prop.kind === core_1.ReferenceKind.SCALAR && this.platform.isNumericColumn(mappedType);
86
80
  this.columns[field] = {
@@ -171,7 +165,7 @@ class DatabaseTable {
171
165
  getEntityDeclaration(namingStrategy, schemaHelper, scalarPropertiesForRelations) {
172
166
  const { fksOnColumnProps, fksOnStandaloneProps, columnFks, fkIndexes, nullableForeignKeys, skippedColumnNames, } = this.foreignKeysToProps(namingStrategy, scalarPropertiesForRelations);
173
167
  const name = namingStrategy.getEntityName(this.name, this.schema);
174
- const schema = new core_1.EntitySchema({ name, collection: this.name, schema: this.schema });
168
+ const schema = new core_1.EntitySchema({ name, collection: this.name, schema: this.schema, comment: this.comment });
175
169
  const compositeFkIndexes = {};
176
170
  const compositeFkUniques = {};
177
171
  const potentiallyUnmappedIndexes = this.indexes.filter(index => !index.primary // Skip primary index. Whether it's in use by scalar column or FK, it's already mapped.
@@ -505,6 +499,7 @@ class DatabaseTable {
505
499
  columnOptions.length = column.length;
506
500
  columnOptions.precision = column.precision;
507
501
  columnOptions.scale = column.scale;
502
+ columnOptions.comment = column.comment;
508
503
  columnOptions.enum = !!column.enumItems?.length;
509
504
  columnOptions.items = column.enumItems;
510
505
  }
@@ -542,7 +537,10 @@ class DatabaseTable {
542
537
  }
543
538
  return {
544
539
  name: prop,
545
- type: fk ? runtimeType : (core_1.Utils.entries(core_1.t).find(([k, v]) => Object.getPrototypeOf(column.mappedType) === v.prototype)?.[0] ?? runtimeType),
540
+ type: fk ? runtimeType : (core_1.Utils.keys(core_1.t).find(k => {
541
+ const typeInCoreMap = this.platform.getMappedType(k);
542
+ return (typeInCoreMap !== core_1.Type.getType(core_1.UnknownType) || k === 'unknown') && typeInCoreMap === column.mappedType;
543
+ }) ?? runtimeType),
546
544
  runtimeType,
547
545
  kind,
548
546
  generated: column.generated,
@@ -558,6 +556,7 @@ class DatabaseTable {
558
556
  length: column.length,
559
557
  precision: column.precision,
560
558
  scale: column.scale,
559
+ comment: column.comment,
561
560
  index: index ? index.keyName : undefined,
562
561
  unique: unique ? unique.keyName : undefined,
563
562
  enum: !!column.enumItems?.length,
@@ -601,8 +600,7 @@ class DatabaseTable {
601
600
  // If this column is using an enum.
602
601
  if (column.enumItems?.length) {
603
602
  // We will create a new enum name for this type and set it as the property type as well.
604
- // The enum name will be a concatenation of the table name and the column name.
605
- return namingStrategy.getClassName(this.name + '_' + column.name, '_');
603
+ return namingStrategy.getEnumClassName(column.name, this.name, this.schema);
606
604
  }
607
605
  return column.mappedType?.runtimeType ?? 'unknown';
608
606
  }
@@ -659,6 +657,7 @@ class DatabaseTable {
659
657
  type: index.type,
660
658
  expression: index.expression,
661
659
  options: index.options,
660
+ deferMode: index.deferMode,
662
661
  });
663
662
  }
664
663
  addCheck(check) {
@@ -369,7 +369,10 @@ class SchemaComparator {
369
369
  }
370
370
  const defaultRule = ['restrict', 'no action'];
371
371
  const rule = (key, method) => {
372
- return (key[method] ?? defaultRule[0]).toLowerCase().replace(defaultRule[1], defaultRule[0]);
372
+ return (key[method] ?? defaultRule[0])
373
+ .toLowerCase()
374
+ .replace(defaultRule[1], defaultRule[0])
375
+ .replace(/"/g, '');
373
376
  };
374
377
  const compare = (method) => rule(key1, method) === rule(key2, method);
375
378
  return !compare('updateRule') || !compare('deleteRule');
@@ -415,7 +418,8 @@ class SchemaComparator {
415
418
  log(`'unsigned' changed for column ${tableName}.${fromColumn.name}`, { fromColumn, toColumn });
416
419
  changedProperties.add('unsigned');
417
420
  }
418
- if (!this.hasSameDefaultValue(fromColumn, toColumn)) {
421
+ if (!(fromColumn.ignoreSchemaChanges?.includes('default') ||
422
+ toColumn.ignoreSchemaChanges?.includes('default')) && !this.hasSameDefaultValue(fromColumn, toColumn)) {
419
423
  log(`'default' changed for column ${tableName}.${fromColumn.name}`, { fromColumn, toColumn });
420
424
  changedProperties.add('default');
421
425
  }
@@ -2,7 +2,7 @@ import { type Connection, type Dictionary } from '@mikro-orm/core';
2
2
  import type { Knex } from 'knex';
3
3
  import type { AbstractSqlConnection } from '../AbstractSqlConnection';
4
4
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
5
- import type { CheckDef, Column, IndexDef, Table, TableDifference } from '../typings';
5
+ import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference } from '../typings';
6
6
  import type { DatabaseSchema } from './DatabaseSchema';
7
7
  import type { DatabaseTable } from './DatabaseTable';
8
8
  export declare abstract class SchemaHelper {
@@ -21,7 +21,7 @@ export declare abstract class SchemaHelper {
21
21
  getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
22
22
  getCreateNativeEnumSQL(name: string, values: unknown[], schema?: string): string;
23
23
  getDropNativeEnumSQL(name: string, schema?: string): string;
24
- getAlterNativeEnumSQL(name: string, schema?: string, value?: string): string;
24
+ getAlterNativeEnumSQL(name: string, schema?: string, value?: string, items?: string[], oldItems?: string[]): string;
25
25
  loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[], schemas?: string[]): Promise<void>;
26
26
  getListTablesSQL(schemaName?: string): string;
27
27
  getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column, schemaName?: string): string;
@@ -58,4 +58,20 @@ export declare abstract class SchemaHelper {
58
58
  * Uses `raw` method injected in `AbstractSqlConnection` to allow adding custom queries inside alter statements.
59
59
  */
60
60
  pushTableQuery(table: Knex.TableBuilder, expression: string, grouping?: string): void;
61
+ dump(builder: Knex.SchemaBuilder | string, append: string): Promise<string>;
62
+ createTable(tableDef: DatabaseTable, alter?: boolean): Knex.SchemaBuilder;
63
+ createForeignKey(table: Knex.CreateTableBuilder, foreignKey: ForeignKey, schema?: string): void;
64
+ splitTableName(name: string): [string | undefined, string];
65
+ getReferencedTableName(referencedTableName: string, schema?: string): string;
66
+ createIndex(table: Knex.CreateTableBuilder, index: IndexDef, tableDef: DatabaseTable, createPrimary?: boolean): void;
67
+ createCheck(table: Knex.CreateTableBuilder, check: CheckDef): void;
68
+ createSchemaBuilder(schema?: string): Knex.SchemaBuilder;
69
+ getAlterTable?(changedTable: TableDifference, wrap?: boolean): Promise<string>;
70
+ get knex(): Knex;
71
+ get options(): {
72
+ disableForeignKeys?: boolean;
73
+ createForeignKeyConstraints?: boolean;
74
+ ignoreSchema?: string[];
75
+ managementDbName?: string;
76
+ };
61
77
  }