@travetto/model-query 8.0.2 → 8.0.3
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/README.md +7 -6
- package/package.json +3 -3
- package/src/types/aggregate.ts +7 -0
- package/src/types/query.ts +0 -6
- package/support/test/crud.ts +17 -11
- package/support/test/polymorphism.ts +8 -6
- package/support/test/query.ts +21 -20
package/README.md
CHANGED
|
@@ -36,12 +36,6 @@ export interface ModelQuerySupport {
|
|
|
36
36
|
* @param failOnMany Should the query fail on more than one result found, defaults to true
|
|
37
37
|
*/
|
|
38
38
|
queryOne<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>, failOnMany?: boolean): Promise<T>;
|
|
39
|
-
/**
|
|
40
|
-
* Find the count of matching documents by query.
|
|
41
|
-
* @param cls The model class
|
|
42
|
-
* @param query The query to count for
|
|
43
|
-
*/
|
|
44
|
-
queryCount<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number>;
|
|
45
39
|
}
|
|
46
40
|
```
|
|
47
41
|
|
|
@@ -150,6 +144,13 @@ export interface ModelQueryAggregateSupport extends ModelQuerySupport {
|
|
|
150
144
|
field: F,
|
|
151
145
|
query?: ModelQuery<T>
|
|
152
146
|
): Promise<AggregateResultType<T, F>>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Find the count of matching documents by query.
|
|
150
|
+
* @param cls The model class
|
|
151
|
+
* @param query The query to count for
|
|
152
|
+
*/
|
|
153
|
+
countByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number>;
|
|
153
154
|
}
|
|
154
155
|
```
|
|
155
156
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-query",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.3",
|
|
4
4
|
"description": "Datastore abstraction for advanced query support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"datastore",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@travetto/di": "^8.0.1",
|
|
34
|
-
"@travetto/model": "^8.0.
|
|
34
|
+
"@travetto/model": "^8.0.3",
|
|
35
35
|
"@travetto/schema": "^8.0.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@travetto/test": "^8.0.
|
|
38
|
+
"@travetto/test": "^8.0.2"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/test": {
|
package/src/types/aggregate.ts
CHANGED
|
@@ -45,4 +45,11 @@ export interface ModelQueryAggregateSupport extends ModelQuerySupport {
|
|
|
45
45
|
field: F,
|
|
46
46
|
query?: ModelQuery<T>
|
|
47
47
|
): Promise<AggregateResultType<T, F>>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Find the count of matching documents by query.
|
|
51
|
+
* @param cls The model class
|
|
52
|
+
* @param query The query to count for
|
|
53
|
+
*/
|
|
54
|
+
countByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number>;
|
|
48
55
|
}
|
package/src/types/query.ts
CHANGED
|
@@ -21,10 +21,4 @@ export interface ModelQuerySupport {
|
|
|
21
21
|
* @param failOnMany Should the query fail on more than one result found, defaults to true
|
|
22
22
|
*/
|
|
23
23
|
queryOne<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>, failOnMany?: boolean): Promise<T>;
|
|
24
|
-
/**
|
|
25
|
-
* Find the count of matching documents by query.
|
|
26
|
-
* @param cls The model class
|
|
27
|
-
* @param query The query to count for
|
|
28
|
-
*/
|
|
29
|
-
queryCount<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number>;
|
|
30
24
|
}
|
package/support/test/crud.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
|
|
3
|
-
import { Model, type ModelCrudSupport, NotFoundError, UniqueError } from '@travetto/model';
|
|
4
|
-
import { castTo } from '@travetto/runtime';
|
|
3
|
+
import { Model, type ModelCrudSupport, type ModelType, NotFoundError, UniqueError } from '@travetto/model';
|
|
4
|
+
import { castTo, type Class } from '@travetto/runtime';
|
|
5
5
|
import { Suite, Test } from '@travetto/test';
|
|
6
6
|
|
|
7
7
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import type { WhereClause } from '../../__index__.ts';
|
|
10
|
+
import { QueryIndex } from '../../src/model/indexes.ts';
|
|
10
11
|
import type { ModelQueryCrudSupport } from '../../src/types/crud.ts';
|
|
11
12
|
import { Address, BigIntModel, Person, Todo } from './model.ts';
|
|
12
13
|
|
|
@@ -25,6 +26,11 @@ class UniqueUser2 {
|
|
|
25
26
|
export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudSupport & ModelCrudSupport> {
|
|
26
27
|
supportsUniqueIndexes = true;
|
|
27
28
|
|
|
29
|
+
async countByQuery<T extends ModelType>(cls: Class<T>, query: WhereClause<T>): Promise<number> {
|
|
30
|
+
const svc = await this.service;
|
|
31
|
+
return svc.query(cls, { where: query, limit: 10000 }).then(v => v.length);
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
@Test({ skip: self => !castTo<ModelQueryCrudSuite>(self).supportsUniqueIndexes })
|
|
29
35
|
async testUnique() {
|
|
30
36
|
const svc = await this.service;
|
|
@@ -147,13 +153,13 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
147
153
|
|
|
148
154
|
assert(c === 2);
|
|
149
155
|
|
|
150
|
-
assert((await
|
|
156
|
+
assert((await this.countByQuery(Person, {})) === 3);
|
|
151
157
|
|
|
152
158
|
const c2 = await svc.deleteByQuery(Person, { where: { age: { $lte: 3 } } });
|
|
153
159
|
|
|
154
160
|
assert(c2 === 3);
|
|
155
161
|
|
|
156
|
-
assert((await
|
|
162
|
+
assert((await this.countByQuery(Person, {})) === 0);
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
@Test()
|
|
@@ -177,7 +183,7 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
177
183
|
|
|
178
184
|
assert(count === 5);
|
|
179
185
|
|
|
180
|
-
assert((await
|
|
186
|
+
assert((await this.countByQuery(Person, { gender: 'm' })) === 5);
|
|
181
187
|
|
|
182
188
|
const c = await svc.updatePartialByQuery(Person, { where: { age: { $gt: 3 } } }, { gender: 'f' });
|
|
183
189
|
|
|
@@ -185,14 +191,14 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
185
191
|
|
|
186
192
|
assert(c === 2);
|
|
187
193
|
|
|
188
|
-
assert((await
|
|
194
|
+
assert((await this.countByQuery(Person, { gender: 'm' })) === 3);
|
|
189
195
|
|
|
190
196
|
const c2 = await svc.updatePartialByQuery(Person, { where: { gender: 'm' } }, { gender: 'f' });
|
|
191
197
|
|
|
192
198
|
assert(c2 === 3);
|
|
193
199
|
|
|
194
|
-
assert((await
|
|
195
|
-
assert((await
|
|
200
|
+
assert((await this.countByQuery(Person, { gender: 'f' })) === 5);
|
|
201
|
+
assert((await this.countByQuery(Person, { gender: 'm' })) === 0);
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
@Test()
|
|
@@ -237,7 +243,7 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
237
243
|
assert(withOptional.every(x => x.optionalBigInt !== undefined));
|
|
238
244
|
|
|
239
245
|
// Test count with bigint condition
|
|
240
|
-
const countResult = await
|
|
246
|
+
const countResult = await this.countByQuery(BigIntModel, { largeNumber: { $gte: 1000n } });
|
|
241
247
|
assert(countResult === 2);
|
|
242
248
|
}
|
|
243
249
|
|
|
@@ -285,7 +291,7 @@ export abstract class ModelQueryCrudSuite extends BaseModelSuite<ModelQueryCrudS
|
|
|
285
291
|
assert(deleted === 2);
|
|
286
292
|
|
|
287
293
|
// Verify deletions
|
|
288
|
-
const remaining = await
|
|
294
|
+
const remaining = await this.countByQuery(BigIntModel, {});
|
|
289
295
|
assert(remaining === 3);
|
|
290
296
|
|
|
291
297
|
const all = await svc.query(BigIntModel, {});
|
|
@@ -18,7 +18,9 @@ import { ModelQueryFacetUtil } from '../../src/util/facet.ts';
|
|
|
18
18
|
import { ModelQuerySuggestUtil } from '../../src/util/suggest.ts';
|
|
19
19
|
|
|
20
20
|
@Suite()
|
|
21
|
-
export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<
|
|
21
|
+
export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<
|
|
22
|
+
ModelQuerySupport & ModelQueryAggregateSupport & ModelCrudSupport
|
|
23
|
+
> {
|
|
22
24
|
@Test()
|
|
23
25
|
async testQuery() {
|
|
24
26
|
const svc = await this.service;
|
|
@@ -36,9 +38,9 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
36
38
|
assert((await svc.query(Doctor, {})).length === 2);
|
|
37
39
|
assert((await svc.query(Engineer, {})).length === 1);
|
|
38
40
|
|
|
39
|
-
assert((await svc.
|
|
40
|
-
assert((await svc.
|
|
41
|
-
assert((await svc.
|
|
41
|
+
assert((await svc.countByQuery(Worker, { where: { name: 'bob' } })) === 1);
|
|
42
|
+
assert((await svc.countByQuery(Doctor, { where: { name: 'bob' } })) === 1);
|
|
43
|
+
assert((await svc.countByQuery(Engineer, { where: { name: 'bob' } })) === 0);
|
|
42
44
|
|
|
43
45
|
assert((await svc.queryOne(Worker, { where: { name: 'bob' } })) instanceof Doctor);
|
|
44
46
|
await assert.rejects(() => svc.queryOne(Firefighter, { where: { name: 'bob' } }), NotFoundError);
|
|
@@ -46,7 +48,7 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
46
48
|
|
|
47
49
|
@Test({ skip: ModelQueryPolymorphismSuite.ifNot(ModelQueryCrudUtil.isSupported) })
|
|
48
50
|
async testCrudQuery() {
|
|
49
|
-
const svc: ModelQueryCrudSupport & ModelQuerySupport = castTo(await this.service);
|
|
51
|
+
const svc: ModelQueryCrudSupport & ModelQueryAggregateSupport & ModelQuerySupport = castTo(await this.service);
|
|
50
52
|
const [doc, doc2, fire, eng] = [
|
|
51
53
|
Doctor.from({ name: 'bob', specialty: 'feet' }),
|
|
52
54
|
Doctor.from({ name: 'nob', specialty: 'eyes' }),
|
|
@@ -60,7 +62,7 @@ export abstract class ModelQueryPolymorphismSuite extends BaseModelSuite<ModelQu
|
|
|
60
62
|
const c = await svc.updatePartialByQuery(Doctor, { where: { specialty: 'feet' } }, { specialty: 'eyes' });
|
|
61
63
|
assert(c === 1);
|
|
62
64
|
|
|
63
|
-
assert((await svc.
|
|
65
|
+
assert((await svc.countByQuery(Doctor, { where: { specialty: 'eyes' } })) === 2);
|
|
64
66
|
|
|
65
67
|
const removed = await svc.deleteByQuery(Worker, { where: { name: 'rob' } });
|
|
66
68
|
|
package/support/test/query.ts
CHANGED
|
@@ -6,11 +6,12 @@ import { Suite, Test } from '@travetto/test';
|
|
|
6
6
|
|
|
7
7
|
import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
8
8
|
|
|
9
|
+
import type { ModelQueryAggregateSupport } from '../../__index__.ts';
|
|
9
10
|
import type { ModelQuerySupport } from '../../src/types/query.ts';
|
|
10
11
|
import { Aged, Location, Names, Note, Person, PersonFamily, Recipe, SimpleList, WithNestedLists, WithNestedNestedLists } from './model.ts';
|
|
11
12
|
|
|
12
13
|
@Suite()
|
|
13
|
-
export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelCrudSupport> {
|
|
14
|
+
export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport & ModelQueryAggregateSupport & ModelCrudSupport> {
|
|
14
15
|
supportsGeo = true;
|
|
15
16
|
|
|
16
17
|
@Test()
|
|
@@ -38,7 +39,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
38
39
|
const one2 = await svc.queryOne(Person, { where: { id: { $eq: people[0].id } } });
|
|
39
40
|
assert(one2.id === people[0].id);
|
|
40
41
|
|
|
41
|
-
const none = await svc.
|
|
42
|
+
const none = await svc.countByQuery(Person, { where: { id: { $ne: people[0].id } } });
|
|
42
43
|
assert(none === 3);
|
|
43
44
|
|
|
44
45
|
const noneIds = await svc.query(Person, { where: { id: { $ne: people[0].id } } });
|
|
@@ -331,7 +332,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
331
332
|
|
|
332
333
|
await this.saveAll(Location, toAdd);
|
|
333
334
|
|
|
334
|
-
assert((await svc.
|
|
335
|
+
assert((await svc.countByQuery(Location, {})) === 25);
|
|
335
336
|
|
|
336
337
|
const result = await svc.query(Location, {
|
|
337
338
|
limit: 100,
|
|
@@ -382,7 +383,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
382
383
|
})
|
|
383
384
|
);
|
|
384
385
|
|
|
385
|
-
const out = await service.
|
|
386
|
+
const out = await service.countByQuery(Note, {
|
|
386
387
|
where: {
|
|
387
388
|
entities: {
|
|
388
389
|
id
|
|
@@ -413,7 +414,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
413
414
|
)
|
|
414
415
|
);
|
|
415
416
|
|
|
416
|
-
const simple = await service.
|
|
417
|
+
const simple = await service.countByQuery(Aged, {
|
|
417
418
|
where: {
|
|
418
419
|
createdAt: {
|
|
419
420
|
$gt: new Date()
|
|
@@ -422,7 +423,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
422
423
|
});
|
|
423
424
|
assert(simple === 5);
|
|
424
425
|
|
|
425
|
-
const simple2 = await service.
|
|
426
|
+
const simple2 = await service.countByQuery(Aged, {
|
|
426
427
|
where: {
|
|
427
428
|
createdAt: {
|
|
428
429
|
$gt: '-1d'
|
|
@@ -431,7 +432,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
431
432
|
});
|
|
432
433
|
assert(simple2 === 6);
|
|
433
434
|
|
|
434
|
-
const simple3 = await service.
|
|
435
|
+
const simple3 = await service.countByQuery(Aged, {
|
|
435
436
|
where: {
|
|
436
437
|
createdAt: {
|
|
437
438
|
$gt: '-1296m', // -1.9d
|
|
@@ -441,7 +442,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
441
442
|
});
|
|
442
443
|
assert(simple3 === 3);
|
|
443
444
|
|
|
444
|
-
const simple4 = await service.
|
|
445
|
+
const simple4 = await service.countByQuery(Aged, {
|
|
445
446
|
where: {
|
|
446
447
|
createdAt: {
|
|
447
448
|
$gt: TimeUtil.fromNow('-144m'), // -0.1d
|
|
@@ -463,35 +464,35 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
463
464
|
WithNestedLists.from({ names: [], tags: [] })
|
|
464
465
|
]);
|
|
465
466
|
|
|
466
|
-
let total = await service.
|
|
467
|
+
let total = await service.countByQuery(WithNestedLists, {
|
|
467
468
|
where: {
|
|
468
469
|
names: { $exists: true }
|
|
469
470
|
}
|
|
470
471
|
});
|
|
471
472
|
assert(total === 3);
|
|
472
473
|
|
|
473
|
-
total = await service.
|
|
474
|
+
total = await service.countByQuery(WithNestedLists, {
|
|
474
475
|
where: {
|
|
475
476
|
names: { $exists: false }
|
|
476
477
|
}
|
|
477
478
|
});
|
|
478
479
|
assert(total === 2);
|
|
479
480
|
|
|
480
|
-
total = await service.
|
|
481
|
+
total = await service.countByQuery(WithNestedLists, {
|
|
481
482
|
where: {
|
|
482
483
|
tags: { $exists: false }
|
|
483
484
|
}
|
|
484
485
|
});
|
|
485
486
|
assert(total === 3);
|
|
486
487
|
|
|
487
|
-
total = await service.
|
|
488
|
+
total = await service.countByQuery(WithNestedLists, {
|
|
488
489
|
where: {
|
|
489
490
|
tags: { $exists: true }
|
|
490
491
|
}
|
|
491
492
|
});
|
|
492
493
|
assert(total === 2);
|
|
493
494
|
|
|
494
|
-
total = await service.
|
|
495
|
+
total = await service.countByQuery(WithNestedLists, {
|
|
495
496
|
where: {
|
|
496
497
|
tags: { $exists: false },
|
|
497
498
|
names: { $exists: false }
|
|
@@ -499,7 +500,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
499
500
|
});
|
|
500
501
|
assert(total === 1);
|
|
501
502
|
|
|
502
|
-
total = await service.
|
|
503
|
+
total = await service.countByQuery(WithNestedLists, {
|
|
503
504
|
where: {
|
|
504
505
|
tags: { $exists: true },
|
|
505
506
|
names: { $exists: true }
|
|
@@ -520,35 +521,35 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
520
521
|
WithNestedNestedLists.from({ sub: {}, tags: [] })
|
|
521
522
|
]);
|
|
522
523
|
|
|
523
|
-
let total = await service.
|
|
524
|
+
let total = await service.countByQuery(WithNestedNestedLists, {
|
|
524
525
|
where: {
|
|
525
526
|
sub: { names: { $exists: true } }
|
|
526
527
|
}
|
|
527
528
|
});
|
|
528
529
|
assert(total === 3);
|
|
529
530
|
|
|
530
|
-
total = await service.
|
|
531
|
+
total = await service.countByQuery(WithNestedNestedLists, {
|
|
531
532
|
where: {
|
|
532
533
|
sub: { names: { $exists: false } }
|
|
533
534
|
}
|
|
534
535
|
});
|
|
535
536
|
assert(total === 2);
|
|
536
537
|
|
|
537
|
-
total = await service.
|
|
538
|
+
total = await service.countByQuery(WithNestedNestedLists, {
|
|
538
539
|
where: {
|
|
539
540
|
tags: { $exists: false }
|
|
540
541
|
}
|
|
541
542
|
});
|
|
542
543
|
assert(total === 3);
|
|
543
544
|
|
|
544
|
-
total = await service.
|
|
545
|
+
total = await service.countByQuery(WithNestedNestedLists, {
|
|
545
546
|
where: {
|
|
546
547
|
tags: { $exists: true }
|
|
547
548
|
}
|
|
548
549
|
});
|
|
549
550
|
assert(total === 2);
|
|
550
551
|
|
|
551
|
-
total = await service.
|
|
552
|
+
total = await service.countByQuery(WithNestedNestedLists, {
|
|
552
553
|
where: {
|
|
553
554
|
tags: { $exists: false },
|
|
554
555
|
sub: { names: { $exists: false } }
|
|
@@ -556,7 +557,7 @@ export abstract class ModelQuerySuite extends BaseModelSuite<ModelQuerySupport &
|
|
|
556
557
|
});
|
|
557
558
|
assert(total === 1);
|
|
558
559
|
|
|
559
|
-
total = await service.
|
|
560
|
+
total = await service.countByQuery(WithNestedNestedLists, {
|
|
560
561
|
where: {
|
|
561
562
|
tags: { $exists: true },
|
|
562
563
|
sub: { names: { $exists: true } }
|