@snowtop/ent 0.2.5 → 0.2.7
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/action/action.js +5 -5
- package/action/executor.d.ts +1 -1
- package/action/executor.js +4 -4
- package/action/experimental_action.js +5 -5
- package/action/operations.js +17 -7
- package/action/orchestrator.d.ts +2 -2
- package/action/orchestrator.js +17 -7
- package/action/privacy.d.ts +2 -2
- package/action/relative_value.js +3 -3
- package/auth/auth.d.ts +0 -1
- package/auth/auth.js +4 -5
- package/core/async_utils.d.ts +1 -0
- package/core/async_utils.js +29 -0
- package/core/base.d.ts +1 -1
- package/core/base.js +5 -5
- package/core/cache_utils.d.ts +1 -0
- package/core/cache_utils.js +28 -0
- package/core/clause.js +76 -67
- package/core/config.d.ts +3 -1
- package/core/config.js +29 -9
- package/core/context.d.ts +3 -2
- package/core/context.js +96 -25
- package/core/convert.d.ts +0 -1
- package/core/convert.js +16 -17
- package/core/date.js +1 -2
- package/core/db.js +17 -7
- package/core/ent.d.ts +4 -2
- package/core/ent.js +111 -106
- package/core/global_schema.js +6 -7
- package/core/loaders/assoc_count_loader.d.ts +2 -2
- package/core/loaders/assoc_count_loader.js +18 -8
- package/core/loaders/assoc_edge_loader.d.ts +5 -2
- package/core/loaders/assoc_edge_loader.js +87 -31
- package/core/loaders/index.d.ts +2 -0
- package/core/loaders/index.js +8 -1
- package/core/loaders/loader.d.ts +33 -0
- package/core/loaders/loader.js +159 -3
- package/core/loaders/object_loader.d.ts +7 -5
- package/core/loaders/object_loader.js +97 -74
- package/core/loaders/query_loader.d.ts +2 -2
- package/core/loaders/query_loader.js +60 -24
- package/core/loaders/raw_count_loader.d.ts +4 -4
- package/core/loaders/raw_count_loader.js +34 -24
- package/core/logger.js +6 -7
- package/core/metrics.d.ts +22 -0
- package/core/metrics.js +31 -0
- package/core/privacy.d.ts +2 -2
- package/core/privacy.js +4 -5
- package/core/query/assoc_query.js +17 -7
- package/core/query/query.js +17 -7
- package/core/query/shared_assoc_test.js +1 -2
- package/core/query_impl.js +4 -5
- package/core/viewer.d.ts +2 -2
- package/graphql/graphql_field_helpers.js +22 -22
- package/graphql/mutations/union.js +1 -2
- package/graphql/node_resolver.js +7 -7
- package/graphql/query/shared_assoc_test.js +1 -2
- package/graphql/scalars/date.js +8 -3
- package/graphql/scalars/time.d.ts +1 -1
- package/imports/dataz/example1/_auth.js +14 -10
- package/imports/index.js +18 -9
- package/index.d.ts +2 -1
- package/index.js +22 -9
- package/names/names.js +61 -18
- package/package.json +14 -17
- package/parse_schema/parse.js +2 -3
- package/schema/binary_field.js +3 -3
- package/schema/field.js +45 -35
- package/schema/json_field.js +7 -7
- package/schema/schema.js +12 -12
- package/schema/struct_field.js +4 -4
- package/schema/union_field.js +3 -3
- package/scripts/custom_compiler.js +17 -7
- package/scripts/custom_graphql.js +17 -7
- package/scripts/fix_action_exports.js +17 -7
- package/scripts/move_types.js +17 -7
- package/scripts/read_schema.js +17 -7
- package/testutils/action/complex_schemas.js +28 -18
- package/testutils/builder.d.ts +1 -1
- package/testutils/builder.js +7 -7
- package/testutils/db/fixture.js +1 -2
- package/testutils/db/temp_db.js +54 -44
- package/testutils/db/value.js +3 -4
- package/testutils/db_mock.js +12 -0
- package/testutils/ent-graphql-tests/index.d.ts +3 -3
- package/testutils/ent-graphql-tests/index.js +27 -18
- package/testutils/fake_data/const.js +2 -2
- package/testutils/fake_data/fake_contact.js +20 -10
- package/testutils/fake_data/fake_event.js +20 -10
- package/testutils/fake_data/fake_tag.js +21 -11
- package/testutils/fake_data/fake_user.js +21 -11
- package/testutils/fake_data/test_helpers.js +17 -17
- package/testutils/fake_data/user_query.js +19 -9
- package/testutils/parse_sql.js +151 -43
- package/testutils/query.js +2 -3
- package/testutils/soft_delete.js +17 -7
- package/testutils/test_edge_global_schema.js +17 -7
- package/testutils/write.js +20 -11
- package/tsc/ast.js +27 -18
- package/tsc/compilerOptions.js +22 -13
- package/tsc/move_generated.js +18 -9
- package/tsc/transform.js +18 -9
- package/tsc/transform_action.js +17 -7
- package/tsc/transform_schema.js +17 -7
|
@@ -15,33 +15,59 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.ObjectLoaderFactory = exports.ObjectCountLoader = exports.ObjectLoader = void 0;
|
|
30
|
-
|
|
39
|
+
exports.ObjectLoaderFactory = exports.ObjectCountLoader = exports.ObjectLoader = exports.mapWithConcurrency = void 0;
|
|
40
|
+
exports.setClauseLoaderConcurrency = setClauseLoaderConcurrency;
|
|
31
41
|
const ent_1 = require("../ent");
|
|
42
|
+
const async_utils_1 = require("../async_utils");
|
|
43
|
+
Object.defineProperty(exports, "mapWithConcurrency", { enumerable: true, get: function () { return async_utils_1.mapWithConcurrency; } });
|
|
32
44
|
const clause = __importStar(require("../clause"));
|
|
33
45
|
const logger_1 = require("../logger");
|
|
34
46
|
const clause_1 = require("../clause");
|
|
35
47
|
const loader_1 = require("./loader");
|
|
36
48
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
49
|
+
const DEFAULT_CLAUSE_LOADER_CONCURRENCY = 10;
|
|
50
|
+
let clauseLoaderConcurrency = DEFAULT_CLAUSE_LOADER_CONCURRENCY;
|
|
51
|
+
function setClauseLoaderConcurrency(limit) {
|
|
52
|
+
if (!Number.isFinite(limit) || limit < 1) {
|
|
53
|
+
clauseLoaderConcurrency = DEFAULT_CLAUSE_LOADER_CONCURRENCY;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
clauseLoaderConcurrency = Math.floor(limit);
|
|
57
|
+
}
|
|
37
58
|
async function loadRowsForIDLoader(options, ids, context) {
|
|
38
59
|
let col = options.key;
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
const typ = options.keyType || "uuid";
|
|
61
|
+
const maxBatchSize = (0, loader_1.getLoaderMaxBatchSize)();
|
|
62
|
+
const batches = [];
|
|
63
|
+
if (maxBatchSize > 0 && ids.length > maxBatchSize) {
|
|
64
|
+
for (let i = 0; i < ids.length; i += maxBatchSize) {
|
|
65
|
+
batches.push(ids.slice(i, i + maxBatchSize));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
batches.push(ids);
|
|
70
|
+
}
|
|
45
71
|
let m = new Map();
|
|
46
72
|
let result = [];
|
|
47
73
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -49,33 +75,43 @@ async function loadRowsForIDLoader(options, ids, context) {
|
|
|
49
75
|
// store the index....
|
|
50
76
|
m.set(ids[i], i);
|
|
51
77
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
for (const batch of batches) {
|
|
79
|
+
const cls = (0, clause_1.getCombinedClause)(options, clause.DBTypeIn(col, batch, typ));
|
|
80
|
+
const rowOptions = {
|
|
81
|
+
...options,
|
|
82
|
+
clause: cls,
|
|
83
|
+
context,
|
|
84
|
+
};
|
|
85
|
+
const rows = (await (0, ent_1.loadRows)(rowOptions));
|
|
86
|
+
for (const row of rows) {
|
|
87
|
+
const id = row[col];
|
|
88
|
+
if (id === undefined) {
|
|
89
|
+
throw new Error(`need to query for column ${col} when using an object loader because the query may not be sorted and we need the id to maintain sort order`);
|
|
90
|
+
}
|
|
91
|
+
const idx = m.get(id);
|
|
92
|
+
if (idx === undefined) {
|
|
93
|
+
throw new Error(`malformed query. got ${id} back but didn't query for it`);
|
|
94
|
+
}
|
|
95
|
+
result[idx] = row;
|
|
61
96
|
}
|
|
62
|
-
result[idx] = row;
|
|
63
97
|
}
|
|
64
98
|
return result;
|
|
65
99
|
}
|
|
66
|
-
async function loadRowsForClauseLoader(options, clause) {
|
|
100
|
+
async function loadRowsForClauseLoader(options, clause, context) {
|
|
67
101
|
const rowOptions = {
|
|
68
102
|
...options,
|
|
69
103
|
// @ts-expect-error clause in LoadRowOptions doesn't take templatized version of Clause
|
|
70
104
|
clause: (0, clause_1.getCombinedClause)(options, clause, true),
|
|
105
|
+
context,
|
|
71
106
|
};
|
|
72
107
|
return (await (0, ent_1.loadRows)(rowOptions));
|
|
73
108
|
}
|
|
74
|
-
async function loadCountForClauseLoader(options, clause) {
|
|
109
|
+
async function loadCountForClauseLoader(options, clause, context) {
|
|
75
110
|
const rowOptions = {
|
|
76
111
|
...options,
|
|
77
112
|
// @ts-expect-error clause in LoadRowOptions doesn't take templatized version of Clause
|
|
78
113
|
clause: (0, clause_1.getCombinedClause)(options, clause, true),
|
|
114
|
+
context,
|
|
79
115
|
};
|
|
80
116
|
const row = await (0, ent_1.loadRow)({
|
|
81
117
|
...rowOptions,
|
|
@@ -89,19 +125,19 @@ async function loadCountForClauseLoader(options, clause) {
|
|
|
89
125
|
// optional clause...
|
|
90
126
|
// so ObjectLoaderFactory and createDataLoader need to take a new optional field which is a clause that's always added here
|
|
91
127
|
// and we need a disableTransform which skips loader completely and uses loadRow...
|
|
92
|
-
function createDataLoader(options) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
return new
|
|
128
|
+
function createDataLoader(options, context) {
|
|
129
|
+
const loaderName = `objectLoader:${options.tableName}:${options.key}`;
|
|
130
|
+
const loaderOptions = {
|
|
131
|
+
maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
|
|
132
|
+
cacheMap: (0, loader_1.createLoaderCacheMap)(options),
|
|
133
|
+
};
|
|
134
|
+
return new loader_1.InstrumentedDataLoader(loaderName, async (ids) => {
|
|
99
135
|
if (!ids.length) {
|
|
100
136
|
return [];
|
|
101
137
|
}
|
|
102
|
-
// context
|
|
103
|
-
return loadRowsForIDLoader(options, ids);
|
|
104
|
-
}, loaderOptions);
|
|
138
|
+
// pass context along so ContextCache is primed alongside DataLoader caching
|
|
139
|
+
return loadRowsForIDLoader(options, ids, context);
|
|
140
|
+
}, loaderOptions, options.tableName);
|
|
105
141
|
}
|
|
106
142
|
class clauseCacheMap {
|
|
107
143
|
constructor(options, count) {
|
|
@@ -130,35 +166,32 @@ class clauseCacheMap {
|
|
|
130
166
|
return this.m.clear();
|
|
131
167
|
}
|
|
132
168
|
}
|
|
133
|
-
function
|
|
134
|
-
return
|
|
169
|
+
function createClauseCacheMap(options, count) {
|
|
170
|
+
return (0, loader_1.createBoundedCacheMap)(new clauseCacheMap(options, count), (key) => key.instanceKey());
|
|
171
|
+
}
|
|
172
|
+
function createClauseDataLoder(options, context) {
|
|
173
|
+
const loaderName = `objectLoader:clause:${options.tableName}`;
|
|
174
|
+
return new loader_1.InstrumentedDataLoader(loaderName, async (clauses) => {
|
|
135
175
|
if (!clauses.length) {
|
|
136
176
|
return [];
|
|
137
177
|
}
|
|
138
|
-
|
|
139
|
-
for await (const clause of clauses) {
|
|
140
|
-
const data = await loadRowsForClauseLoader(options, clause);
|
|
141
|
-
ret.push(data);
|
|
142
|
-
}
|
|
143
|
-
return ret;
|
|
178
|
+
return (0, async_utils_1.mapWithConcurrency)(clauses, clauseLoaderConcurrency, (clauseItem) => loadRowsForClauseLoader(options, clauseItem, context));
|
|
144
179
|
}, {
|
|
145
|
-
cacheMap:
|
|
146
|
-
|
|
180
|
+
cacheMap: createClauseCacheMap(options),
|
|
181
|
+
maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
|
|
182
|
+
}, options.tableName, (key) => key.instanceKey());
|
|
147
183
|
}
|
|
148
|
-
function createClauseCountDataLoader(options) {
|
|
149
|
-
|
|
184
|
+
function createClauseCountDataLoader(options, context) {
|
|
185
|
+
const loaderName = `objectLoader:count:${options.tableName}`;
|
|
186
|
+
return new loader_1.InstrumentedDataLoader(loaderName, async (clauses) => {
|
|
150
187
|
if (!clauses.length) {
|
|
151
188
|
return [];
|
|
152
189
|
}
|
|
153
|
-
|
|
154
|
-
for await (const clause of clauses) {
|
|
155
|
-
const data = await loadCountForClauseLoader(options, clause);
|
|
156
|
-
ret.push(data);
|
|
157
|
-
}
|
|
158
|
-
return ret;
|
|
190
|
+
return (0, async_utils_1.mapWithConcurrency)(clauses, clauseLoaderConcurrency, (clauseItem) => loadCountForClauseLoader(options, clauseItem, context));
|
|
159
191
|
}, {
|
|
160
|
-
cacheMap:
|
|
161
|
-
|
|
192
|
+
cacheMap: createClauseCacheMap(options, true),
|
|
193
|
+
maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
|
|
194
|
+
}, options.tableName, (key) => `${key.instanceKey()}:count`);
|
|
162
195
|
}
|
|
163
196
|
class ObjectLoader {
|
|
164
197
|
constructor(options, context, toPrime) {
|
|
@@ -169,8 +202,8 @@ class ObjectLoader {
|
|
|
169
202
|
console.trace();
|
|
170
203
|
}
|
|
171
204
|
if (context) {
|
|
172
|
-
this.idLoader = createDataLoader(options);
|
|
173
|
-
this.clauseLoader = createClauseDataLoder(options);
|
|
205
|
+
this.idLoader = createDataLoader(options, context);
|
|
206
|
+
this.clauseLoader = createClauseDataLoder(options, context);
|
|
174
207
|
}
|
|
175
208
|
this.memoizedInitPrime = (0, memoizee_1.default)(this.initPrime.bind(this));
|
|
176
209
|
}
|
|
@@ -225,7 +258,7 @@ class ObjectLoader {
|
|
|
225
258
|
if (this.clauseLoader) {
|
|
226
259
|
return this.clauseLoader.load(key);
|
|
227
260
|
}
|
|
228
|
-
return loadRowsForClauseLoader(this.options, key);
|
|
261
|
+
return loadRowsForClauseLoader(this.options, key, this.context);
|
|
229
262
|
}
|
|
230
263
|
clearAll() {
|
|
231
264
|
this.idLoader && this.idLoader.clearAll();
|
|
@@ -252,12 +285,7 @@ class ObjectLoader {
|
|
|
252
285
|
// @ts-expect-error TODO?
|
|
253
286
|
return this.clauseLoader.loadMany(keys);
|
|
254
287
|
}
|
|
255
|
-
|
|
256
|
-
for await (const key of keys) {
|
|
257
|
-
const rows = await loadRowsForClauseLoader(this.options, key);
|
|
258
|
-
res.push(rows);
|
|
259
|
-
}
|
|
260
|
-
return res;
|
|
288
|
+
return (0, async_utils_1.mapWithConcurrency)(keys, clauseLoaderConcurrency, (key) => loadRowsForClauseLoader(this.options, key, this.context));
|
|
261
289
|
}
|
|
262
290
|
prime(data) {
|
|
263
291
|
// we have this data from somewhere else, prime it in the c
|
|
@@ -286,7 +314,7 @@ class ObjectCountLoader {
|
|
|
286
314
|
this.options = options;
|
|
287
315
|
this.context = context;
|
|
288
316
|
if (context) {
|
|
289
|
-
this.loader = createClauseCountDataLoader(options);
|
|
317
|
+
this.loader = createClauseCountDataLoader(options, context);
|
|
290
318
|
}
|
|
291
319
|
}
|
|
292
320
|
getOptions() {
|
|
@@ -296,7 +324,7 @@ class ObjectCountLoader {
|
|
|
296
324
|
if (this.loader) {
|
|
297
325
|
return this.loader.load(key);
|
|
298
326
|
}
|
|
299
|
-
return loadCountForClauseLoader(this.options, key);
|
|
327
|
+
return loadCountForClauseLoader(this.options, key, this.context);
|
|
300
328
|
}
|
|
301
329
|
clearAll() {
|
|
302
330
|
this.loader && this.loader.clearAll();
|
|
@@ -309,12 +337,7 @@ class ObjectCountLoader {
|
|
|
309
337
|
// @ts-expect-error
|
|
310
338
|
return this.loader.loadMany(keys);
|
|
311
339
|
}
|
|
312
|
-
|
|
313
|
-
for await (const key of keys) {
|
|
314
|
-
const r = await loadCountForClauseLoader(this.options, key);
|
|
315
|
-
res.push(r);
|
|
316
|
-
}
|
|
317
|
-
return res;
|
|
340
|
+
return (0, async_utils_1.mapWithConcurrency)(keys, clauseLoaderConcurrency, (key) => loadCountForClauseLoader(this.options, key, this.context));
|
|
318
341
|
}
|
|
319
342
|
}
|
|
320
343
|
exports.ObjectCountLoader = ObjectCountLoader;
|
|
@@ -5,10 +5,10 @@ import { ObjectLoaderFactory } from "./object_loader";
|
|
|
5
5
|
declare class QueryDirectLoader<K extends any> implements Loader<K, Data[]> {
|
|
6
6
|
private options;
|
|
7
7
|
private queryOptions?;
|
|
8
|
-
context?: Context
|
|
8
|
+
context?: Context | undefined;
|
|
9
9
|
private memoizedInitPrime;
|
|
10
10
|
private primedLoaders;
|
|
11
|
-
constructor(options: QueryOptions, queryOptions?:
|
|
11
|
+
constructor(options: QueryOptions, queryOptions?: EdgeQueryableDataOptions | undefined, context?: Context | undefined);
|
|
12
12
|
private initPrime;
|
|
13
13
|
load(id: K): Promise<Data[]>;
|
|
14
14
|
clearAll(): void;
|
|
@@ -15,23 +15,32 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
39
|
exports.QueryLoaderFactory = void 0;
|
|
30
|
-
const dataloader_1 = __importDefault(require("dataloader"));
|
|
31
40
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
32
41
|
const clause = __importStar(require("../clause"));
|
|
33
42
|
const ent_1 = require("../ent");
|
|
34
|
-
const
|
|
43
|
+
const cache_utils_1 = require("../cache_utils");
|
|
35
44
|
const loader_1 = require("./loader");
|
|
36
45
|
function getOrderByLocal(options, queryOptions) {
|
|
37
46
|
return (options.orderby ??
|
|
@@ -42,7 +51,7 @@ function getOrderByLocal(options, queryOptions) {
|
|
|
42
51
|
},
|
|
43
52
|
]);
|
|
44
53
|
}
|
|
45
|
-
async function simpleCase(options, id, queryOptions) {
|
|
54
|
+
async function simpleCase(options, id, queryOptions, context) {
|
|
46
55
|
let cls;
|
|
47
56
|
if (options.groupCol) {
|
|
48
57
|
cls = clause.Eq(options.groupCol, id);
|
|
@@ -65,22 +74,27 @@ async function simpleCase(options, id, queryOptions) {
|
|
|
65
74
|
clause: cls,
|
|
66
75
|
orderby: getOrderByLocal(options, queryOptions),
|
|
67
76
|
limit: queryOptions?.limit || (0, ent_1.getDefaultLimit)(),
|
|
77
|
+
context,
|
|
68
78
|
});
|
|
69
79
|
}
|
|
70
|
-
function createLoader(options, queryOptions) {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
function createLoader(options, queryOptions, context) {
|
|
81
|
+
const loaderName = options.groupCol
|
|
82
|
+
? `queryLoader:${options.tableName}:${options.groupCol}`
|
|
83
|
+
: options.clause
|
|
84
|
+
? `queryLoader:${options.tableName}:${options.clause.instanceKey()}`
|
|
85
|
+
: `queryLoader:${options.tableName}`;
|
|
86
|
+
const loaderOptions = {
|
|
87
|
+
maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
|
|
88
|
+
cacheMap: (0, loader_1.createLoaderCacheMap)(options),
|
|
89
|
+
};
|
|
90
|
+
return new loader_1.InstrumentedDataLoader(loaderName, async (keys) => {
|
|
77
91
|
if (!keys.length) {
|
|
78
92
|
return [];
|
|
79
93
|
}
|
|
80
94
|
// keep query simple if we're only fetching for one id
|
|
81
95
|
// or can't group because no groupCol...
|
|
82
96
|
if (keys.length == 1 || !options.groupCol) {
|
|
83
|
-
const rows = await simpleCase(options, keys[0], queryOptions);
|
|
97
|
+
const rows = await simpleCase(options, keys[0], queryOptions, context);
|
|
84
98
|
return [rows];
|
|
85
99
|
}
|
|
86
100
|
let m = new Map();
|
|
@@ -121,7 +135,7 @@ function createLoader(options, queryOptions) {
|
|
|
121
135
|
result[idx].push(row);
|
|
122
136
|
}
|
|
123
137
|
return result;
|
|
124
|
-
}, loaderOptions);
|
|
138
|
+
}, loaderOptions, options.tableName);
|
|
125
139
|
}
|
|
126
140
|
class QueryDirectLoader {
|
|
127
141
|
constructor(options, queryOptions, context) {
|
|
@@ -145,7 +159,7 @@ class QueryDirectLoader {
|
|
|
145
159
|
this.primedLoaders = primedLoaders;
|
|
146
160
|
}
|
|
147
161
|
async load(id) {
|
|
148
|
-
const rows = await simpleCase(this.options, id, this.queryOptions);
|
|
162
|
+
const rows = await simpleCase(this.options, id, this.queryOptions, this.context);
|
|
149
163
|
if (this.context) {
|
|
150
164
|
this.memoizedInitPrime();
|
|
151
165
|
if (this.primedLoaders) {
|
|
@@ -171,7 +185,7 @@ class QueryLoader {
|
|
|
171
185
|
this.context = context;
|
|
172
186
|
this.queryOptions = queryOptions;
|
|
173
187
|
if (context) {
|
|
174
|
-
this.loader = createLoader(options, queryOptions);
|
|
188
|
+
this.loader = createLoader(options, queryOptions, context);
|
|
175
189
|
}
|
|
176
190
|
this.memoizedInitPrime = (0, memoizee_1.default)(this.initPrime.bind(this));
|
|
177
191
|
}
|
|
@@ -205,7 +219,7 @@ class QueryLoader {
|
|
|
205
219
|
}
|
|
206
220
|
return rows;
|
|
207
221
|
}
|
|
208
|
-
return simpleCase(this.options, id, this.queryOptions);
|
|
222
|
+
return simpleCase(this.options, id, this.queryOptions, this.context);
|
|
209
223
|
}
|
|
210
224
|
clearAll() {
|
|
211
225
|
this.loader && this.loader.clearAll();
|
|
@@ -231,10 +245,32 @@ class QueryLoaderFactory {
|
|
|
231
245
|
return QueryLoaderFactory.createConfigurableLoader(this.name, this.options, options, context);
|
|
232
246
|
}
|
|
233
247
|
static createConfigurableLoader(name, queryOptions, options, context) {
|
|
234
|
-
if (
|
|
248
|
+
if (!context) {
|
|
235
249
|
return new QueryDirectLoader(queryOptions, options, context);
|
|
236
250
|
}
|
|
237
|
-
|
|
251
|
+
if (options.clause) {
|
|
252
|
+
const effectiveOrderBy = getOrderByLocal(queryOptions, options);
|
|
253
|
+
const effectiveLimit = options.limit || (0, ent_1.getDefaultLimit)();
|
|
254
|
+
const disableTransformations = options.disableTransformations ?? false;
|
|
255
|
+
const keyParts = [
|
|
256
|
+
name,
|
|
257
|
+
`clause:${options.clause.instanceKey()}`,
|
|
258
|
+
queryOptions.clause
|
|
259
|
+
? `baseClause:${queryOptions.clause.instanceKey()}`
|
|
260
|
+
: undefined,
|
|
261
|
+
`limit:${effectiveLimit}`,
|
|
262
|
+
`orderby:${(0, cache_utils_1.stableStringify)(effectiveOrderBy)}`,
|
|
263
|
+
`disableTransformations:${disableTransformations}`,
|
|
264
|
+
];
|
|
265
|
+
const key = keyParts
|
|
266
|
+
.filter((part) => Boolean(part))
|
|
267
|
+
.join(":");
|
|
268
|
+
return (0, loader_1.getCustomLoader)(key, () => new QueryDirectLoader(queryOptions, options, context), context);
|
|
269
|
+
}
|
|
270
|
+
const effectiveOrderBy = getOrderByLocal(queryOptions, options);
|
|
271
|
+
const effectiveLimit = options.limit || (0, ent_1.getDefaultLimit)();
|
|
272
|
+
const disableTransformations = options.disableTransformations ?? false;
|
|
273
|
+
const key = `${name}:limit:${effectiveLimit}:orderby:${(0, cache_utils_1.stableStringify)(effectiveOrderBy)}:disableTransformations:${disableTransformations}`;
|
|
238
274
|
return (0, loader_1.getCustomLoader)(key, () => new QueryLoader(queryOptions, context, options), context);
|
|
239
275
|
}
|
|
240
276
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import DataLoader from "dataloader";
|
|
2
1
|
import { ID, Context, Loader, LoaderFactory, SelectBaseDataOptions } from "../base";
|
|
3
2
|
import * as clause from "../clause";
|
|
3
|
+
import { InstrumentedDataLoader } from "./loader";
|
|
4
4
|
interface QueryCountOptions {
|
|
5
5
|
tableName: string;
|
|
6
6
|
groupCol?: string;
|
|
7
7
|
groupColType?: string;
|
|
8
8
|
clause?: clause.Clause;
|
|
9
9
|
}
|
|
10
|
-
export declare function createCountDataLoader<K extends any>(options: QueryCountOptions):
|
|
10
|
+
export declare function createCountDataLoader<K extends any>(options: QueryCountOptions, context?: Context): InstrumentedDataLoader<K, number>;
|
|
11
11
|
export declare class RawCountLoader<K extends any> implements Loader<K, number> {
|
|
12
12
|
private options;
|
|
13
|
-
context?: Context
|
|
13
|
+
context?: Context | undefined;
|
|
14
14
|
private loader;
|
|
15
|
-
constructor(options: QueryCountOptions, context?: Context
|
|
15
|
+
constructor(options: QueryCountOptions, context?: Context | undefined);
|
|
16
16
|
load(id: K): Promise<number>;
|
|
17
17
|
clearAll(): void;
|
|
18
18
|
}
|
|
@@ -15,22 +15,28 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
28
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.RawCountLoaderFactory = exports.RawCountLoader =
|
|
30
|
-
|
|
36
|
+
exports.RawCountLoaderFactory = exports.RawCountLoader = void 0;
|
|
37
|
+
exports.createCountDataLoader = createCountDataLoader;
|
|
31
38
|
const ent_1 = require("../ent");
|
|
32
39
|
const clause = __importStar(require("../clause"));
|
|
33
|
-
const logger_1 = require("../logger");
|
|
34
40
|
const loader_1 = require("./loader");
|
|
35
41
|
async function simpleCase(options, key, context) {
|
|
36
42
|
let cls;
|
|
@@ -55,19 +61,23 @@ async function simpleCase(options, key, context) {
|
|
|
55
61
|
});
|
|
56
62
|
return [parseInt(row?.count, 10) || 0];
|
|
57
63
|
}
|
|
58
|
-
function createCountDataLoader(options) {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
function createCountDataLoader(options, context) {
|
|
65
|
+
const loaderName = options.groupCol
|
|
66
|
+
? `rawCountLoader:${options.tableName}:${options.groupCol}`
|
|
67
|
+
: options.clause
|
|
68
|
+
? `rawCountLoader:${options.tableName}:${options.clause.instanceKey()}`
|
|
69
|
+
: `rawCountLoader:${options.tableName}`;
|
|
70
|
+
const loaderOptions = {
|
|
71
|
+
maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
|
|
72
|
+
cacheMap: (0, loader_1.createLoaderCacheMap)(options),
|
|
73
|
+
};
|
|
74
|
+
return new loader_1.InstrumentedDataLoader(loaderName, async (keys) => {
|
|
65
75
|
if (!keys.length) {
|
|
66
76
|
return [];
|
|
67
77
|
}
|
|
68
78
|
// keep query simple if we're only fetching for one id
|
|
69
79
|
if (keys.length == 1 || !options.groupCol) {
|
|
70
|
-
return simpleCase(options, keys[0]);
|
|
80
|
+
return simpleCase(options, keys[0], context);
|
|
71
81
|
}
|
|
72
82
|
let typ = options.groupColType || "uuid";
|
|
73
83
|
let cls = clause.DBTypeIn(options.groupCol, keys, typ);
|
|
@@ -86,6 +96,7 @@ function createCountDataLoader(options) {
|
|
|
86
96
|
fields: ["count(1) as count", options.groupCol],
|
|
87
97
|
groupby: options.groupCol,
|
|
88
98
|
clause: cls,
|
|
99
|
+
context,
|
|
89
100
|
};
|
|
90
101
|
const rows = await (0, ent_1.loadRows)(rowOptions);
|
|
91
102
|
for (const row of rows) {
|
|
@@ -97,9 +108,8 @@ function createCountDataLoader(options) {
|
|
|
97
108
|
result[idx] = parseInt(row.count, 10);
|
|
98
109
|
}
|
|
99
110
|
return result;
|
|
100
|
-
}, loaderOptions);
|
|
111
|
+
}, loaderOptions, options.tableName);
|
|
101
112
|
}
|
|
102
|
-
exports.createCountDataLoader = createCountDataLoader;
|
|
103
113
|
// for now this only works for single column counts
|
|
104
114
|
// e.g. foreign key count
|
|
105
115
|
class RawCountLoader {
|
|
@@ -108,7 +118,7 @@ class RawCountLoader {
|
|
|
108
118
|
this.options = options;
|
|
109
119
|
this.context = context;
|
|
110
120
|
if (context && options.groupCol) {
|
|
111
|
-
this.loader = createCountDataLoader(options);
|
|
121
|
+
this.loader = createCountDataLoader(options, context);
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
124
|
async load(id) {
|
package/core/logger.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.setLogLevels = setLogLevels;
|
|
4
|
+
exports.clearLogLevels = clearLogLevels;
|
|
5
|
+
exports.log = log;
|
|
6
|
+
exports.logIf = logIf;
|
|
7
|
+
exports.logTrace = logTrace;
|
|
8
|
+
exports.logEnabled = logEnabled;
|
|
4
9
|
var m = {
|
|
5
10
|
query: "log",
|
|
6
11
|
warn: "warn",
|
|
@@ -16,11 +21,9 @@ function setLogLevels(levels) {
|
|
|
16
21
|
}
|
|
17
22
|
levels.forEach((level) => logLevels.set(level, true));
|
|
18
23
|
}
|
|
19
|
-
exports.setLogLevels = setLogLevels;
|
|
20
24
|
function clearLogLevels() {
|
|
21
25
|
logLevels.clear();
|
|
22
26
|
}
|
|
23
|
-
exports.clearLogLevels = clearLogLevels;
|
|
24
27
|
function log(level, msg) {
|
|
25
28
|
if (logLevels.has(level)) {
|
|
26
29
|
// mostly for sqlite error but fine for any type of error
|
|
@@ -32,20 +35,16 @@ function log(level, msg) {
|
|
|
32
35
|
console[m[level]](msg);
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
|
-
exports.log = log;
|
|
36
38
|
function logIf(level, logFn) {
|
|
37
39
|
if (logLevels.has(level)) {
|
|
38
40
|
console[m[level]](logFn());
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
|
-
exports.logIf = logIf;
|
|
42
43
|
function logTrace() {
|
|
43
44
|
if (logLevels.has("debug")) {
|
|
44
45
|
console.trace();
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
exports.logTrace = logTrace;
|
|
48
48
|
function logEnabled(level) {
|
|
49
49
|
return logLevels.has(level);
|
|
50
50
|
}
|
|
51
|
-
exports.logEnabled = logEnabled;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type DataLoaderBatchMetrics = {
|
|
2
|
+
loaderName: string;
|
|
3
|
+
batchSize: number;
|
|
4
|
+
};
|
|
5
|
+
export type DataLoaderCacheHitMetrics = {
|
|
6
|
+
tableName: string;
|
|
7
|
+
key: unknown;
|
|
8
|
+
};
|
|
9
|
+
export type QueryCacheHitMetrics = {
|
|
10
|
+
tableName: string;
|
|
11
|
+
key: string;
|
|
12
|
+
};
|
|
13
|
+
export type MetricsHook = {
|
|
14
|
+
onDataLoaderBatch?: (info: DataLoaderBatchMetrics) => void;
|
|
15
|
+
onDataLoaderCacheHit?: (info: DataLoaderCacheHitMetrics) => void;
|
|
16
|
+
onQueryCacheHit?: (info: QueryCacheHitMetrics) => void;
|
|
17
|
+
};
|
|
18
|
+
export declare function setMetricsHook(hooks?: MetricsHook | null): void;
|
|
19
|
+
export declare function getMetricsHook(): MetricsHook;
|
|
20
|
+
export declare function getOnDataLoaderBatch(): ((info: DataLoaderBatchMetrics) => void) | undefined;
|
|
21
|
+
export declare function getOnDataLoaderCacheHit(): ((info: DataLoaderCacheHitMetrics) => void) | undefined;
|
|
22
|
+
export declare function getOnQueryCacheHit(): ((info: QueryCacheHitMetrics) => void) | undefined;
|