@mikro-orm/knex 6.5.10-dev.10 → 6.5.10-dev.12
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/AbstractSqlDriver.js +2 -2
- package/package.json +2 -2
- package/query/ArrayCriteriaNode.d.ts +1 -0
- package/query/ArrayCriteriaNode.js +3 -0
- package/query/CriteriaNode.d.ts +3 -1
- package/query/CriteriaNode.js +6 -1
- package/query/CriteriaNodeFactory.js +1 -1
- package/query/ObjectCriteriaNode.d.ts +1 -0
- package/query/ObjectCriteriaNode.js +21 -13
- package/typings.d.ts +1 -0
package/AbstractSqlDriver.js
CHANGED
|
@@ -847,10 +847,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
847
847
|
*/
|
|
848
848
|
joinedProps(meta, populate, options) {
|
|
849
849
|
return populate.filter(hint => {
|
|
850
|
-
const [propName] = hint.field.split(':', 2);
|
|
850
|
+
const [propName, ref] = hint.field.split(':', 2);
|
|
851
851
|
const prop = meta.properties[propName] || {};
|
|
852
852
|
const strategy = (0, core_1.getLoadingStrategy)(hint.strategy || prop.strategy || options?.strategy || this.config.get('loadStrategy'), prop.kind);
|
|
853
|
-
if (
|
|
853
|
+
if (ref && [core_1.ReferenceKind.ONE_TO_ONE, core_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {
|
|
854
854
|
return true;
|
|
855
855
|
}
|
|
856
856
|
// skip redundant joins for 1:1 owner population hints when using `mapToPk`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.5.10-dev.
|
|
3
|
+
"version": "6.5.10-dev.12",
|
|
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.5.9"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.5.10-dev.
|
|
69
|
+
"@mikro-orm/core": "6.5.10-dev.12",
|
|
70
70
|
"better-sqlite3": "*",
|
|
71
71
|
"libsql": "*",
|
|
72
72
|
"mariadb": "*"
|
|
@@ -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
|
}
|
|
@@ -21,5 +21,8 @@ class ArrayCriteriaNode extends CriteriaNode_1.CriteriaNode {
|
|
|
21
21
|
return node.willAutoJoin(qb, alias, options);
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
isStrict() {
|
|
25
|
+
return this.strict || this.payload.some((node) => node.isStrict());
|
|
26
|
+
}
|
|
24
27
|
}
|
|
25
28
|
exports.ArrayCriteriaNode = ArrayCriteriaNode;
|
package/query/CriteriaNode.d.ts
CHANGED
|
@@ -11,10 +11,11 @@ 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;
|
|
@@ -25,6 +26,7 @@ export declare class CriteriaNode<T extends object> implements ICriteriaNode<T>
|
|
|
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
|
@@ -13,14 +13,16 @@ class CriteriaNode {
|
|
|
13
13
|
entityName;
|
|
14
14
|
parent;
|
|
15
15
|
key;
|
|
16
|
+
strict;
|
|
16
17
|
payload;
|
|
17
18
|
prop;
|
|
18
19
|
index;
|
|
19
|
-
constructor(metadata, entityName, parent, key, validate = true) {
|
|
20
|
+
constructor(metadata, entityName, parent, key, validate = true, strict = false) {
|
|
20
21
|
this.metadata = metadata;
|
|
21
22
|
this.entityName = entityName;
|
|
22
23
|
this.parent = parent;
|
|
23
24
|
this.key = key;
|
|
25
|
+
this.strict = strict;
|
|
24
26
|
const meta = parent && metadata.find(parent.entityName);
|
|
25
27
|
if (meta && key) {
|
|
26
28
|
const pks = core_1.Utils.splitPrimaryKeys(key);
|
|
@@ -109,6 +111,9 @@ class CriteriaNode {
|
|
|
109
111
|
aliased(field, alias) {
|
|
110
112
|
return alias ? `${alias}.${field}` : field;
|
|
111
113
|
}
|
|
114
|
+
isStrict() {
|
|
115
|
+
return this.strict;
|
|
116
|
+
}
|
|
112
117
|
/** @ignore */
|
|
113
118
|
[node_util_1.inspect.custom]() {
|
|
114
119
|
const o = {};
|
|
@@ -39,7 +39,7 @@ class CriteriaNodeFactory {
|
|
|
39
39
|
}
|
|
40
40
|
static createObjectNode(metadata, entityName, payload, parent, key) {
|
|
41
41
|
const meta = metadata.find(entityName);
|
|
42
|
-
const node = new ObjectCriteriaNode_1.ObjectCriteriaNode(metadata, entityName, parent, key);
|
|
42
|
+
const node = new ObjectCriteriaNode_1.ObjectCriteriaNode(metadata, entityName, parent, key, true, payload.__strict);
|
|
43
43
|
node.payload = Object.keys(payload).reduce((o, item) => {
|
|
44
44
|
o[item] = this.createObjectItemNode(metadata, entityName, node, payload, item, meta);
|
|
45
45
|
return o;
|
|
@@ -5,6 +5,7 @@ import type { ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings';
|
|
|
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;
|
|
@@ -61,6 +61,22 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
|
|
|
61
61
|
}
|
|
62
62
|
alias = this.autoJoin(qb, ownerAlias, options);
|
|
63
63
|
}
|
|
64
|
+
if (this.prop && nestedAlias) {
|
|
65
|
+
const toOneProperty = [core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(this.prop.kind);
|
|
66
|
+
// if the property is nullable and the filter is strict, we need to use left join, so we mimic the inner join behaviour
|
|
67
|
+
// with an exclusive condition on the join columns:
|
|
68
|
+
// - if the owning column is null, the row is missing, we don't apply the filter
|
|
69
|
+
// - if the target column is not null, the row is matched, we apply the filter
|
|
70
|
+
if (toOneProperty && this.prop.nullable && this.isStrict()) {
|
|
71
|
+
const key = this.prop.owner ? this.prop.name : this.prop.referencedPKs;
|
|
72
|
+
qb.andWhere({
|
|
73
|
+
$or: [
|
|
74
|
+
{ [ownerAlias + '.' + key]: null },
|
|
75
|
+
{ [nestedAlias + '.' + core_1.Utils.getPrimaryKeyHash(this.prop.referencedPKs)]: { $ne: null } },
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
64
80
|
return keys.reduce((o, field) => {
|
|
65
81
|
const childNode = this.payload[field];
|
|
66
82
|
const payload = childNode.process(qb, { ...options, alias: this.prop ? alias : ownerAlias });
|
|
@@ -92,6 +108,11 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
|
|
|
92
108
|
return o;
|
|
93
109
|
}, {});
|
|
94
110
|
}
|
|
111
|
+
isStrict() {
|
|
112
|
+
return this.strict || Object.keys(this.payload).some(key => {
|
|
113
|
+
return this.payload[key].isStrict();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
95
116
|
unwrap() {
|
|
96
117
|
return Object.keys(this.payload).reduce((o, field) => {
|
|
97
118
|
o[field] = this.payload[field].unwrap();
|
|
@@ -216,19 +237,6 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
|
|
|
216
237
|
? enums_1.JoinType.innerJoin
|
|
217
238
|
: enums_1.JoinType.leftJoin;
|
|
218
239
|
qb[method](field, nestedAlias, undefined, joinType, path);
|
|
219
|
-
// if the property is nullable, we need to use left join, so we mimic the inner join behaviour
|
|
220
|
-
// with an exclusive condition on the join columns:
|
|
221
|
-
// - if the owning column is null, the row is missing, we don't apply the filter
|
|
222
|
-
// - if the target column is not null, the row is matched, we apply the filter
|
|
223
|
-
if (toOneProperty && this.prop.nullable && options?.filter) {
|
|
224
|
-
const key = this.prop.owner ? this.prop.name : this.prop.referencedPKs;
|
|
225
|
-
qb.andWhere({
|
|
226
|
-
$or: [
|
|
227
|
-
{ [alias + '.' + key]: null },
|
|
228
|
-
{ [nestedAlias + '.' + core_1.Utils.getPrimaryKeyHash(this.prop.referencedPKs)]: { $ne: null } },
|
|
229
|
-
],
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
240
|
if (!qb.hasFlag(core_1.QueryFlag.INFER_POPULATE)) {
|
|
233
241
|
qb._fields = prev;
|
|
234
242
|
}
|
package/typings.d.ts
CHANGED
|
@@ -178,6 +178,7 @@ export interface ICriteriaNode<T extends object> {
|
|
|
178
178
|
readonly entityName: string;
|
|
179
179
|
readonly parent?: ICriteriaNode<T> | undefined;
|
|
180
180
|
readonly key?: string | undefined;
|
|
181
|
+
readonly strict?: boolean;
|
|
181
182
|
payload: any;
|
|
182
183
|
prop?: EntityProperty;
|
|
183
184
|
index?: number;
|