joist-core 2.2.0-next.3 → 2.2.0-next.30
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/build/BaseEntity.d.ts +2 -0
- package/build/BaseEntity.d.ts.map +1 -1
- package/build/BaseEntity.js +1 -1
- package/build/BaseEntity.js.map +1 -1
- package/build/Entity.d.ts +1 -0
- package/build/Entity.d.ts.map +1 -1
- package/build/EntityManager.d.ts +6 -2
- package/build/EntityManager.d.ts.map +1 -1
- package/build/EntityManager.js +170 -88
- package/build/EntityManager.js.map +1 -1
- package/build/EntityMetadata.d.ts +20 -1
- package/build/EntityMetadata.d.ts.map +1 -1
- package/build/EntityMetadata.js +13 -0
- package/build/EntityMetadata.js.map +1 -1
- package/build/IndexManager.d.ts +5 -5
- package/build/IndexManager.d.ts.map +1 -1
- package/build/IndexManager.js +48 -32
- package/build/IndexManager.js.map +1 -1
- package/build/InstanceData.d.ts +16 -2
- package/build/InstanceData.d.ts.map +1 -1
- package/build/InstanceData.js +36 -3
- package/build/InstanceData.js.map +1 -1
- package/build/IsLoadedCache.d.ts.map +1 -1
- package/build/IsLoadedCache.js +31 -25
- package/build/IsLoadedCache.js.map +1 -1
- package/build/JoinRows.js +1 -1
- package/build/JoinRows.js.map +1 -1
- package/build/QueryParser.collectionJoins.js +8 -2
- package/build/QueryParser.collectionJoins.js.map +1 -1
- package/build/QueryParser.d.ts +4 -2
- package/build/QueryParser.d.ts.map +1 -1
- package/build/QueryParser.js +19 -5
- package/build/QueryParser.js.map +1 -1
- package/build/QueryParser.pruning.d.ts.map +1 -1
- package/build/QueryParser.pruning.js +8 -1
- package/build/QueryParser.pruning.js.map +1 -1
- package/build/QueryParser.test.d.ts +2 -0
- package/build/QueryParser.test.d.ts.map +1 -0
- package/build/QueryParser.test.js +16 -0
- package/build/QueryParser.test.js.map +1 -0
- package/build/ReactionsManager.d.ts +2 -1
- package/build/ReactionsManager.d.ts.map +1 -1
- package/build/ReactionsManager.js +53 -49
- package/build/ReactionsManager.js.map +1 -1
- package/build/batchloaders/BatchLoader.d.ts.map +1 -1
- package/build/batchloaders/BatchLoader.js +6 -1
- package/build/batchloaders/BatchLoader.js.map +1 -1
- package/build/batchloaders/manyToManyBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/manyToManyBatchLoader.js +1 -1
- package/build/batchloaders/manyToManyBatchLoader.js.map +1 -1
- package/build/batchloaders/populateBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/populateBatchLoader.js +26 -8
- package/build/batchloaders/populateBatchLoader.js.map +1 -1
- package/build/batchloaders/recursiveChildrenBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/recursiveChildrenBatchLoader.js +2 -0
- package/build/batchloaders/recursiveChildrenBatchLoader.js.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.js +1 -3
- package/build/batchloaders/recursiveM2mBatchLoader.js.map +1 -1
- package/build/batchloaders/recursiveParentsBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/recursiveParentsBatchLoader.js +2 -0
- package/build/batchloaders/recursiveParentsBatchLoader.js.map +1 -1
- package/build/configure.d.ts +3 -3
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +65 -0
- package/build/configure.js.map +1 -1
- package/build/dataloaders/fastWhereFilterHash.d.ts +15 -0
- package/build/dataloaders/fastWhereFilterHash.d.ts.map +1 -0
- package/build/dataloaders/fastWhereFilterHash.js +164 -0
- package/build/dataloaders/fastWhereFilterHash.js.map +1 -0
- package/build/dataloaders/fastWhereFilterHash.test.d.ts +2 -0
- package/build/dataloaders/fastWhereFilterHash.test.d.ts.map +1 -0
- package/build/dataloaders/fastWhereFilterHash.test.js +59 -0
- package/build/dataloaders/fastWhereFilterHash.test.js.map +1 -0
- package/build/dataloaders/findCountDataLoader.d.ts +1 -2
- package/build/dataloaders/findCountDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findCountDataLoader.js +48 -13
- package/build/dataloaders/findCountDataLoader.js.map +1 -1
- package/build/dataloaders/findDataLoader.d.ts +10 -5
- package/build/dataloaders/findDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findDataLoader.js +109 -82
- package/build/dataloaders/findDataLoader.js.map +1 -1
- package/build/dataloaders/findIdsDataLoader.d.ts +1 -2
- package/build/dataloaders/findIdsDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findIdsDataLoader.js +16 -15
- package/build/dataloaders/findIdsDataLoader.js.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.js +3 -3
- package/build/dataloaders/findOrCreateDataLoader.js.map +1 -1
- package/build/dataloaders/findPaginatedDataLoader.d.ts +1 -2
- package/build/dataloaders/findPaginatedDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findPaginatedDataLoader.js +33 -25
- package/build/dataloaders/findPaginatedDataLoader.js.map +1 -1
- package/build/drivers/EntityWriter.js +13 -7
- package/build/drivers/EntityWriter.js.map +1 -1
- package/build/drivers/buildRawQuery.d.ts.map +1 -1
- package/build/drivers/buildRawQuery.js +5 -1
- package/build/drivers/buildRawQuery.js.map +1 -1
- package/build/fields.d.ts.map +1 -1
- package/build/fields.js +16 -6
- package/build/fields.js.map +1 -1
- package/build/keys.d.ts.map +1 -1
- package/build/keys.js +8 -6
- package/build/keys.js.map +1 -1
- package/build/loadHints.d.ts +9 -0
- package/build/loadHints.d.ts.map +1 -1
- package/build/loadHints.js +63 -9
- package/build/loadHints.js.map +1 -1
- package/build/loadLens.d.ts +11 -0
- package/build/loadLens.d.ts.map +1 -1
- package/build/loadLens.js +43 -10
- package/build/loadLens.js.map +1 -1
- package/build/newEntity.d.ts.map +1 -1
- package/build/newEntity.js +16 -14
- package/build/newEntity.js.map +1 -1
- package/build/normalizeHints.d.ts +7 -0
- package/build/normalizeHints.d.ts.map +1 -1
- package/build/normalizeHints.js +40 -2
- package/build/normalizeHints.js.map +1 -1
- package/build/relations/ManyToManyCollection.d.ts.map +1 -1
- package/build/relations/ManyToManyCollection.js +2 -2
- package/build/relations/ManyToManyCollection.js.map +1 -1
- package/build/relations/ManyToManyLargeCollection.d.ts.map +1 -1
- package/build/relations/ManyToManyLargeCollection.js +2 -1
- package/build/relations/ManyToManyLargeCollection.js.map +1 -1
- package/build/relations/OneToManyCollection.d.ts.map +1 -1
- package/build/relations/OneToManyCollection.js +2 -2
- package/build/relations/OneToManyCollection.js.map +1 -1
- package/build/relations/OneToManyLargeCollection.d.ts.map +1 -1
- package/build/relations/OneToManyLargeCollection.js +2 -1
- package/build/relations/OneToManyLargeCollection.js.map +1 -1
- package/build/relations/ReactiveManyToMany.d.ts.map +1 -1
- package/build/relations/ReactiveManyToMany.js +1 -1
- package/build/relations/ReactiveManyToMany.js.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.d.ts.map +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.js +1 -1
- package/build/relations/ReactiveManyToManyOtherSide.js.map +1 -1
- package/build/relations/RecursiveCollection.d.ts +2 -6
- package/build/relations/RecursiveCollection.d.ts.map +1 -1
- package/build/relations/RecursiveCollection.js +9 -17
- package/build/relations/RecursiveCollection.js.map +1 -1
- package/build/relations/RecursiveCycleError.d.ts +13 -0
- package/build/relations/RecursiveCycleError.d.ts.map +1 -0
- package/build/relations/RecursiveCycleError.js +15 -0
- package/build/relations/RecursiveCycleError.js.map +1 -0
- package/build/relations/hasOneThrough.d.ts.map +1 -1
- package/build/relations/hasOneThrough.js +6 -4
- package/build/relations/hasOneThrough.js.map +1 -1
- package/build/relations/hasProperty.d.ts +2 -1
- package/build/relations/hasProperty.d.ts.map +1 -1
- package/build/relations/hasProperty.js +15 -5
- package/build/relations/hasProperty.js.map +1 -1
- package/build/utils.d.ts +2 -0
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +12 -0
- package/build/utils.js.map +1 -1
- package/package.json +3 -5
- package/build/caches.d.ts +0 -6
- package/build/caches.d.ts.map +0 -1
- package/build/caches.js +0 -42
- package/build/caches.js.map +0 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fastWhereFilterHash = fastWhereFilterHash;
|
|
4
|
+
const Aliases_1 = require("../Aliases");
|
|
5
|
+
const Entity_1 = require("../Entity");
|
|
6
|
+
const relations_1 = require("../relations");
|
|
7
|
+
const temporal_1 = require("../temporal");
|
|
8
|
+
const temporalMappers_1 = require("../temporalMappers");
|
|
9
|
+
const Temporal = (0, temporal_1.maybeRequireTemporal)()?.Temporal;
|
|
10
|
+
/**
|
|
11
|
+
* Returns a fast stable key for find filters.
|
|
12
|
+
*
|
|
13
|
+
* This avoids `object-hash` for simple find filters; the phase 8 query-prep benchmark saw 1,000-query p50s drop
|
|
14
|
+
* from ~22-26ms to ~7.6-10.9ms, with heap allocation dropping from ~24-30MB to ~10-16MB.
|
|
15
|
+
*
|
|
16
|
+
* We also benchmarked native/WASM non-cryptographic hash libraries, but they only hash bytes; they still need this
|
|
17
|
+
* deterministic serialization first. For 1,000 filter keys, this helper alone had p50s of 0.337/0.353/0.410ms vs.
|
|
18
|
+
* object-hash md5 at 7.467/7.436/7.620ms, and wrapping this key with native hashes was slower: farmhash
|
|
19
|
+
* fingerprint64 at 0.517/0.524/0.538ms, @node-rs/xxhash xxh3-128 at 0.611/0.613/0.627ms, and xxhash-addon
|
|
20
|
+
* XXH128 at 1.031/1.078/1.348ms. So the stable serialization is the necessary work, and keeping it as the cache
|
|
21
|
+
* key avoids extra native-call/digest overhead and avoids introducing probabilistic hash collisions.
|
|
22
|
+
*/
|
|
23
|
+
function fastWhereFilterHash(value) {
|
|
24
|
+
return appendStableValue("", value, new WeakSet());
|
|
25
|
+
}
|
|
26
|
+
/** Appends a deterministic, type-tagged representation of `value` to `key`. */
|
|
27
|
+
function appendStableValue(key, value, seen) {
|
|
28
|
+
if (value === undefined)
|
|
29
|
+
return `${key}u;`;
|
|
30
|
+
if (value === null)
|
|
31
|
+
return `${key}n;`;
|
|
32
|
+
switch (typeof value) {
|
|
33
|
+
case "string":
|
|
34
|
+
return `${key}s${value.length}:${value};`;
|
|
35
|
+
case "number":
|
|
36
|
+
return `${key}d${value};`;
|
|
37
|
+
case "boolean":
|
|
38
|
+
return `${key}b${value ? 1 : 0};`;
|
|
39
|
+
case "bigint":
|
|
40
|
+
return `${key}i${value.toString()};`;
|
|
41
|
+
case "object":
|
|
42
|
+
return appendStableObject(key, value, seen);
|
|
43
|
+
case "function":
|
|
44
|
+
return (0, Aliases_1.isAlias)(value) ? `${key}xalias;` : undefined;
|
|
45
|
+
default:
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Appends a deterministic, type-tagged representation of `value` to `key`. */
|
|
50
|
+
function appendStableObject(key, value, seen) {
|
|
51
|
+
if (value instanceof Date)
|
|
52
|
+
return `${key}t${value.toISOString().length}:${value.toISOString()};`;
|
|
53
|
+
if (ArrayBuffer.isView(value))
|
|
54
|
+
return appendArrayBufferView(key, value);
|
|
55
|
+
if (Array.isArray(value)) {
|
|
56
|
+
if (seen.has(value))
|
|
57
|
+
return undefined;
|
|
58
|
+
seen.add(value);
|
|
59
|
+
key = `${key}a${value.length}[`;
|
|
60
|
+
for (const item of value) {
|
|
61
|
+
const nextKey = appendStableValue(key, item, seen);
|
|
62
|
+
if (nextKey === undefined) {
|
|
63
|
+
seen.delete(value);
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
key = nextKey;
|
|
67
|
+
}
|
|
68
|
+
seen.delete(value);
|
|
69
|
+
return `${key}]`;
|
|
70
|
+
}
|
|
71
|
+
if (isPlainObject(value)) {
|
|
72
|
+
if (seen.has(value))
|
|
73
|
+
return undefined;
|
|
74
|
+
seen.add(value);
|
|
75
|
+
const keys = Object.keys(value).sort();
|
|
76
|
+
key = `${key}o${keys.length}{`;
|
|
77
|
+
for (const property of keys) {
|
|
78
|
+
key = `${key}${property.length}:${property}=`;
|
|
79
|
+
const nextKey = appendStableValue(key, value[property], seen);
|
|
80
|
+
if (nextKey === undefined) {
|
|
81
|
+
seen.delete(value);
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
key = nextKey;
|
|
85
|
+
}
|
|
86
|
+
seen.delete(value);
|
|
87
|
+
return `${key}}`;
|
|
88
|
+
}
|
|
89
|
+
if ((0, Entity_1.isEntity)(value))
|
|
90
|
+
return `${key}e${value.toString().length}:${value.toString()};`;
|
|
91
|
+
const referenceKey = appendReferenceValue(key, value);
|
|
92
|
+
if (referenceKey !== undefined)
|
|
93
|
+
return referenceKey;
|
|
94
|
+
const temporalValue = toTemporalDbValue(value);
|
|
95
|
+
if (temporalValue !== undefined)
|
|
96
|
+
return appendTemporalValue(key, temporalValue);
|
|
97
|
+
const valueObjectKey = appendValueObject(key, value, seen);
|
|
98
|
+
if (valueObjectKey !== undefined)
|
|
99
|
+
return valueObjectKey;
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
/** Appends an ArrayBuffer view by its exact byte contents. */
|
|
103
|
+
function appendArrayBufferView(key, value) {
|
|
104
|
+
const bytes = Buffer.from(value.buffer, value.byteOffset, value.byteLength).toString("base64");
|
|
105
|
+
return `${key}y${value.constructor.name.length}:${value.constructor.name}:${bytes.length}:${bytes};`;
|
|
106
|
+
}
|
|
107
|
+
/** Appends a Joist reference by its tagged id. */
|
|
108
|
+
function appendReferenceValue(key, value) {
|
|
109
|
+
if (!(0, relations_1.isReference)(value))
|
|
110
|
+
return undefined;
|
|
111
|
+
const id = value.idTaggedMaybe;
|
|
112
|
+
return id === undefined ? `${key}r;` : `${key}r${id.length}:${id};`;
|
|
113
|
+
}
|
|
114
|
+
/** Appends a custom value object by constructor name and enumerable properties. */
|
|
115
|
+
function appendValueObject(key, value, seen) {
|
|
116
|
+
if (!isValueObject(value))
|
|
117
|
+
return undefined;
|
|
118
|
+
if (seen.has(value))
|
|
119
|
+
return undefined;
|
|
120
|
+
seen.add(value);
|
|
121
|
+
const constructorName = value.constructor.name;
|
|
122
|
+
const keys = Object.keys(value).sort();
|
|
123
|
+
key = `${key}c${constructorName.length}:${constructorName}:${keys.length}{`;
|
|
124
|
+
for (const property of keys) {
|
|
125
|
+
key = `${key}${property.length}:${property}=`;
|
|
126
|
+
const nextKey = appendStableValue(key, value[property], seen);
|
|
127
|
+
if (nextKey === undefined) {
|
|
128
|
+
seen.delete(value);
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
key = nextKey;
|
|
132
|
+
}
|
|
133
|
+
seen.delete(value);
|
|
134
|
+
return `${key}}`;
|
|
135
|
+
}
|
|
136
|
+
/** Appends a Temporal value as a distinct scalar type. */
|
|
137
|
+
function appendTemporalValue(key, value) {
|
|
138
|
+
return `${key}t${value.length}:${value};`;
|
|
139
|
+
}
|
|
140
|
+
/** Returns the db representation for Temporal values, or undefined for non-Temporal values. */
|
|
141
|
+
function toTemporalDbValue(value) {
|
|
142
|
+
if (!Temporal)
|
|
143
|
+
return undefined;
|
|
144
|
+
if (value instanceof Temporal.ZonedDateTime)
|
|
145
|
+
return temporalMappers_1.zonedDateTimeMapper.toDb(value);
|
|
146
|
+
if (value instanceof Temporal.PlainDateTime)
|
|
147
|
+
return temporalMappers_1.plainDateTimeMapper.toDb(value);
|
|
148
|
+
if (value instanceof Temporal.PlainDate)
|
|
149
|
+
return temporalMappers_1.plainDateMapper.toDb(value);
|
|
150
|
+
if (value instanceof Temporal.PlainTime)
|
|
151
|
+
return temporalMappers_1.plainTimeMapper.toDb(value);
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
/** Returns true for plain object literals used by find filters/settings. */
|
|
155
|
+
function isPlainObject(value) {
|
|
156
|
+
const prototype = Object.getPrototypeOf(value);
|
|
157
|
+
return prototype === Object.prototype || prototype === null;
|
|
158
|
+
}
|
|
159
|
+
/** Returns true for custom value objects that can be represented by enumerable fields. */
|
|
160
|
+
function isValueObject(value) {
|
|
161
|
+
const prototype = Object.getPrototypeOf(value);
|
|
162
|
+
return prototype !== Object.prototype && prototype !== null && Object.keys(value).length > 0;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=fastWhereFilterHash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastWhereFilterHash.js","sourceRoot":"","sources":["../../src/dataloaders/fastWhereFilterHash.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastWhereFilterHash.test.d.ts","sourceRoot":"","sources":["../../src/dataloaders/fastWhereFilterHash.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fastWhereFilterHash_1 = require("./fastWhereFilterHash");
|
|
4
|
+
describe("fastWhereFilterHash", () => {
|
|
5
|
+
it("returns stable hashes for object keys regardless of insertion order", () => {
|
|
6
|
+
const first = (0, fastWhereFilterHash_1.fastWhereFilterHash)({ b: 2, a: "one" });
|
|
7
|
+
const second = (0, fastWhereFilterHash_1.fastWhereFilterHash)({ a: "one", b: 2 });
|
|
8
|
+
expect(first).toEqual("o2{1:a=s3:one;1:b=d2;}");
|
|
9
|
+
expect(second).toEqual(first);
|
|
10
|
+
});
|
|
11
|
+
it("uses type tags to distinguish similar scalar values", () => {
|
|
12
|
+
expect([
|
|
13
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: "1" }),
|
|
14
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: 1 }),
|
|
15
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: true }),
|
|
16
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: 1n }),
|
|
17
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: null }),
|
|
18
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: undefined }),
|
|
19
|
+
]).toEqual([
|
|
20
|
+
"o1{5:value=s1:1;}",
|
|
21
|
+
"o1{5:value=d1;}",
|
|
22
|
+
"o1{5:value=b1;}",
|
|
23
|
+
"o1{5:value=i1;}",
|
|
24
|
+
"o1{5:value=n;}",
|
|
25
|
+
"o1{5:value=u;}",
|
|
26
|
+
]);
|
|
27
|
+
});
|
|
28
|
+
it("hashes nested arrays and plain objects", () => {
|
|
29
|
+
const hash = (0, fastWhereFilterHash_1.fastWhereFilterHash)({ ids: [1, 2], nested: { name: "a1" } });
|
|
30
|
+
expect(hash).toEqual("o2{3:ids=a2[d1;d2;]6:nested=o1{4:name=s2:a1;}}");
|
|
31
|
+
});
|
|
32
|
+
it("hashes date values with their db representation", () => {
|
|
33
|
+
expect((0, fastWhereFilterHash_1.fastWhereFilterHash)({ at: new Date("2020-01-02T03:04:05.000Z") })).toEqual("o1{2:at=t24:2020-01-02T03:04:05.000Z;}");
|
|
34
|
+
});
|
|
35
|
+
it("hashes byte array values by their contents", () => {
|
|
36
|
+
expect((0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: new Uint8Array([11, 22]) })).toEqual("o1{5:value=y10:Uint8Array:4:CxY=;}");
|
|
37
|
+
});
|
|
38
|
+
it("hashes custom value objects by constructor and enumerable values", () => {
|
|
39
|
+
expect((0, fastWhereFilterHash_1.fastWhereFilterHash)({ value: new SupportedValue("a1") })).toEqual("o1{5:value=c14:SupportedValue:1{4:name=s2:a1;}}");
|
|
40
|
+
});
|
|
41
|
+
it("returns undefined for unsupported object types", () => {
|
|
42
|
+
expect([
|
|
43
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)(new Map([["name", "a1"]])),
|
|
44
|
+
(0, fastWhereFilterHash_1.fastWhereFilterHash)(function unsupportedFunction() { }),
|
|
45
|
+
]).toEqual([undefined, undefined]);
|
|
46
|
+
});
|
|
47
|
+
it("returns undefined for circular structures", () => {
|
|
48
|
+
const value = { name: "a1" };
|
|
49
|
+
value.self = value;
|
|
50
|
+
expect((0, fastWhereFilterHash_1.fastWhereFilterHash)(value)).toEqual(undefined);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
class SupportedValue {
|
|
54
|
+
name;
|
|
55
|
+
constructor(name) {
|
|
56
|
+
this.name = name;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=fastWhereFilterHash.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastWhereFilterHash.test.js","sourceRoot":"","sources":["../../src/dataloaders/fastWhereFilterHash.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import DataLoader from "dataloader";
|
|
2
1
|
import { Entity } from "../Entity";
|
|
3
2
|
import { FilterAndSettings } from "../EntityFilter";
|
|
4
3
|
import { EntityManager, MaybeAbstractEntityConstructor } from "../EntityManager";
|
|
5
4
|
export declare const findCountOperation = "find-count";
|
|
6
|
-
export declare function findCountDataLoader<T extends Entity>(em: EntityManager, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T>):
|
|
5
|
+
export declare function findCountDataLoader<T extends Entity>(em: EntityManager, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T>): Promise<number>;
|
|
7
6
|
//# sourceMappingURL=findCountDataLoader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findCountDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataloaders/findCountDataLoader.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"findCountDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataloaders/findCountDataLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAoB,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAcnG,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAClD,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,8BAA8B,CAAC,CAAC,CAAC,EACvC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmFjB"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findCountOperation = void 0;
|
|
4
4
|
exports.findCountDataLoader = findCountDataLoader;
|
|
5
|
+
const EntityManager_1 = require("../EntityManager");
|
|
5
6
|
const EntityMetadata_1 = require("../EntityMetadata");
|
|
6
7
|
const keywords_1 = require("../keywords");
|
|
7
8
|
const QueryParser_1 = require("../QueryParser");
|
|
@@ -16,18 +17,22 @@ function findCountDataLoader(em, type, filter) {
|
|
|
16
17
|
}
|
|
17
18
|
const meta = (0, EntityMetadata_1.getMetadata)(type);
|
|
18
19
|
const query = (0, QueryParser_1.parseFindQuery)(meta, where, opts);
|
|
20
|
+
const pendingDeletedIds = appendPendingDeletedIds(em, type, query, meta.idDbType, where, opts);
|
|
21
|
+
const { findSettings } = em["prepareFind"](meta, exports.findCountOperation, query, { ...opts, checkLimit: false });
|
|
22
|
+
const bindings = [];
|
|
23
|
+
(0, findDataLoader_1.collectValues)(bindings, query);
|
|
24
|
+
const prepared = { filter, pendingDeletedIds, query, bindings, findSettings };
|
|
19
25
|
const batchKey = (0, findDataLoader_1.getBatchKeyFromGenericStructure)(meta, query);
|
|
20
|
-
return em
|
|
26
|
+
return em
|
|
27
|
+
.getLoader(exports.findCountOperation, batchKey, async (entries) => {
|
|
21
28
|
// We're guaranteed that these queries all have the same structure
|
|
22
29
|
// Don't bother with the CTE if there's only 1 query (or each query has exactly the same filter values)
|
|
23
|
-
if (
|
|
24
|
-
const {
|
|
25
|
-
const meta = (0, EntityMetadata_1.getMetadata)(type);
|
|
26
|
-
const query = (0, QueryParser_1.parseFindQuery)(meta, where, options);
|
|
30
|
+
if (entries.length === 1) {
|
|
31
|
+
const { query, findSettings } = entries[0];
|
|
27
32
|
const primary = query.tables.find((t) => t.join === "primary") ?? (0, utils_1.fail)("No primary");
|
|
28
33
|
query.selects = [`count(distinct ${(0, keywords_1.kq)(primary.alias)}.id) as count`];
|
|
29
34
|
query.orderBys = [];
|
|
30
|
-
const rows = await em["
|
|
35
|
+
const rows = await em["executePreparedFind"](meta, exports.findCountOperation, query, findSettings, false);
|
|
31
36
|
return [Number(rows[0].count)];
|
|
32
37
|
}
|
|
33
38
|
// WITH _find (tag, arg1, arg2) AS (
|
|
@@ -40,8 +45,7 @@ function findCountDataLoader(em, type, filter) {
|
|
|
40
45
|
// FROM author a WHERE a.first_name = _find.arg1 OR a.last_name = _find.arg2
|
|
41
46
|
// ) _data
|
|
42
47
|
// Build the list of 'arg1', 'arg2', ... strings
|
|
43
|
-
const {
|
|
44
|
-
const query = (0, QueryParser_1.parseFindQuery)((0, EntityMetadata_1.getMetadata)(type), where, options);
|
|
48
|
+
const { query, findSettings } = entries[0];
|
|
45
49
|
const argsColumns = (0, findDataLoader_1.collectAndReplaceArgs)(query);
|
|
46
50
|
argsColumns.unshift({ columnName: "tag", dbType: "int" });
|
|
47
51
|
// We're not returning the entities, just counting them...
|
|
@@ -56,19 +60,50 @@ function findCountDataLoader(em, type, filter) {
|
|
|
56
60
|
{ join: "lateral", query: query, table: meta.tableName, alias: "_data", fromAlias: "_f" },
|
|
57
61
|
],
|
|
58
62
|
// For each unique query, capture its filter values in `bindings` to populate the CTE _find table
|
|
59
|
-
ctes: [(0, unnest_1.buildUnnestCte)("_find", argsColumns, (0, findDataLoader_1.
|
|
63
|
+
ctes: [(0, unnest_1.buildUnnestCte)("_find", argsColumns, (0, findDataLoader_1.createColumnValuesFromPrepared)(argsColumns, entries))],
|
|
60
64
|
orderBys: [],
|
|
61
65
|
};
|
|
62
|
-
const rows = await em["
|
|
66
|
+
const rows = await em["executePreparedFind"](meta, exports.findCountOperation, query2, findSettings, false);
|
|
63
67
|
// Make an empty array for each batched query, per the dataloader contract
|
|
64
|
-
const results =
|
|
68
|
+
const results = entries.map(() => 0);
|
|
65
69
|
// Then put each row into the tagged query it matched
|
|
66
70
|
for (const row of rows) {
|
|
67
71
|
results[row.tag] = Number(row.count);
|
|
68
72
|
}
|
|
69
73
|
return results;
|
|
70
74
|
},
|
|
71
|
-
// Our filter/order tuple is a complex object, so
|
|
72
|
-
{
|
|
75
|
+
// Our filter/order tuple is a complex object, so use a stable cache key to ensure caching works.
|
|
76
|
+
{
|
|
77
|
+
cacheKeyFn: (entry) => {
|
|
78
|
+
// Include pendingDeletedIds so that each new em.delete => recalcs the count
|
|
79
|
+
return (0, findDataLoader_1.whereFilterHash)({ ...entry.filter, pendingDeletedIds: entry.pendingDeletedIds });
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
.load(prepared);
|
|
83
|
+
}
|
|
84
|
+
/** Adds `id not in pendingDeletedIds` to the count query so pending deletes are excluded in SQL. */
|
|
85
|
+
function appendPendingDeletedIds(em, type, query, idDbType, where, opts) {
|
|
86
|
+
const pendingDeletedIds = Object.keys(where).length === 0 && opts.conditions === undefined ? [] : (0, EntityManager_1.getEmInternalApi)(em).pendingDeleteIds(type);
|
|
87
|
+
if (pendingDeletedIds.length === 0)
|
|
88
|
+
return pendingDeletedIds;
|
|
89
|
+
const primary = query.tables.find((t) => t.join === "primary") ?? (0, utils_1.fail)("No primary");
|
|
90
|
+
const condition = {
|
|
91
|
+
kind: "column",
|
|
92
|
+
alias: primary.alias,
|
|
93
|
+
column: "id",
|
|
94
|
+
dbType: idDbType,
|
|
95
|
+
cond: { kind: "nin", value: pendingDeletedIds },
|
|
96
|
+
pruneable: true,
|
|
97
|
+
};
|
|
98
|
+
if (!query.condition) {
|
|
99
|
+
query.condition = { kind: "exp", op: "and", conditions: [condition] };
|
|
100
|
+
}
|
|
101
|
+
else if (query.condition.op === "and") {
|
|
102
|
+
query.condition.conditions.push(condition);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
query.condition = { kind: "exp", op: "and", conditions: [query.condition, condition] };
|
|
106
|
+
}
|
|
107
|
+
return pendingDeletedIds;
|
|
73
108
|
}
|
|
74
109
|
//# sourceMappingURL=findCountDataLoader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findCountDataLoader.js","sourceRoot":"","sources":["../../src/dataloaders/findCountDataLoader.ts"],"names":[],"mappings":";;;AAkBA,
|
|
1
|
+
{"version":3,"file":"findCountDataLoader.js","sourceRoot":"","sources":["../../src/dataloaders/findCountDataLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import DataLoader from "dataloader";
|
|
2
1
|
import { Entity } from "../Entity";
|
|
3
2
|
import { FilterAndSettings } from "../EntityFilter";
|
|
4
3
|
import { EntityManager, MaybeAbstractEntityConstructor } from "../EntityManager";
|
|
5
4
|
import { EntityMetadata } from "../EntityMetadata";
|
|
6
5
|
import { ParsedCteClause, ParsedFindQuery } from "../QueryParser";
|
|
7
|
-
import { optimizeCollectionJoins } from "../QueryParser.collectionJoins";
|
|
8
6
|
import { OpColumn } from "../drivers/EntityWriter";
|
|
9
7
|
import { LoadHint } from "../loadHints";
|
|
10
8
|
export declare const findOperation = "find";
|
|
11
|
-
export declare function findDataLoader<T extends Entity>(em: EntityManager, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T>, hint: LoadHint<T> | undefined):
|
|
12
|
-
export declare function whereFilterHash(where:
|
|
9
|
+
export declare function findDataLoader<T extends Entity>(em: EntityManager, type: MaybeAbstractEntityConstructor<T>, filter: FilterAndSettings<T>, hint: LoadHint<T> | undefined): Promise<T[]>;
|
|
10
|
+
export declare function whereFilterHash(where: object): any;
|
|
11
|
+
/** Filters pending-delete entities in place to avoid allocating a replacement array for the common find path. */
|
|
12
|
+
export declare function filterDeletedEntities<T extends Entity>(em: EntityManager, entities: T[]): T[];
|
|
13
13
|
/**
|
|
14
14
|
* Recursively finds args in `query` and replaces them with `_find.argX` placeholders.
|
|
15
15
|
*
|
|
@@ -19,7 +19,12 @@ export declare function collectAndReplaceArgs(query: ParsedFindQuery): {
|
|
|
19
19
|
columnName: string;
|
|
20
20
|
dbType: string;
|
|
21
21
|
}[];
|
|
22
|
-
|
|
22
|
+
/** Builds `_find` column values from already prepared queries. */
|
|
23
|
+
export declare function createColumnValuesFromPrepared(columns: OpColumn[], entries: readonly {
|
|
24
|
+
bindings: any[];
|
|
25
|
+
}[]): any[][];
|
|
26
|
+
/** Pushes the arg values of a given query in the cross-query `bindings` array. */
|
|
27
|
+
export declare function collectValues(bindings: any[], query: ParsedFindQuery): void;
|
|
23
28
|
/**
|
|
24
29
|
* Creates a `VALUES (...), (...)` SQL string for use in a CTE, typically for our
|
|
25
30
|
* batch INSERTs/UPDATEs where the CTE is how we inject N rows of data/params into
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataloaders/findDataLoader.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"findDataLoader.d.ts","sourceRoot":"","sources":["../../src/dataloaders/findDataLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,8BAA8B,EAAoB,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAEL,eAAe,EACf,eAAe,EAQhB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAMxC,eAAO,MAAM,aAAa,SAAS,CAAC;AAUpC,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,8BAA8B,CAAC,CAAC,CAAC,EACvC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC5B,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,GAC5B,OAAO,CAAC,CAAC,EAAE,CAAC,CA2Gd;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAIlD;AAED,iHAAiH;AACjH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAgB7F;AASD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAiCtG;AAaD,kEAAkE;AAClE,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS;IAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;CAAE,EAAE,GAAG,GAAG,EAAE,EAAE,CAUpH;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAc3E;AAuHD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,EACjD,IAAI,EAAE,SAAS,GAAG,EAAE,EAEpB,QAAQ,EAAE,SAAS,GAAG,EAAE,GACvB,eAAe,CAYjB;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CAUpG"}
|