@byted-apaas/server-sdk-node 1.0.12 → 1.0.14
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 +11 -1
- package/context/db/impl/IObject.d.ts +13 -0
- package/context/db/impl/object.d.ts +8 -0
- package/context/db/impl/object.js +169 -18
- package/context/db/impl/queryBuilder.d.ts +2 -2
- package/context/db/impl/queryBuilder.js +5 -13
- package/kunlun/operator/impl/logicV2.d.ts +1 -0
- package/kunlun/operator/impl/logicV2.js +1 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
-
## aPaaS
|
|
1
|
+
## aPaaS @byted-apaas/server-sdk-node 版本说明:
|
|
2
|
+
|
|
3
|
+
-------
|
|
4
|
+
### 版本:1.0.13|兼容升级
|
|
5
|
+
新功能:支持流式查询 findStream
|
|
6
|
+
```js
|
|
7
|
+
await context.db.object("_user").findStream(async (records) => {
|
|
8
|
+
// doSomething ...
|
|
9
|
+
});
|
|
10
|
+
```
|
|
11
|
+
优化:findAll 标记为过时方法,用 findStream 替代
|
|
@@ -121,6 +121,8 @@ export interface _IKAsyncEndpoint<T> {
|
|
|
121
121
|
}
|
|
122
122
|
export interface _IKQuery<T> {
|
|
123
123
|
/**
|
|
124
|
+
* @Deprecated Use FindStream instead.
|
|
125
|
+
*
|
|
124
126
|
* 无需入参,返回全部符合条件的记录
|
|
125
127
|
* @example
|
|
126
128
|
* ```
|
|
@@ -130,6 +132,17 @@ export interface _IKQuery<T> {
|
|
|
130
132
|
* ```
|
|
131
133
|
*/
|
|
132
134
|
findAll(): Promise<_Record<T>[]>;
|
|
135
|
+
/**
|
|
136
|
+
* 遍历全部符合条件的记录
|
|
137
|
+
* @param handler 业务处理函数
|
|
138
|
+
* @example
|
|
139
|
+
* ```
|
|
140
|
+
* await context.db.object("_user").findStream(async (records) => {
|
|
141
|
+
* // doSomething ...
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
findStream(handler: (records: object[]) => Promise<void>): Promise<void>;
|
|
133
146
|
/**
|
|
134
147
|
* 无需入参,返回符合条件的记录,单次返回 200 条
|
|
135
148
|
* @example
|
|
@@ -56,6 +56,7 @@ declare class _KObjectQuery<T> implements _IKQuery<T> {
|
|
|
56
56
|
find(): Promise<_Record<T>[]>;
|
|
57
57
|
findOne(): Promise<_Record<T>>;
|
|
58
58
|
findAll(): Promise<_Record<T>[]>;
|
|
59
|
+
findStream(handler: (records: object[]) => Promise<void>): Promise<void>;
|
|
59
60
|
orderBy<K extends keyof T>(fieldApiNames: K[]): _KQuery<T>;
|
|
60
61
|
orderBy<K extends keyof T>(...fieldApiNames: K[]): _KQuery<T>;
|
|
61
62
|
orderByDesc<K extends keyof T>(fieldApiNames: K[]): _KQuery<T>;
|
|
@@ -75,7 +76,13 @@ declare class _KQuery<T> implements _IKQuery<T> {
|
|
|
75
76
|
constructor(objectApiName: string, appCtx?: AppCtx);
|
|
76
77
|
find(): Promise<_Record<T>[]>;
|
|
77
78
|
findOne(): Promise<_Record<T>>;
|
|
79
|
+
/**
|
|
80
|
+
* @Deprecated Use FindStream instead.
|
|
81
|
+
*/
|
|
78
82
|
findAll(): Promise<_Record<T>[]>;
|
|
83
|
+
findStream(handler: (records: object[]) => Promise<void>): Promise<void>;
|
|
84
|
+
private walkRecordsByID;
|
|
85
|
+
private walkRecordsByLimitOffset;
|
|
79
86
|
private getRecordsByPage;
|
|
80
87
|
orderBy<K extends keyof T>(fieldApiNames: K[]): this;
|
|
81
88
|
orderBy<K extends keyof T>(...fieldApiNames: K[]): this;
|
|
@@ -88,5 +95,6 @@ declare class _KQuery<T> implements _IKQuery<T> {
|
|
|
88
95
|
limit(limit: number): this;
|
|
89
96
|
offset(offset: number): this;
|
|
90
97
|
count(): Promise<number>;
|
|
98
|
+
private findPreCheck;
|
|
91
99
|
}
|
|
92
100
|
export {};
|
|
@@ -301,6 +301,9 @@ class _KObjectQuery {
|
|
|
301
301
|
return new _KQuery(this.apiName, this.appCtx).findAll();
|
|
302
302
|
}
|
|
303
303
|
;
|
|
304
|
+
async findStream(handler) {
|
|
305
|
+
return new _KQuery(this.apiName, this.appCtx).findStream(handler);
|
|
306
|
+
}
|
|
304
307
|
orderBy(fieldApiNames, ...restFieldApiNames) {
|
|
305
308
|
fieldApiNames = !fieldApiNames ? [] : fieldApiNames;
|
|
306
309
|
return new _KQuery(this.apiName, this.appCtx).orderBy(server_common_node_1.utils.argsToList(fieldApiNames, restFieldApiNames));
|
|
@@ -350,23 +353,8 @@ class _KQuery {
|
|
|
350
353
|
});
|
|
351
354
|
}
|
|
352
355
|
async find() {
|
|
356
|
+
this.findPreCheck();
|
|
353
357
|
const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
354
|
-
// 查询非 _id 字段或者关联对象下钻._id, limit 不允许超过 200
|
|
355
|
-
let checkLimit;
|
|
356
|
-
let checkFields;
|
|
357
|
-
if (queryV2) {
|
|
358
|
-
checkLimit = queryV2._limit;
|
|
359
|
-
checkFields = queryV2.fields;
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
checkLimit = queryBuilder.getLimit();
|
|
363
|
-
checkFields = queryBuilder.getSelect();
|
|
364
|
-
}
|
|
365
|
-
if (checkFields.length != 1 || !(checkFields[0] == "_id" || checkFields[0].endsWith("._id"))) {
|
|
366
|
-
if (checkLimit > 200) {
|
|
367
|
-
throw new Error(`limit(${checkLimit}) > ${queryBuilder_1.maxLimit}. Limit should be 1~${queryBuilder_1.maxLimitV2} when querying the id field, otherwise it should be 1~${queryBuilder_1.maxLimit}`);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
358
|
if (appCtx) {
|
|
371
359
|
const param = {
|
|
372
360
|
limit: queryV2._limit,
|
|
@@ -393,6 +381,9 @@ class _KQuery {
|
|
|
393
381
|
return records instanceof Array ? (records.length > 0 ? records[0] : null) : null;
|
|
394
382
|
}
|
|
395
383
|
;
|
|
384
|
+
/**
|
|
385
|
+
* @Deprecated Use FindStream instead.
|
|
386
|
+
*/
|
|
396
387
|
async findAll() {
|
|
397
388
|
const { queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
398
389
|
if (queryBuilder.getOrder().length > 0) {
|
|
@@ -404,6 +395,152 @@ class _KQuery {
|
|
|
404
395
|
return await this.getRecordsByPage();
|
|
405
396
|
}
|
|
406
397
|
;
|
|
398
|
+
async findStream(handler) {
|
|
399
|
+
const { queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
400
|
+
let offset = 0, orders = [];
|
|
401
|
+
if (queryV2) {
|
|
402
|
+
offset = queryV2._offset;
|
|
403
|
+
orders = queryV2._order;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
offset = queryBuilder.getOffset();
|
|
407
|
+
orders = queryBuilder.getOrder();
|
|
408
|
+
}
|
|
409
|
+
if (orders.length === 0 && offset === 0) {
|
|
410
|
+
// 走主键翻页
|
|
411
|
+
return await this.walkRecordsByID(handler);
|
|
412
|
+
}
|
|
413
|
+
// 走 limit offset 翻页
|
|
414
|
+
return await this.walkRecordsByLimitOffset(handler);
|
|
415
|
+
}
|
|
416
|
+
async walkRecordsByID(handler) {
|
|
417
|
+
const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
418
|
+
let limit = 0, selectFields = [];
|
|
419
|
+
if (queryV2) {
|
|
420
|
+
if (queryV2.isSetLimit) {
|
|
421
|
+
limit = queryV2._limit;
|
|
422
|
+
}
|
|
423
|
+
selectFields = queryV2.fields;
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
if (queryBuilder.isSetLimit) {
|
|
427
|
+
limit = queryBuilder.getLimit();
|
|
428
|
+
}
|
|
429
|
+
selectFields = queryBuilder.getSelect();
|
|
430
|
+
}
|
|
431
|
+
let maxId = 0, queryCount = 0;
|
|
432
|
+
while (true) {
|
|
433
|
+
let newLimit = queryBuilder_1.defaultLimit;
|
|
434
|
+
if (limit > 0 && limit - queryCount < queryBuilder_1.defaultLimit) {
|
|
435
|
+
newLimit = limit - queryCount;
|
|
436
|
+
}
|
|
437
|
+
if (newLimit <= 0) {
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
let rs;
|
|
441
|
+
if (appCtx) {
|
|
442
|
+
let criterion = (0, logicV2_1.buildCriterionV2)(queryV2.filter);
|
|
443
|
+
criterion.push({ leftValue: '_id', operator: operator_1.operates.GT, rightValue: maxId });
|
|
444
|
+
const param = {
|
|
445
|
+
limit: newLimit,
|
|
446
|
+
offset: 0,
|
|
447
|
+
sort: [{ field: '_id', direction: 'asc', type: '' }],
|
|
448
|
+
fields: selectFields,
|
|
449
|
+
count: false,
|
|
450
|
+
filter: criterion,
|
|
451
|
+
};
|
|
452
|
+
rs = await (0, common_1.runCtxForOpenSDK)(appCtx, async () => {
|
|
453
|
+
return await Request.GetInstance().openSDKGetRecords(apiName, param);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
let criterion = (0, logic_1.buildCriterion)(queryBuilder.getLogic(), apiName, maxId);
|
|
458
|
+
rs = await Request.GetInstance().getRecordsOrCountByCriterion(apiName, await (0, logic_1.handleCriterion)(criterion), [new order_1.Order("_id", "asc")], false, queryBuilder.getSelect(), 0, newLimit, false);
|
|
459
|
+
}
|
|
460
|
+
queryCount += rs.length;
|
|
461
|
+
rs.forEach((r) => {
|
|
462
|
+
maxId = r._id > maxId ? r._id : maxId;
|
|
463
|
+
});
|
|
464
|
+
try {
|
|
465
|
+
if (rs.length > 0) {
|
|
466
|
+
await handler(rs);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
catch (err) {
|
|
470
|
+
throw err;
|
|
471
|
+
}
|
|
472
|
+
if (rs.length < queryBuilder_1.defaultLimit) {
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async walkRecordsByLimitOffset(handler) {
|
|
478
|
+
const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
479
|
+
let limit = 0, offset = 0, selectFields = [], orders = [];
|
|
480
|
+
if (queryV2) {
|
|
481
|
+
if (queryV2.isSetLimit) {
|
|
482
|
+
limit = queryV2._limit;
|
|
483
|
+
}
|
|
484
|
+
offset = queryV2._offset;
|
|
485
|
+
selectFields = queryV2.fields;
|
|
486
|
+
orders = queryV2._order;
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
if (queryBuilder.isSetLimit) {
|
|
490
|
+
limit = queryBuilder.getLimit();
|
|
491
|
+
}
|
|
492
|
+
offset = queryBuilder.getOffset();
|
|
493
|
+
selectFields = queryBuilder.getSelect();
|
|
494
|
+
orders = queryBuilder.getOrder();
|
|
495
|
+
}
|
|
496
|
+
let maxId = 0, queryCount = 0;
|
|
497
|
+
for (let i = offset; !limit || i < offset + limit; i += queryBuilder_1.defaultLimit) {
|
|
498
|
+
let newLimit = function () {
|
|
499
|
+
if (limit == 0) {
|
|
500
|
+
return queryBuilder_1.defaultLimit;
|
|
501
|
+
}
|
|
502
|
+
if (offset + limit - i < queryBuilder_1.defaultLimit) {
|
|
503
|
+
return offset + limit - i;
|
|
504
|
+
}
|
|
505
|
+
return queryBuilder_1.defaultLimit;
|
|
506
|
+
}();
|
|
507
|
+
if (newLimit <= 0) {
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
let rs;
|
|
511
|
+
if (appCtx) {
|
|
512
|
+
let criterion = (0, logicV2_1.buildCriterionV2)(queryV2.filter);
|
|
513
|
+
criterion.push({ leftValue: '_id', operator: operator_1.operates.GT, rightValue: maxId });
|
|
514
|
+
const param = {
|
|
515
|
+
limit: newLimit,
|
|
516
|
+
offset: i,
|
|
517
|
+
sort: orders,
|
|
518
|
+
fields: selectFields,
|
|
519
|
+
count: false,
|
|
520
|
+
filter: criterion,
|
|
521
|
+
};
|
|
522
|
+
rs = await (0, common_1.runCtxForOpenSDK)(appCtx, async () => {
|
|
523
|
+
return await Request.GetInstance().openSDKGetRecords(apiName, param);
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
let criterion = (0, logic_1.buildCriterion)(queryBuilder.getLogic(), apiName, maxId);
|
|
528
|
+
rs = await Request.GetInstance().getRecordsOrCountByCriterion(apiName, await (0, logic_1.handleCriterion)(criterion), orders, false, selectFields, i, newLimit, false);
|
|
529
|
+
}
|
|
530
|
+
queryCount += rs.length;
|
|
531
|
+
try {
|
|
532
|
+
if (rs.length > 0) {
|
|
533
|
+
await handler(rs);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
catch (err) {
|
|
537
|
+
throw err;
|
|
538
|
+
}
|
|
539
|
+
if (rs.length < queryBuilder_1.defaultLimit) {
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
407
544
|
async getRecordsByPage() {
|
|
408
545
|
const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
409
546
|
let maxId = 0, records = [];
|
|
@@ -426,13 +563,13 @@ class _KQuery {
|
|
|
426
563
|
}
|
|
427
564
|
else {
|
|
428
565
|
let criterion = (0, logic_1.buildCriterion)(queryBuilder.getLogic(), apiName, maxId);
|
|
429
|
-
rs = await Request.GetInstance().getRecordsOrCountByCriterion(apiName, await (0, logic_1.handleCriterion)(criterion), [new order_1.Order("_id", "asc")], false, queryBuilder.getSelect(), 0, queryBuilder_1.
|
|
566
|
+
rs = await Request.GetInstance().getRecordsOrCountByCriterion(apiName, await (0, logic_1.handleCriterion)(criterion), [new order_1.Order("_id", "asc")], false, queryBuilder.getSelect(), 0, queryBuilder_1.defaultLimit, false);
|
|
430
567
|
}
|
|
431
568
|
rs.forEach((r) => {
|
|
432
569
|
maxId = r._id > maxId ? r._id : maxId;
|
|
433
570
|
});
|
|
434
571
|
records.push(...rs);
|
|
435
|
-
if (rs.length < queryBuilder_1.
|
|
572
|
+
if (rs.length < queryBuilder_1.defaultLimit) {
|
|
436
573
|
break;
|
|
437
574
|
}
|
|
438
575
|
}
|
|
@@ -542,6 +679,20 @@ class _KQuery {
|
|
|
542
679
|
}
|
|
543
680
|
}
|
|
544
681
|
;
|
|
682
|
+
findPreCheck() {
|
|
683
|
+
const { queryBuilder, queryV2 } = queryPropertiesStore.get(this);
|
|
684
|
+
let limit = queryBuilder_1.defaultLimit;
|
|
685
|
+
if (queryV2) {
|
|
686
|
+
limit = queryV2._limit;
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
limit = queryBuilder.limit;
|
|
690
|
+
}
|
|
691
|
+
if (limit < 1) {
|
|
692
|
+
// need import exceptions
|
|
693
|
+
throw new server_common_node_1.exceptions.InvalidParamError(`limit(${limit}) < 1`);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
545
696
|
}
|
|
546
697
|
function applyMixins(derivedCtor, constructors) {
|
|
547
698
|
constructors.forEach((baseCtor) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Order, OrderType } from './order';
|
|
2
2
|
import { Logic } from '../../../kunlun/operator/impl/logic';
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const maxLimitV2 = 10000;
|
|
3
|
+
export declare const defaultLimit = 200;
|
|
5
4
|
/**
|
|
6
5
|
* 查询构造器,在 DB 中被初始化,用于构建一次查询
|
|
7
6
|
*/
|
|
@@ -11,6 +10,7 @@ export declare class QueryBuilder {
|
|
|
11
10
|
select: string[];
|
|
12
11
|
where: Logic[];
|
|
13
12
|
limit: number;
|
|
13
|
+
isSetLimit: boolean;
|
|
14
14
|
offset: number;
|
|
15
15
|
order: Order[];
|
|
16
16
|
logic: Logic;
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
// Copyright 2022 ByteDance Ltd. and/or its affiliates
|
|
3
3
|
// SPDX-License-Identifier: MIT
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.QueryBuilder = exports.
|
|
5
|
+
exports.QueryBuilder = exports.defaultLimit = void 0;
|
|
6
6
|
const order_1 = require("./order");
|
|
7
7
|
const logic_1 = require("../../../kunlun/operator/impl/logic");
|
|
8
8
|
const server_common_node_1 = require("@byted-apaas/server-common-node");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
exports.maxLimitV2 = 10000;
|
|
9
|
+
// SDK 仅作 limit 小于 0 校验,其他校验拦截由底层控制,如当查询结果不满足受控条件时,limit 仅支持最大 200
|
|
10
|
+
exports.defaultLimit = 200;
|
|
12
11
|
/**
|
|
13
12
|
* 查询构造器,在 DB 中被初始化,用于构建一次查询
|
|
14
13
|
*/
|
|
@@ -18,7 +17,7 @@ class QueryBuilder {
|
|
|
18
17
|
this.dataSource = '';
|
|
19
18
|
this.select = [];
|
|
20
19
|
this.where = null;
|
|
21
|
-
this.limit = exports.
|
|
20
|
+
this.limit = exports.defaultLimit;
|
|
22
21
|
this.offset = 0;
|
|
23
22
|
this.order = [];
|
|
24
23
|
this.logic = new logic_1.Logic();
|
|
@@ -60,15 +59,8 @@ class QueryBuilder {
|
|
|
60
59
|
this.offset = offset;
|
|
61
60
|
}
|
|
62
61
|
setLimit(limit) {
|
|
63
|
-
if (limit < 1) {
|
|
64
|
-
// need import exceptions
|
|
65
|
-
throw new server_common_node_1.exceptions.InvalidParamError(`limit(${limit}) < 1`);
|
|
66
|
-
}
|
|
67
|
-
if (limit > exports.maxLimitV2) {
|
|
68
|
-
// need import exceptions
|
|
69
|
-
throw new server_common_node_1.exceptions.InvalidParamError(`limit(${limit}) > ${exports.maxLimitV2}. Limit should be 1~${exports.maxLimitV2} when querying the id field, otherwise it should be 1~${exports.maxLimit}`);
|
|
70
|
-
}
|
|
71
62
|
this.limit = limit;
|
|
63
|
+
this.isSetLimit = true;
|
|
72
64
|
}
|
|
73
65
|
getLimit() {
|
|
74
66
|
return this.limit;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildCriterionV2 = exports.logical = exports.QueryV2 = exports.LogicalExpression = exports.ArithmeticExpression = exports.NewConstantExpressionField = exports.NewMetadataExpressionField = void 0;
|
|
4
4
|
const operator_1 = require("./operator");
|
|
5
|
-
const queryBuilder_1 = require("../../../context/db/impl/queryBuilder");
|
|
6
5
|
function NewMetadataExpressionField(objectApiName, fieldApiName) {
|
|
7
6
|
return {
|
|
8
7
|
type: "metadataVariable",
|
|
@@ -110,10 +109,8 @@ class QueryV2 {
|
|
|
110
109
|
return this;
|
|
111
110
|
}
|
|
112
111
|
limit(limit) {
|
|
113
|
-
if (limit <= 0 || limit > 10000) {
|
|
114
|
-
throw new Error(`limit(${limit}) > ${queryBuilder_1.maxLimitV2}. Limit should be 1~${queryBuilder_1.maxLimitV2} when querying the id field, otherwise it should be 1~${queryBuilder_1.maxLimit}`);
|
|
115
|
-
}
|
|
116
112
|
this._limit = limit;
|
|
113
|
+
this.isSetLimit = true;
|
|
117
114
|
return this;
|
|
118
115
|
}
|
|
119
116
|
orderBy(fieldApiNames) {
|