@mikro-orm/knex 7.0.0-dev.7 → 7.0.0-dev.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AbstractSqlConnection.d.ts +11 -5
- package/AbstractSqlConnection.js +79 -32
- package/AbstractSqlDriver.d.ts +9 -5
- package/AbstractSqlDriver.js +268 -220
- package/AbstractSqlPlatform.js +3 -3
- package/PivotCollectionPersister.d.ts +3 -2
- package/PivotCollectionPersister.js +12 -21
- package/README.md +3 -2
- package/SqlEntityManager.d.ts +9 -2
- package/SqlEntityManager.js +2 -2
- package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +2 -0
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +43 -2
- package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +1 -0
- package/dialects/postgresql/PostgreSqlTableCompiler.js +1 -0
- package/dialects/sqlite/BaseSqliteConnection.d.ts +4 -2
- package/dialects/sqlite/BaseSqliteConnection.js +8 -5
- package/dialects/sqlite/BaseSqlitePlatform.js +1 -2
- package/dialects/sqlite/SqliteSchemaHelper.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +5 -5
- package/query/ArrayCriteriaNode.d.ts +1 -0
- package/query/ArrayCriteriaNode.js +3 -0
- package/query/CriteriaNode.d.ts +4 -2
- package/query/CriteriaNode.js +11 -6
- package/query/CriteriaNodeFactory.js +12 -7
- package/query/NativeQueryBuilder.js +1 -1
- package/query/ObjectCriteriaNode.d.ts +1 -0
- package/query/ObjectCriteriaNode.js +38 -9
- package/query/QueryBuilder.d.ts +59 -7
- package/query/QueryBuilder.js +171 -47
- package/query/QueryBuilderHelper.d.ts +1 -1
- package/query/QueryBuilderHelper.js +15 -8
- package/query/ScalarCriteriaNode.d.ts +3 -3
- package/query/ScalarCriteriaNode.js +9 -7
- package/query/index.d.ts +1 -0
- package/query/index.js +1 -0
- package/query/raw.d.ts +59 -0
- package/query/raw.js +68 -0
- package/query/rawKnex.d.ts +58 -0
- package/query/rawKnex.js +72 -0
- package/schema/DatabaseSchema.js +25 -4
- package/schema/DatabaseTable.d.ts +5 -4
- package/schema/DatabaseTable.js +67 -33
- package/schema/SchemaComparator.js +2 -2
- package/schema/SchemaHelper.d.ts +2 -0
- package/schema/SchemaHelper.js +8 -4
- package/schema/SqlSchemaGenerator.d.ts +13 -6
- package/schema/SqlSchemaGenerator.js +38 -17
- package/typings.d.ts +85 -3
package/AbstractSqlPlatform.js
CHANGED
|
@@ -43,13 +43,13 @@ export class AbstractSqlPlatform extends Platform {
|
|
|
43
43
|
return 'rollback';
|
|
44
44
|
}
|
|
45
45
|
getSavepointSQL(savepointName) {
|
|
46
|
-
return `savepoint ${savepointName}`;
|
|
46
|
+
return `savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
47
47
|
}
|
|
48
48
|
getRollbackToSavepointSQL(savepointName) {
|
|
49
|
-
return `rollback to savepoint ${savepointName}`;
|
|
49
|
+
return `rollback to savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
50
50
|
}
|
|
51
51
|
getReleaseSavepointSQL(savepointName) {
|
|
52
|
-
return `release savepoint ${savepointName}`;
|
|
52
|
+
return `release savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
53
53
|
}
|
|
54
54
|
quoteValue(value) {
|
|
55
55
|
if (isRaw(value)) {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { type EntityMetadata, type EntityProperty, type Primary, type Transaction } from '@mikro-orm/core';
|
|
1
|
+
import { type Dictionary, type EntityMetadata, type EntityProperty, type Primary, type Transaction } from '@mikro-orm/core';
|
|
2
2
|
import { type AbstractSqlDriver } from './AbstractSqlDriver.js';
|
|
3
3
|
export declare class PivotCollectionPersister<Entity extends object> {
|
|
4
4
|
private readonly meta;
|
|
5
5
|
private readonly driver;
|
|
6
6
|
private readonly ctx?;
|
|
7
7
|
private readonly schema?;
|
|
8
|
+
private readonly loggerContext?;
|
|
8
9
|
private readonly platform;
|
|
9
10
|
private readonly inserts;
|
|
10
11
|
private readonly deletes;
|
|
11
12
|
private readonly batchSize;
|
|
12
13
|
private order;
|
|
13
|
-
constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined);
|
|
14
|
+
constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined, loggerContext?: Dictionary | undefined);
|
|
14
15
|
enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[]): void;
|
|
15
16
|
private enqueueInsert;
|
|
16
17
|
private enqueueDelete;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Utils, } from '@mikro-orm/core';
|
|
2
1
|
class InsertStatement {
|
|
3
2
|
keys;
|
|
4
3
|
data;
|
|
@@ -38,16 +37,18 @@ export class PivotCollectionPersister {
|
|
|
38
37
|
driver;
|
|
39
38
|
ctx;
|
|
40
39
|
schema;
|
|
40
|
+
loggerContext;
|
|
41
41
|
platform;
|
|
42
42
|
inserts = new Map();
|
|
43
43
|
deletes = new Map();
|
|
44
44
|
batchSize;
|
|
45
45
|
order = 0;
|
|
46
|
-
constructor(meta, driver, ctx, schema) {
|
|
46
|
+
constructor(meta, driver, ctx, schema, loggerContext) {
|
|
47
47
|
this.meta = meta;
|
|
48
48
|
this.driver = driver;
|
|
49
49
|
this.ctx = ctx;
|
|
50
50
|
this.schema = schema;
|
|
51
|
+
this.loggerContext = loggerContext;
|
|
51
52
|
this.platform = this.driver.getPlatform();
|
|
52
53
|
this.batchSize = this.driver.config.get('batchSize');
|
|
53
54
|
}
|
|
@@ -99,6 +100,7 @@ export class PivotCollectionPersister {
|
|
|
99
100
|
await this.driver.nativeDelete(this.meta.className, cond, {
|
|
100
101
|
ctx: this.ctx,
|
|
101
102
|
schema: this.schema,
|
|
103
|
+
loggerContext: this.loggerContext,
|
|
102
104
|
});
|
|
103
105
|
}
|
|
104
106
|
}
|
|
@@ -110,26 +112,15 @@ export class PivotCollectionPersister {
|
|
|
110
112
|
items[insert.order] = insert.getData();
|
|
111
113
|
}
|
|
112
114
|
items = items.filter(i => i);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
/* v8 ignore start */
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
await Utils.runSerial(items, item => {
|
|
127
|
-
return this.driver.createQueryBuilder(this.meta.className, this.ctx, 'write')
|
|
128
|
-
.withSchema(this.schema)
|
|
129
|
-
.insert(item)
|
|
130
|
-
.execute('run', false);
|
|
115
|
+
for (let i = 0; i < items.length; i += this.batchSize) {
|
|
116
|
+
const chunk = items.slice(i, i + this.batchSize);
|
|
117
|
+
await this.driver.nativeInsertMany(this.meta.className, chunk, {
|
|
118
|
+
ctx: this.ctx,
|
|
119
|
+
schema: this.schema,
|
|
120
|
+
convertCustomTypes: false,
|
|
121
|
+
processCollections: false,
|
|
122
|
+
loggerContext: this.loggerContext,
|
|
131
123
|
});
|
|
132
124
|
}
|
|
133
|
-
/* v8 ignore stop */
|
|
134
125
|
}
|
|
135
126
|
}
|
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
|
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
12
|
[](https://www.npmjs.com/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
|
-
[](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
|
|
15
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
16
15
|
|
|
17
16
|
## 🤔 Unit of What?
|
|
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
|
|
|
141
140
|
- [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
|
|
142
141
|
- [Filters](https://mikro-orm.io/docs/filters)
|
|
143
142
|
- [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
|
|
144
|
-
- [
|
|
143
|
+
- [Populating relations](https://mikro-orm.io/docs/populating-relations)
|
|
145
144
|
- [Property Validation](https://mikro-orm.io/docs/property-validation)
|
|
146
145
|
- [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
|
|
147
146
|
- [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
|
|
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
382
381
|
|
|
383
382
|
Please ⭐️ this repository if this project helped you!
|
|
384
383
|
|
|
384
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
385
|
+
|
|
385
386
|
## 📝 License
|
|
386
387
|
|
|
387
388
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/SqlEntityManager.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { EntityManager, type AnyEntity, type ConnectionType, type EntityData, type EntityName, type EntityRepository, type GetRepository, type QueryResult, type FilterQuery, type LoggingOptions, type RawQueryFragment } from '@mikro-orm/core';
|
|
1
|
+
import { type EntitySchemaWithMeta, EntityManager, type AnyEntity, type ConnectionType, type EntityData, type EntityName, type EntityRepository, type GetRepository, type QueryResult, type FilterQuery, type LoggingOptions, type RawQueryFragment } from '@mikro-orm/core';
|
|
2
2
|
import type { AbstractSqlDriver } from './AbstractSqlDriver.js';
|
|
3
3
|
import type { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
|
|
4
4
|
import type { QueryBuilder } from './query/QueryBuilder.js';
|
|
5
5
|
import type { SqlEntityRepository } from './SqlEntityRepository.js';
|
|
6
|
+
import type { Kysely } from 'kysely';
|
|
7
|
+
import type { InferKyselyDB } from './typings.js';
|
|
8
|
+
export interface GetKyselyOptions {
|
|
9
|
+
type?: ConnectionType;
|
|
10
|
+
}
|
|
6
11
|
/**
|
|
7
12
|
* @inheritDoc
|
|
8
13
|
*/
|
|
@@ -18,8 +23,10 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
|
|
|
18
23
|
/**
|
|
19
24
|
* Returns configured Kysely instance.
|
|
20
25
|
*/
|
|
21
|
-
getKysely(
|
|
26
|
+
getKysely<TDB = undefined, TOptions extends GetKyselyOptions = GetKyselyOptions>(options?: TOptions): Kysely<TDB extends undefined ? InferKyselyDB<EntitiesFromManager<this>, TOptions> : TDB>;
|
|
22
27
|
execute<T extends QueryResult | EntityData<AnyEntity> | EntityData<AnyEntity>[] = EntityData<AnyEntity>[]>(query: string | NativeQueryBuilder | RawQueryFragment, params?: any[], method?: 'all' | 'get' | 'run', loggerContext?: LoggingOptions): Promise<T>;
|
|
23
28
|
getRepository<T extends object, U extends EntityRepository<T> = SqlEntityRepository<T>>(entityName: EntityName<T>): GetRepository<T, U>;
|
|
24
29
|
protected applyDiscriminatorCondition<Entity extends object>(entityName: string, where: FilterQuery<Entity>): FilterQuery<Entity>;
|
|
25
30
|
}
|
|
31
|
+
type EntitiesFromManager<TEntityManager extends EntityManager<any>> = NonNullable<TEntityManager['~entities']> extends any[] ? (Extract<NonNullable<TEntityManager['~entities']>[number], EntitySchemaWithMeta>) : never;
|
|
32
|
+
export {};
|
package/SqlEntityManager.js
CHANGED
|
@@ -19,8 +19,8 @@ export class SqlEntityManager extends EntityManager {
|
|
|
19
19
|
/**
|
|
20
20
|
* Returns configured Kysely instance.
|
|
21
21
|
*/
|
|
22
|
-
getKysely(
|
|
23
|
-
return this.getConnection(type).getClient();
|
|
22
|
+
getKysely(options = {}) {
|
|
23
|
+
return this.getConnection(options.type).getClient();
|
|
24
24
|
}
|
|
25
25
|
async execute(query, params = [], method = 'all', loggerContext) {
|
|
26
26
|
return this.getDriver().execute(query, params, method, this.getContext(false).getTransactionContext(), loggerContext);
|
|
@@ -5,6 +5,8 @@ export declare class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
5
5
|
sql: string;
|
|
6
6
|
params: unknown[];
|
|
7
7
|
};
|
|
8
|
+
protected compileInsert(): void;
|
|
9
|
+
private appendOutputTable;
|
|
8
10
|
private compileUpsert;
|
|
9
11
|
protected compileSelect(): void;
|
|
10
12
|
protected addLockClause(): void;
|
|
@@ -12,6 +12,10 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
12
12
|
if (this.options.flags?.has(QueryFlag.IDENTITY_INSERT)) {
|
|
13
13
|
this.parts.push(`set identity_insert ${this.getTableName()} on;`);
|
|
14
14
|
}
|
|
15
|
+
const { prefix, suffix } = this.appendOutputTable();
|
|
16
|
+
if (prefix) {
|
|
17
|
+
this.parts.push(prefix);
|
|
18
|
+
}
|
|
15
19
|
if (this.options.comment) {
|
|
16
20
|
this.parts.push(...this.options.comment.map(comment => `/* ${comment} */`));
|
|
17
21
|
}
|
|
@@ -37,7 +41,11 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
37
41
|
this.compileTruncate();
|
|
38
42
|
break;
|
|
39
43
|
}
|
|
40
|
-
if (
|
|
44
|
+
if (suffix) {
|
|
45
|
+
this.parts[this.parts.length - 1] += ';';
|
|
46
|
+
this.parts.push(suffix);
|
|
47
|
+
}
|
|
48
|
+
else if ([QueryType.INSERT, QueryType.UPDATE, QueryType.DELETE].includes(this.type)) {
|
|
41
49
|
this.parts[this.parts.length - 1] += '; select @@rowcount;';
|
|
42
50
|
}
|
|
43
51
|
}
|
|
@@ -46,6 +54,37 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
46
54
|
}
|
|
47
55
|
return this.combineParts();
|
|
48
56
|
}
|
|
57
|
+
compileInsert() {
|
|
58
|
+
if (!this.options.data) {
|
|
59
|
+
throw new Error('No data provided');
|
|
60
|
+
}
|
|
61
|
+
this.parts.push('insert');
|
|
62
|
+
this.addHintComment();
|
|
63
|
+
this.parts.push(`into ${this.getTableName()}`);
|
|
64
|
+
if (Object.keys(this.options.data).length === 0) {
|
|
65
|
+
this.addOutputClause('inserted');
|
|
66
|
+
this.parts.push('default values');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const parts = this.processInsertData();
|
|
70
|
+
if (this.options.flags?.has(QueryFlag.OUTPUT_TABLE)) {
|
|
71
|
+
this.parts[this.parts.length - 2] += ' into #out ';
|
|
72
|
+
}
|
|
73
|
+
this.parts.push(parts.join(', '));
|
|
74
|
+
}
|
|
75
|
+
appendOutputTable() {
|
|
76
|
+
if (!this.options.flags?.has(QueryFlag.OUTPUT_TABLE)) {
|
|
77
|
+
return { prefix: '', suffix: '' };
|
|
78
|
+
}
|
|
79
|
+
const returningFields = this.options.returning;
|
|
80
|
+
const selections = returningFields
|
|
81
|
+
.map(field => `[t].${this.platform.quoteIdentifier(field)}`)
|
|
82
|
+
.join(',');
|
|
83
|
+
return {
|
|
84
|
+
prefix: `select top(0) ${selections} into #out from ${this.getTableName()} as t left join ${this.getTableName()} on 0 = 1;`,
|
|
85
|
+
suffix: `select ${selections} from #out as t; drop table #out`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
49
88
|
compileUpsert() {
|
|
50
89
|
const clause = this.options.onConflict;
|
|
51
90
|
const dataAsArray = Utils.asArray(this.options.data);
|
|
@@ -82,7 +121,9 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
82
121
|
}
|
|
83
122
|
this.parts.push('then update set');
|
|
84
123
|
if (!clause.merge || Array.isArray(clause.merge)) {
|
|
85
|
-
const parts =
|
|
124
|
+
const parts = (clause.merge || keys)
|
|
125
|
+
.filter(field => !Array.isArray(clause.fields) || !clause.fields.includes(field))
|
|
126
|
+
.map((column) => `${this.quote(column)} = tsource.${this.quote(column)}`);
|
|
86
127
|
this.parts.push(parts.join(', '));
|
|
87
128
|
}
|
|
88
129
|
else if (typeof clause.merge === 'object') {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
|
|
2
2
|
export declare abstract class BaseSqliteConnection extends AbstractSqlConnection {
|
|
3
|
-
connect(
|
|
4
|
-
|
|
3
|
+
connect(options?: {
|
|
4
|
+
skipOnConnect?: boolean;
|
|
5
|
+
simple?: boolean;
|
|
6
|
+
}): Promise<void>;
|
|
5
7
|
}
|
|
@@ -3,12 +3,15 @@ import { CompiledQuery } from 'kysely';
|
|
|
3
3
|
import { Utils } from '@mikro-orm/core';
|
|
4
4
|
import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
|
|
5
5
|
export class BaseSqliteConnection extends AbstractSqlConnection {
|
|
6
|
-
async connect() {
|
|
6
|
+
async connect(options) {
|
|
7
7
|
await super.connect();
|
|
8
|
-
|
|
8
|
+
if (options?.simple) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const dbName = this.config.get('dbName');
|
|
12
|
+
if (dbName && dbName !== ':memory:') {
|
|
13
|
+
Utils.ensureDir(dirname(this.config.get('dbName')));
|
|
14
|
+
}
|
|
9
15
|
await this.client.executeQuery(CompiledQuery.raw('pragma foreign_keys = on'));
|
|
10
16
|
}
|
|
11
|
-
getClientUrl() {
|
|
12
|
-
return '';
|
|
13
|
-
}
|
|
14
17
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Utils } from '@mikro-orm/core';
|
|
2
1
|
import { AbstractSqlPlatform } from '../../AbstractSqlPlatform.js';
|
|
3
2
|
import { SqliteNativeQueryBuilder } from './SqliteNativeQueryBuilder.js';
|
|
4
3
|
import { SqliteSchemaHelper } from './SqliteSchemaHelper.js';
|
|
@@ -29,7 +28,7 @@ export class BaseSqlitePlatform extends AbstractSqlPlatform {
|
|
|
29
28
|
return ['begin'];
|
|
30
29
|
}
|
|
31
30
|
getEnumTypeDeclarationSQL(column) {
|
|
32
|
-
if (column.items?.every(item =>
|
|
31
|
+
if (column.items?.every(item => typeof item === 'string')) {
|
|
33
32
|
return 'text';
|
|
34
33
|
}
|
|
35
34
|
/* v8 ignore next */
|
|
@@ -167,7 +167,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
167
167
|
if (col.hidden > 1) {
|
|
168
168
|
/* v8 ignore next */
|
|
169
169
|
const storage = col.hidden === 2 ? 'virtual' : 'stored';
|
|
170
|
-
const re = `(generated always)? as \\((.*)\\)( ${storage})
|
|
170
|
+
const re = new RegExp(`(generated always)? as \\((.*)\\)( ${storage})?$`, 'i');
|
|
171
171
|
const match = columnDefinitions[col.name].definition.match(re);
|
|
172
172
|
if (match) {
|
|
173
173
|
generated = `${match[2]} ${storage}`;
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module knex
|
|
4
4
|
*/
|
|
5
|
-
/** @ignore */
|
|
6
5
|
export { Kysely } from 'kysely';
|
|
7
6
|
export * from '@mikro-orm/core';
|
|
8
7
|
export * from './AbstractSqlConnection.js';
|
|
@@ -11,6 +10,7 @@ export * from './AbstractSqlPlatform.js';
|
|
|
11
10
|
export * from './SqlEntityManager.js';
|
|
12
11
|
export * from './SqlEntityRepository.js';
|
|
13
12
|
export * from './query/index.js';
|
|
13
|
+
export { raw } from './query/index.js';
|
|
14
14
|
export * from './schema/index.js';
|
|
15
15
|
export * from './dialects/index.js';
|
|
16
16
|
export * from './typings.js';
|
package/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module knex
|
|
4
4
|
*/
|
|
5
|
-
/** @ignore */
|
|
6
5
|
export { Kysely } from 'kysely';
|
|
7
6
|
export * from '@mikro-orm/core';
|
|
8
7
|
export * from './AbstractSqlConnection.js';
|
|
@@ -11,6 +10,7 @@ export * from './AbstractSqlPlatform.js';
|
|
|
11
10
|
export * from './SqlEntityManager.js';
|
|
12
11
|
export * from './SqlEntityRepository.js';
|
|
13
12
|
export * from './query/index.js';
|
|
13
|
+
export { raw } from './query/index.js';
|
|
14
14
|
export * from './schema/index.js';
|
|
15
15
|
export * from './dialects/index.js';
|
|
16
16
|
export * from './typings.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.71",
|
|
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": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"homepage": "https://mikro-orm.io",
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">= 22.
|
|
41
|
+
"node": ">= 22.17.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "yarn clean && yarn compile && yarn copy",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"kysely": "
|
|
53
|
+
"kysely": "0.28.8",
|
|
54
54
|
"sqlstring": "2.3.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@mikro-orm/core": "^6.
|
|
57
|
+
"@mikro-orm/core": "^6.6.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
60
|
+
"@mikro-orm/core": "7.0.0-dev.71"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -7,4 +7,5 @@ export declare class ArrayCriteriaNode<T extends object> extends CriteriaNode<T>
|
|
|
7
7
|
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
8
8
|
unwrap(): any;
|
|
9
9
|
willAutoJoin(qb: IQueryBuilder<T>, alias?: string, options?: ICriteriaNodeProcessOptions): any;
|
|
10
|
+
isStrict(): boolean;
|
|
10
11
|
}
|
package/query/CriteriaNode.d.ts
CHANGED
|
@@ -11,20 +11,22 @@ export declare class CriteriaNode<T extends object> implements ICriteriaNode<T>
|
|
|
11
11
|
readonly entityName: string;
|
|
12
12
|
readonly parent?: ICriteriaNode<T> | undefined;
|
|
13
13
|
readonly key?: EntityKey<T> | undefined;
|
|
14
|
+
readonly strict: boolean;
|
|
14
15
|
payload: any;
|
|
15
16
|
prop?: EntityProperty<T>;
|
|
16
17
|
index?: number;
|
|
17
|
-
constructor(metadata: MetadataStorage, entityName: string, parent?: ICriteriaNode<T> | undefined, key?: EntityKey<T> | undefined, validate?: boolean);
|
|
18
|
+
constructor(metadata: MetadataStorage, entityName: string, parent?: ICriteriaNode<T> | undefined, key?: EntityKey<T> | undefined, validate?: boolean, strict?: boolean);
|
|
18
19
|
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
19
20
|
unwrap(): any;
|
|
20
21
|
shouldInline(payload: any): boolean;
|
|
21
22
|
willAutoJoin(qb: IQueryBuilder<T>, alias?: string, options?: ICriteriaNodeProcessOptions): boolean;
|
|
22
23
|
shouldRename(payload: any): boolean;
|
|
23
|
-
renameFieldToPK<T>(qb: IQueryBuilder<T
|
|
24
|
+
renameFieldToPK<T>(qb: IQueryBuilder<T>, ownerAlias?: string): string;
|
|
24
25
|
getPath(addIndex?: boolean): string;
|
|
25
26
|
private isPivotJoin;
|
|
26
27
|
getPivotPath(path: string): string;
|
|
27
28
|
aliased(field: string, alias?: string): string;
|
|
29
|
+
isStrict(): boolean;
|
|
28
30
|
/** @ignore */
|
|
29
31
|
[inspect.custom](): string;
|
|
30
32
|
}
|
package/query/CriteriaNode.js
CHANGED
|
@@ -10,14 +10,16 @@ export class CriteriaNode {
|
|
|
10
10
|
entityName;
|
|
11
11
|
parent;
|
|
12
12
|
key;
|
|
13
|
+
strict;
|
|
13
14
|
payload;
|
|
14
15
|
prop;
|
|
15
16
|
index;
|
|
16
|
-
constructor(metadata, entityName, parent, key, validate = true) {
|
|
17
|
+
constructor(metadata, entityName, parent, key, validate = true, strict = false) {
|
|
17
18
|
this.metadata = metadata;
|
|
18
19
|
this.entityName = entityName;
|
|
19
20
|
this.parent = parent;
|
|
20
21
|
this.key = key;
|
|
22
|
+
this.strict = strict;
|
|
21
23
|
const meta = parent && metadata.find(parent.entityName);
|
|
22
24
|
if (meta && key) {
|
|
23
25
|
const pks = Utils.splitPrimaryKeys(key);
|
|
@@ -65,13 +67,13 @@ export class CriteriaNode {
|
|
|
65
67
|
default: return false;
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
|
-
renameFieldToPK(qb) {
|
|
69
|
-
|
|
70
|
+
renameFieldToPK(qb, ownerAlias) {
|
|
71
|
+
const joinAlias = qb.getAliasForJoinPath(this.getPath(), { matchPopulateJoins: true });
|
|
70
72
|
if (!joinAlias && this.parent && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop.kind) && this.prop.owner) {
|
|
71
|
-
|
|
72
|
-
return Utils.getPrimaryKeyHash(this.prop.joinColumns.map(col => `${
|
|
73
|
+
const alias = qb.getAliasForJoinPath(this.parent.getPath()) ?? ownerAlias ?? qb.alias;
|
|
74
|
+
return Utils.getPrimaryKeyHash(this.prop.joinColumns.map(col => `${alias}.${col}`));
|
|
73
75
|
}
|
|
74
|
-
const alias = joinAlias ?? qb.alias;
|
|
76
|
+
const alias = joinAlias ?? ownerAlias ?? qb.alias;
|
|
75
77
|
if (this.prop.kind === ReferenceKind.MANY_TO_MANY) {
|
|
76
78
|
return Utils.getPrimaryKeyHash(this.prop.inverseJoinColumns.map(col => `${alias}.${col}`));
|
|
77
79
|
}
|
|
@@ -106,6 +108,9 @@ export class CriteriaNode {
|
|
|
106
108
|
aliased(field, alias) {
|
|
107
109
|
return alias ? `${alias}.${field}` : field;
|
|
108
110
|
}
|
|
111
|
+
isStrict() {
|
|
112
|
+
return this.strict;
|
|
113
|
+
}
|
|
109
114
|
/** @ignore */
|
|
110
115
|
[inspect.custom]() {
|
|
111
116
|
const o = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isRaw, JsonType, RawQueryFragment, ReferenceKind, Utils, ValidationError, } from '@mikro-orm/core';
|
|
1
|
+
import { GroupOperator, isRaw, JsonType, RawQueryFragment, ReferenceKind, Utils, ValidationError, } from '@mikro-orm/core';
|
|
2
2
|
import { ObjectCriteriaNode } from './ObjectCriteriaNode.js';
|
|
3
3
|
import { ArrayCriteriaNode } from './ArrayCriteriaNode.js';
|
|
4
4
|
import { ScalarCriteriaNode } from './ScalarCriteriaNode.js';
|
|
@@ -36,7 +36,7 @@ export class CriteriaNodeFactory {
|
|
|
36
36
|
}
|
|
37
37
|
static createObjectNode(metadata, entityName, payload, parent, key) {
|
|
38
38
|
const meta = metadata.find(entityName);
|
|
39
|
-
const node = new ObjectCriteriaNode(metadata, entityName, parent, key);
|
|
39
|
+
const node = new ObjectCriteriaNode(metadata, entityName, parent, key, true, payload.__strict);
|
|
40
40
|
node.payload = {};
|
|
41
41
|
for (const key of Object.keys(payload)) {
|
|
42
42
|
node.payload[key] = this.createObjectItemNode(metadata, entityName, node, payload, key, meta);
|
|
@@ -46,10 +46,14 @@ export class CriteriaNodeFactory {
|
|
|
46
46
|
static createObjectItemNode(metadata, entityName, node, payload, key, meta) {
|
|
47
47
|
const prop = meta?.properties[key];
|
|
48
48
|
const childEntity = prop && prop.kind !== ReferenceKind.SCALAR ? prop.type : entityName;
|
|
49
|
-
|
|
49
|
+
const isNotEmbedded = prop?.kind !== ReferenceKind.EMBEDDED;
|
|
50
|
+
if (isNotEmbedded && prop?.customType instanceof JsonType) {
|
|
50
51
|
return this.createScalarNode(metadata, childEntity, payload[key], node, key);
|
|
51
52
|
}
|
|
52
|
-
if (prop?.kind
|
|
53
|
+
if (prop?.kind === ReferenceKind.SCALAR && payload[key] != null && Object.keys(payload[key]).some(f => f in GroupOperator)) {
|
|
54
|
+
throw ValidationError.cannotUseGroupOperatorsInsideScalars(entityName, prop.name, payload);
|
|
55
|
+
}
|
|
56
|
+
if (isNotEmbedded) {
|
|
53
57
|
return this.createNode(metadata, childEntity, payload[key], node, key);
|
|
54
58
|
}
|
|
55
59
|
if (payload[key] == null) {
|
|
@@ -66,11 +70,12 @@ export class CriteriaNodeFactory {
|
|
|
66
70
|
throw ValidationError.cannotUseOperatorsInsideEmbeddables(entityName, prop.name, payload);
|
|
67
71
|
}
|
|
68
72
|
const map = Object.keys(payload[key]).reduce((oo, k) => {
|
|
69
|
-
|
|
73
|
+
const embeddedProp = prop.embeddedProps[k] ?? Object.values(prop.embeddedProps).find(p => p.name === k);
|
|
74
|
+
if (!embeddedProp && !allowedOperators.includes(k)) {
|
|
70
75
|
throw ValidationError.invalidEmbeddableQuery(entityName, k, prop.type);
|
|
71
76
|
}
|
|
72
|
-
if (
|
|
73
|
-
oo[
|
|
77
|
+
if (embeddedProp) {
|
|
78
|
+
oo[embeddedProp.name] = payload[key][k];
|
|
74
79
|
}
|
|
75
80
|
else if (typeof payload[key][k] === 'object') {
|
|
76
81
|
oo[k] = JSON.stringify(payload[key][k]);
|
|
@@ -261,7 +261,7 @@ export class NativeQueryBuilder {
|
|
|
261
261
|
}
|
|
262
262
|
if (this.options.where?.sql.trim()) {
|
|
263
263
|
this.parts.push(`where ${this.options.where.sql}`);
|
|
264
|
-
this.params.
|
|
264
|
+
this.options.where.params.forEach(p => this.params.push(p));
|
|
265
265
|
}
|
|
266
266
|
if (this.options.groupBy) {
|
|
267
267
|
const fields = this.options.groupBy.map(field => this.quote(field));
|
|
@@ -5,6 +5,7 @@ import type { ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class ObjectCriteriaNode<T extends object> extends CriteriaNode<T> {
|
|
7
7
|
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
8
|
+
isStrict(): boolean;
|
|
8
9
|
unwrap(): any;
|
|
9
10
|
willAutoJoin(qb: IQueryBuilder<T>, alias?: string, options?: ICriteriaNodeProcessOptions): boolean;
|
|
10
11
|
shouldInline(payload: any): boolean;
|