@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.
@@ -20,7 +20,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
20
20
  countVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: CountOptions<T, any>): Promise<number>;
21
21
  protected findFromVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: FindOptions<T, any> | CountOptions<T, any>, type: QueryType): Promise<EntityData<T>[] | number>;
22
22
  protected wrapVirtualExpressionInSubquery<T extends object>(meta: EntityMetadata<T>, expression: string, where: FilterQuery<T>, options: FindOptions<T, any>, type: QueryType): Promise<T[] | number>;
23
- mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: QueryBuilder<T>, map?: Dictionary): EntityData<T> | null;
23
+ mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: QueryBuilder<T, any, any, any>, map?: Dictionary): EntityData<T> | null;
24
24
  private mapJoinedProps;
25
25
  count<T extends object>(entityName: string, where: any, options?: CountOptions<T>): Promise<number>;
26
26
  nativeInsert<T extends object>(entityName: string, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
@@ -52,16 +52,16 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
52
52
  * @internal
53
53
  */
54
54
  mergeJoinedResult<T extends object>(rawResults: EntityData<T>[], meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[]): EntityData<T>[];
55
- protected getFieldsForJoinedLoad<T extends object>(qb: QueryBuilder<T>, meta: EntityMetadata<T>, explicitFields?: Field<T>[], exclude?: Field<T>[], populate?: PopulateOptions<T>[], options?: {
55
+ protected getFieldsForJoinedLoad<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, explicitFields?: Field<T>[], exclude?: Field<T>[], populate?: PopulateOptions<T>[], options?: {
56
56
  strategy?: Options['loadStrategy'];
57
57
  populateWhere?: FindOptions<any>['populateWhere'];
58
58
  }, parentTableAlias?: string, parentJoinPath?: string): Field<T>[];
59
59
  /**
60
60
  * @internal
61
61
  */
62
- mapPropToFieldNames<T extends object>(qb: QueryBuilder<T>, prop: EntityProperty<T>, tableAlias?: string): Field<T>[];
62
+ mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any>, prop: EntityProperty<T>, tableAlias?: string): Field<T>[];
63
63
  /** @internal */
64
- createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T>, ctx?: Transaction<Knex.Transaction>, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): QueryBuilder<T>;
64
+ createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T, any, any, any>, ctx?: Transaction<Knex.Transaction>, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): QueryBuilder<T, any, any, any>;
65
65
  protected resolveConnectionType(args: {
66
66
  ctx?: Transaction<Knex.Transaction>;
67
67
  connectionType?: ConnectionType;
@@ -70,10 +70,10 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
70
70
  protected processManyToMany<T extends object>(meta: EntityMetadata<T> | undefined, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
71
71
  lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
72
72
  protected buildPopulateWhere<T extends object>(meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'populateWhere'>): ObjectQuery<T>;
73
- protected buildOrderBy<T extends object>(qb: QueryBuilder<T>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
74
- protected buildPopulateOrderBy<T extends object>(qb: QueryBuilder<T>, meta: EntityMetadata<T>, populateOrderBy: QueryOrderMap<T>[], parentPath: string, explicit: boolean, parentAlias?: string): QueryOrderMap<T>[];
75
- protected buildJoinedPropsOrderBy<T extends object>(qb: QueryBuilder<T>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options?: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>, parentPath?: string): QueryOrderMap<T>[];
73
+ protected buildOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
74
+ 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>[];
75
+ 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>[];
76
76
  protected normalizeFields<T extends object>(fields: Field<T>[], prefix?: string): string[];
77
- 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>): void;
78
- protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>): Field<T>[];
77
+ 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;
78
+ 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>[];
79
79
  }
@@ -538,7 +538,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
538
538
  let sql = `update ${this.getTableName(meta, options)} set `;
539
539
  const addParams = (prop, value) => {
540
540
  if (prop.kind === core_1.ReferenceKind.EMBEDDED && prop.object) {
541
- if (prop.array) {
541
+ if (prop.array && value) {
542
542
  for (let i = 0; i < value.length; i++) {
543
543
  const item = value[i];
544
544
  value[i] = this.mapDataToFieldNames(item, false, prop.embeddedProps, options.convertCustomTypes);
@@ -1099,9 +1099,12 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
1099
1099
  if (!prop) {
1100
1100
  throw new Error(`Trying to order by not existing property ${meta.className}.${propName}`);
1101
1101
  }
1102
+ let path = parentPath;
1102
1103
  const meta2 = this.metadata.find(prop.type);
1103
1104
  const childOrder = orderHint[prop.name];
1104
- let path = `${parentPath}.${propName}`;
1105
+ if (![core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) || !prop.owner || core_1.Utils.isPlainObject(childOrder)) {
1106
+ path += `.${propName}`;
1107
+ }
1105
1108
  if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY && typeof childOrder !== 'object') {
1106
1109
  path += '[pivot]';
1107
1110
  }
@@ -1,4 +1,4 @@
1
- import { type EntityMetadata, type EntityProperty, type Primary } from '@mikro-orm/core';
1
+ import { type EntityMetadata, type EntityProperty, type Primary, type Transaction } from '@mikro-orm/core';
2
2
  import { type AbstractSqlDriver } from './AbstractSqlDriver';
3
3
  export declare class PivotCollectionPersister<Entity extends object> {
4
4
  private readonly meta;
@@ -10,7 +10,7 @@ export declare class PivotCollectionPersister<Entity extends object> {
10
10
  private readonly deletes;
11
11
  private readonly batchSize;
12
12
  private order;
13
- constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: any, schema?: string | undefined);
13
+ constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined);
14
14
  enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[]): void;
15
15
  private enqueueInsert;
16
16
  private enqueueDelete;
@@ -10,11 +10,11 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
10
10
  /**
11
11
  * Creates a QueryBuilder instance
12
12
  */
13
- createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T>, alias?: string, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<T>;
13
+ createQueryBuilder<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity> | QueryBuilder<Entity>, alias?: RootAlias, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias>;
14
14
  /**
15
15
  * Shortcut for `createQueryBuilder()`
16
16
  */
17
- qb<T extends object>(entityName: EntityName<T>, alias?: string, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<T>;
17
+ qb<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity>, alias?: RootAlias, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias, never, never>;
18
18
  /**
19
19
  * Returns configured knex instance.
20
20
  */
@@ -2,17 +2,17 @@ import type { Knex } from 'knex';
2
2
  import { EntityRepository, type ConnectionType, type EntityName } from '@mikro-orm/core';
3
3
  import type { SqlEntityManager } from './SqlEntityManager';
4
4
  import type { QueryBuilder } from './query';
5
- export declare class SqlEntityRepository<T extends object> extends EntityRepository<T> {
5
+ export declare class SqlEntityRepository<Entity extends object> extends EntityRepository<Entity> {
6
6
  protected readonly em: SqlEntityManager;
7
- constructor(em: SqlEntityManager, entityName: EntityName<T>);
7
+ constructor(em: SqlEntityManager, entityName: EntityName<Entity>);
8
8
  /**
9
9
  * Creates a QueryBuilder instance
10
10
  */
11
- createQueryBuilder(alias?: string): QueryBuilder<T>;
11
+ createQueryBuilder<RootAlias extends string = never>(alias?: RootAlias): QueryBuilder<Entity, RootAlias>;
12
12
  /**
13
13
  * Shortcut for `createQueryBuilder()`
14
14
  */
15
- qb(alias?: string): QueryBuilder<T>;
15
+ qb<RootAlias extends string = never>(alias?: RootAlias): QueryBuilder<Entity, RootAlias>;
16
16
  /**
17
17
  * Returns configured knex instance.
18
18
  */
@@ -46,7 +46,7 @@ class MySqlSchemaHelper extends SchemaHelper_1.SchemaHelper {
46
46
  }
47
47
  }
48
48
  async getAllIndexes(connection, tables) {
49
- const sql = `select table_name as table_name, nullif(table_schema, schema()) as schema_name, index_name as index_name, non_unique as non_unique, column_name as column_name, expression as expression
49
+ const sql = `select table_name as table_name, nullif(table_schema, schema()) as schema_name, index_name as index_name, non_unique as non_unique, column_name as column_name /*!80013 , expression as expression */
50
50
  from information_schema.statistics where table_schema = database()
51
51
  and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
52
52
  order by schema_name, table_name, index_name, seq_in_index`;
@@ -78,7 +78,7 @@ class MySqlSchemaHelper extends SchemaHelper_1.SchemaHelper {
78
78
  nullif(table_schema, schema()) as schema_name,
79
79
  column_name as column_name,
80
80
  column_default as column_default,
81
- column_comment as column_comment,
81
+ nullif(column_comment, '') as column_comment,
82
82
  is_nullable as is_nullable,
83
83
  data_type as data_type,
84
84
  column_type as column_type,
@@ -30,6 +30,9 @@ export declare abstract class BaseSqlitePlatform extends AbstractSqlPlatform {
30
30
  }): string;
31
31
  getFloatDeclarationSQL(): string;
32
32
  getBooleanTypeDeclarationSQL(): string;
33
+ getCharTypeDeclarationSQL(column: {
34
+ length?: number;
35
+ }): string;
33
36
  getVarcharTypeDeclarationSQL(column: {
34
37
  length?: number;
35
38
  }): string;
@@ -38,6 +38,9 @@ class BaseSqlitePlatform extends AbstractSqlPlatform_1.AbstractSqlPlatform {
38
38
  getBooleanTypeDeclarationSQL() {
39
39
  return 'integer';
40
40
  }
41
+ getCharTypeDeclarationSQL(column) {
42
+ return 'text';
43
+ }
41
44
  getVarcharTypeDeclarationSQL(column) {
42
45
  return 'text';
43
46
  }
@@ -1,7 +1,7 @@
1
1
  import type { Connection, Dictionary } from '@mikro-orm/core';
2
2
  import type { AbstractSqlConnection } from '../../AbstractSqlConnection';
3
3
  import { SchemaHelper } from '../../schema/SchemaHelper';
4
- import type { CheckDef, Column, IndexDef } from '../../typings';
4
+ import type { CheckDef, Column, IndexDef, TableDifference } from '../../typings';
5
5
  export declare abstract class BaseSqliteSchemaHelper extends SchemaHelper {
6
6
  disableForeignKeysSQL(): string;
7
7
  enableForeignKeysSQL(): string;
@@ -24,4 +24,5 @@ export declare abstract class BaseSqliteSchemaHelper extends SchemaHelper {
24
24
  * Implicit indexes will be ignored when diffing
25
25
  */
26
26
  isImplicitIndex(name: string): boolean;
27
+ getAlterTable(changedTable: TableDifference, wrap?: boolean): Promise<string>;
27
28
  }
@@ -168,5 +168,22 @@ class BaseSqliteSchemaHelper extends SchemaHelper_1.SchemaHelper {
168
168
  // Ignore indexes with reserved names, e.g. autoindexes
169
169
  return name.startsWith('sqlite_');
170
170
  }
171
+ async getAlterTable(changedTable, wrap) {
172
+ wrap ??= this.options.disableForeignKeys;
173
+ const tempName = `${(changedTable.toTable.name)}__temp_alter`;
174
+ const quotedName = this.platform.quoteIdentifier(changedTable.toTable.name);
175
+ const quotedTempName = this.platform.quoteIdentifier(tempName);
176
+ const createSql = await this.dump(this.createTable(changedTable.toTable), '');
177
+ const [first, ...rest] = createSql.split('\n');
178
+ return [
179
+ 'pragma foreign_keys = off;',
180
+ first.replace(`create table ${quotedName}`, `create table ${quotedTempName}`),
181
+ `insert into ${quotedTempName} select * from ${quotedName};`,
182
+ `drop table ${quotedName};`,
183
+ `alter table ${quotedTempName} rename to ${quotedName};`,
184
+ ...rest,
185
+ 'pragma foreign_keys = on;',
186
+ ].join('\n');
187
+ }
171
188
  }
172
189
  exports.BaseSqliteSchemaHelper = BaseSqliteSchemaHelper;
@@ -2,5 +2,10 @@ import { MonkeyPatchable } from '../../MonkeyPatchable';
2
2
  export declare class LibSqlKnexDialect extends MonkeyPatchable.BetterSqlite3Dialect {
3
3
  get driverName(): string;
4
4
  _driver(): any;
5
+ _query(this: any, connection: any, obj: any): Promise<any>;
6
+ acquireRawConnection(this: any): Promise<any>;
5
7
  tableCompiler(): any;
8
+ validateConnection(connection: any): boolean;
9
+ private getCallMethod;
10
+ private isRunQuery;
6
11
  }
@@ -10,9 +10,76 @@ class LibSqlKnexDialect extends MonkeyPatchable_1.MonkeyPatchable.BetterSqlite3D
10
10
  _driver() {
11
11
  return require('libsql');
12
12
  }
13
+ async _query(connection, obj) {
14
+ /* istanbul ignore next */
15
+ if (!obj.sql) {
16
+ throw new Error('The query is empty');
17
+ }
18
+ /* istanbul ignore next */
19
+ if (!connection) {
20
+ throw new Error('No connection provided');
21
+ }
22
+ const callMethod = this.getCallMethod(obj);
23
+ const statement = connection.prepare(obj.sql);
24
+ const bindings = this._formatBindings(obj.bindings);
25
+ const response = await statement[callMethod](bindings);
26
+ obj.response = response;
27
+ obj.context = {
28
+ lastID: response.lastInsertRowid,
29
+ changes: response.changes,
30
+ };
31
+ return obj;
32
+ }
33
+ async acquireRawConnection() {
34
+ const connection = new this.driver(this.connectionSettings.filename, {
35
+ ...this.connectionSettings,
36
+ });
37
+ connection.__created = Date.now();
38
+ return connection;
39
+ }
13
40
  tableCompiler() {
14
41
  // eslint-disable-next-line prefer-rest-params
15
42
  return new SqliteTableCompiler_1.SqliteTableCompiler(this, ...arguments);
16
43
  }
44
+ validateConnection(connection) {
45
+ if (connection.memory) {
46
+ return true;
47
+ }
48
+ /* istanbul ignore next */
49
+ return connection.__created > Date.now() - 10_000;
50
+ }
51
+ getCallMethod(obj) {
52
+ if (obj.method === 'raw') {
53
+ const query = obj.sql.trim().toLowerCase();
54
+ if ((query.startsWith('insert into') || query.startsWith('update ')) && query.includes(' returning ')) {
55
+ return 'all';
56
+ }
57
+ if (this.isRunQuery(query)) {
58
+ return 'run';
59
+ }
60
+ }
61
+ /* istanbul ignore next */
62
+ switch (obj.method) {
63
+ case 'insert':
64
+ case 'update':
65
+ return obj.returning ? 'all' : 'run';
66
+ case 'counter':
67
+ case 'del':
68
+ return 'run';
69
+ default:
70
+ return 'all';
71
+ }
72
+ }
73
+ isRunQuery(query) {
74
+ query = query.trim().toLowerCase();
75
+ /* istanbul ignore next */
76
+ if ((query.startsWith('insert into') || query.startsWith('update ')) && query.includes(' returning ')) {
77
+ return false;
78
+ }
79
+ return query.startsWith('insert into') ||
80
+ query.startsWith('update') ||
81
+ query.startsWith('delete') ||
82
+ query.startsWith('truncate');
83
+ }
17
84
  }
18
85
  exports.LibSqlKnexDialect = LibSqlKnexDialect;
package/index.mjs CHANGED
@@ -33,6 +33,7 @@ export const ChangeSet = mod.ChangeSet;
33
33
  export const ChangeSetComputer = mod.ChangeSetComputer;
34
34
  export const ChangeSetPersister = mod.ChangeSetPersister;
35
35
  export const ChangeSetType = mod.ChangeSetType;
36
+ export const CharacterType = mod.CharacterType;
36
37
  export const Check = mod.Check;
37
38
  export const CheckConstraintViolationException = mod.CheckConstraintViolationException;
38
39
  export const Collection = mod.Collection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.2.10-dev.1",
3
+ "version": "6.2.10-dev.100",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -66,7 +66,7 @@
66
66
  "@mikro-orm/core": "^6.2.9"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.2.10-dev.1",
69
+ "@mikro-orm/core": "6.2.10-dev.100",
70
70
  "better-sqlite3": "*",
71
71
  "libsql": "*",
72
72
  "mariadb": "*"
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { inspect } from 'util';
3
2
  import { type EntityKey, type EntityProperty, type MetadataStorage } from '@mikro-orm/core';
4
3
  import type { ICriteriaNode, ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings';
@@ -70,7 +70,8 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
70
70
  const primaryKey = this.key && this.metadata.find(this.entityName).primaryKeys.includes(field);
71
71
  if (childNode.shouldInline(payload)) {
72
72
  const childAlias = qb.getAliasForJoinPath(childNode.getPath(), options);
73
- this.inlineChildPayload(o, payload, field, alias, childAlias);
73
+ const a = qb.helper.isTableNameAliasRequired(qb.type) ? alias : undefined;
74
+ this.inlineChildPayload(o, payload, field, a, childAlias);
74
75
  }
75
76
  else if (childNode.shouldRename(payload)) {
76
77
  o[childNode.renameFieldToPK(qb)] = payload;
@@ -149,7 +150,6 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
149
150
  o[k] = payload[k];
150
151
  }
151
152
  else {
152
- o[`${childAlias}.${k}`] = payload[k];
153
153
  o[this.aliased(k, childAlias)] = payload[k];
154
154
  }
155
155
  }