@cloudbase/database 0.11.0 → 0.12.1

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.
Files changed (65) hide show
  1. package/dist/commonjs/collection.d.ts +1 -1
  2. package/dist/commonjs/document.js +16 -6
  3. package/dist/commonjs/transaction/query.d.ts +39 -1
  4. package/dist/commonjs/transaction/query.js +251 -1
  5. package/dist/esm/collection.d.ts +1 -1
  6. package/dist/esm/document.js +16 -6
  7. package/dist/esm/transaction/query.d.ts +39 -1
  8. package/dist/esm/transaction/query.js +251 -1
  9. package/package.json +1 -1
  10. package/src/collection.ts +4 -3
  11. package/src/document.ts +17 -9
  12. package/src/transaction/query.ts +355 -2
  13. package/tests/transaction-query.test.ts +657 -0
  14. package/coverage/lcov-report/base.css +0 -224
  15. package/coverage/lcov-report/block-navigation.js +0 -87
  16. package/coverage/lcov-report/favicon.png +0 -0
  17. package/coverage/lcov-report/index.html +0 -101
  18. package/coverage/lcov-report/prettify.css +0 -1
  19. package/coverage/lcov-report/prettify.js +0 -2
  20. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  21. package/coverage/lcov-report/sorter.js +0 -210
  22. package/coverage/lcov.info +0 -0
  23. package/dist/esm/aggregate.d.ts.map +0 -1
  24. package/dist/esm/collection.d.ts.map +0 -1
  25. package/dist/esm/command.d.ts.map +0 -1
  26. package/dist/esm/commands/logic.d.ts.map +0 -1
  27. package/dist/esm/commands/query.d.ts.map +0 -1
  28. package/dist/esm/commands/update.d.ts.map +0 -1
  29. package/dist/esm/config/app.config.d.ts.map +0 -1
  30. package/dist/esm/config/error.config.d.ts.map +0 -1
  31. package/dist/esm/const/code.d.ts.map +0 -1
  32. package/dist/esm/constant.d.ts.map +0 -1
  33. package/dist/esm/document.d.ts.map +0 -1
  34. package/dist/esm/geo/index.d.ts.map +0 -1
  35. package/dist/esm/geo/interface.d.ts.map +0 -1
  36. package/dist/esm/geo/lineString.d.ts.map +0 -1
  37. package/dist/esm/geo/multiLineString.d.ts.map +0 -1
  38. package/dist/esm/geo/multiPoint.d.ts.map +0 -1
  39. package/dist/esm/geo/multiPolygon.d.ts.map +0 -1
  40. package/dist/esm/geo/point.d.ts.map +0 -1
  41. package/dist/esm/geo/polygon.d.ts.map +0 -1
  42. package/dist/esm/helper/symbol.d.ts.map +0 -1
  43. package/dist/esm/index.d.ts.map +0 -1
  44. package/dist/esm/lib/util.d.ts.map +0 -1
  45. package/dist/esm/operator-map.d.ts.map +0 -1
  46. package/dist/esm/query.d.ts.map +0 -1
  47. package/dist/esm/regexp/index.d.ts.map +0 -1
  48. package/dist/esm/serializer/common.d.ts.map +0 -1
  49. package/dist/esm/serializer/datatype.d.ts.map +0 -1
  50. package/dist/esm/serializer/query.d.ts.map +0 -1
  51. package/dist/esm/serializer/update.d.ts.map +0 -1
  52. package/dist/esm/serverDate/index.d.ts.map +0 -1
  53. package/dist/esm/transaction/collection.d.ts.map +0 -1
  54. package/dist/esm/transaction/document.d.ts.map +0 -1
  55. package/dist/esm/transaction/index.d.ts.map +0 -1
  56. package/dist/esm/transaction/query.d.ts.map +0 -1
  57. package/dist/esm/typings/index.d.ts.map +0 -1
  58. package/dist/esm/typings/realtime.d.ts.map +0 -1
  59. package/dist/esm/util.d.ts.map +0 -1
  60. package/dist/esm/utils/error.d.ts.map +0 -1
  61. package/dist/esm/utils/msg.d.ts.map +0 -1
  62. package/dist/esm/utils/symbol.d.ts.map +0 -1
  63. package/dist/esm/utils/type.d.ts.map +0 -1
  64. package/dist/esm/utils/utils.d.ts.map +0 -1
  65. package/dist/esm/validate.d.ts.map +0 -1
@@ -1,8 +1,258 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { EJSON } from 'bson';
49
+ import { ErrorCode } from '../constant';
50
+ import { Validate } from '../validate';
51
+ import { QuerySerializer } from '../serializer/query';
52
+ import { UpdateSerializer } from '../serializer/update';
53
+ import { Util } from '../util';
54
+ var GET_DOC = 'database.getInTransaction';
55
+ var UPDATE_DOC = 'database.updateDocInTransaction';
56
+ var DELETE_DOC = 'database.deleteDocInTransaction';
1
57
  var Query = (function () {
2
- function Query(transaction, coll) {
58
+ function Query(transaction, coll, fieldFilters, fieldOrders, queryOptions) {
3
59
  this._coll = coll;
4
60
  this._transaction = transaction;
61
+ this._fieldFilters = fieldFilters;
62
+ this._fieldOrders = fieldOrders || [];
63
+ this._queryOptions = queryOptions || {};
64
+ this._request = this._transaction.getRequestMethod();
65
+ this._transactionId = this._transaction.getTransactionId();
5
66
  }
67
+ Query.prototype.where = function (query) {
68
+ if (Object.prototype.toString.call(query).slice(8, -1) !== 'Object') {
69
+ throw Error(ErrorCode.QueryParamTypeError);
70
+ }
71
+ var keys = Object.keys(query);
72
+ var checkFlag = keys.some(function (item) {
73
+ return query[item] !== undefined;
74
+ });
75
+ if (keys.length && !checkFlag) {
76
+ throw Error(ErrorCode.QueryParamValueError);
77
+ }
78
+ return new Query(this._transaction, this._coll, QuerySerializer.encode(query), this._fieldOrders, this._queryOptions);
79
+ };
80
+ Query.prototype.orderBy = function (fieldPath, directionStr) {
81
+ Validate.isFieldPath(fieldPath);
82
+ Validate.isFieldOrder(directionStr);
83
+ var newOrder = {
84
+ field: fieldPath,
85
+ direction: directionStr
86
+ };
87
+ var combinedOrders = this._fieldOrders.concat(newOrder);
88
+ return new Query(this._transaction, this._coll, this._fieldFilters, combinedOrders, this._queryOptions);
89
+ };
90
+ Query.prototype.limit = function (limit) {
91
+ Validate.isInteger('limit', limit);
92
+ var option = __assign({}, this._queryOptions);
93
+ option.limit = limit;
94
+ return new Query(this._transaction, this._coll, this._fieldFilters, this._fieldOrders, option);
95
+ };
96
+ Query.prototype.skip = function (offset) {
97
+ Validate.isInteger('offset', offset);
98
+ var option = __assign({}, this._queryOptions);
99
+ option.offset = offset;
100
+ return new Query(this._transaction, this._coll, this._fieldFilters, this._fieldOrders, option);
101
+ };
102
+ Query.prototype.field = function (projection) {
103
+ for (var k in projection) {
104
+ if (projection[k]) {
105
+ if (typeof projection[k] !== 'object') {
106
+ projection[k] = 1;
107
+ }
108
+ }
109
+ else {
110
+ projection[k] = 0;
111
+ }
112
+ }
113
+ var option = __assign({}, this._queryOptions);
114
+ option.projection = projection;
115
+ return new Query(this._transaction, this._coll, this._fieldFilters, this._fieldOrders, option);
116
+ };
117
+ Query.prototype.get = function () {
118
+ return __awaiter(this, void 0, void 0, function () {
119
+ var newOrder, param, res, data, documents, result;
120
+ return __generator(this, function (_a) {
121
+ switch (_a.label) {
122
+ case 0:
123
+ newOrder = [];
124
+ if (this._fieldOrders) {
125
+ this._fieldOrders.forEach(function (order) {
126
+ newOrder.push(order);
127
+ });
128
+ }
129
+ param = {
130
+ collectionName: this._coll,
131
+ transactionId: this._transactionId
132
+ };
133
+ if (this._fieldFilters) {
134
+ param.query = this._fieldFilters;
135
+ }
136
+ if (newOrder.length > 0) {
137
+ param.order = newOrder;
138
+ }
139
+ if (this._queryOptions.offset) {
140
+ param.offset = this._queryOptions.offset;
141
+ }
142
+ if (this._queryOptions.limit) {
143
+ param.limit = this._queryOptions.limit < 1000 ? this._queryOptions.limit : 1000;
144
+ }
145
+ else {
146
+ param.limit = 100;
147
+ }
148
+ if (this._queryOptions.projection) {
149
+ param.projection = this._queryOptions.projection;
150
+ }
151
+ return [4, this._request.send(GET_DOC, param)];
152
+ case 1:
153
+ res = _a.sent();
154
+ if (res.code)
155
+ throw res;
156
+ data = res.data !== 'null' ? EJSON.parse(res.data) : null;
157
+ documents = data ? (Array.isArray(data) ? Util.formatResDocumentData(data) : [Util.formatField(data)]) : [];
158
+ result = {
159
+ data: documents,
160
+ requestId: res.requestId
161
+ };
162
+ if (res.total !== undefined)
163
+ result.total = res.total;
164
+ if (res.limit !== undefined)
165
+ result.limit = res.limit;
166
+ if (res.offset !== undefined)
167
+ result.offset = res.offset;
168
+ return [2, result];
169
+ }
170
+ });
171
+ });
172
+ };
173
+ Query.prototype.count = function () {
174
+ return __awaiter(this, void 0, void 0, function () {
175
+ var param, res, data, total;
176
+ return __generator(this, function (_a) {
177
+ switch (_a.label) {
178
+ case 0:
179
+ param = {
180
+ collectionName: this._coll,
181
+ transactionId: this._transactionId
182
+ };
183
+ if (this._fieldFilters) {
184
+ param.query = this._fieldFilters;
185
+ }
186
+ return [4, this._request.send(GET_DOC, param)];
187
+ case 1:
188
+ res = _a.sent();
189
+ if (res.code)
190
+ throw res;
191
+ data = res.data !== 'null' ? EJSON.parse(res.data) : null;
192
+ total = Array.isArray(data) ? data.length : (data ? 1 : 0);
193
+ return [2, {
194
+ requestId: res.requestId,
195
+ total: res.total !== undefined ? res.total : total
196
+ }];
197
+ }
198
+ });
199
+ });
200
+ };
201
+ Query.prototype.update = function (data) {
202
+ return __awaiter(this, void 0, void 0, function () {
203
+ var param, res;
204
+ return __generator(this, function (_a) {
205
+ switch (_a.label) {
206
+ case 0:
207
+ if (!data || typeof data !== 'object') {
208
+ throw new Error('参数必需是非空对象');
209
+ }
210
+ if (data.hasOwnProperty('_id')) {
211
+ throw new Error('不能更新_id的值');
212
+ }
213
+ param = {
214
+ collectionName: this._coll,
215
+ transactionId: this._transactionId,
216
+ query: this._fieldFilters,
217
+ data: EJSON.stringify(UpdateSerializer.encode(data), { relaxed: false })
218
+ };
219
+ return [4, this._request.send(UPDATE_DOC, param)];
220
+ case 1:
221
+ res = _a.sent();
222
+ if (res.code)
223
+ throw res;
224
+ return [2, __assign(__assign({}, res), { updated: EJSON.parse(res.updated) })];
225
+ }
226
+ });
227
+ });
228
+ };
229
+ Query.prototype.remove = function () {
230
+ return __awaiter(this, void 0, void 0, function () {
231
+ var param, res;
232
+ return __generator(this, function (_a) {
233
+ switch (_a.label) {
234
+ case 0:
235
+ if (Object.keys(this._queryOptions).length > 0) {
236
+ console.warn('`offset`, `limit` and `projection` are not supported in remove() operation');
237
+ }
238
+ if (this._fieldOrders.length > 0) {
239
+ console.warn('`orderBy` is not supported in remove() operation');
240
+ }
241
+ param = {
242
+ collectionName: this._coll,
243
+ transactionId: this._transactionId,
244
+ query: this._fieldFilters
245
+ };
246
+ return [4, this._request.send(DELETE_DOC, param)];
247
+ case 1:
248
+ res = _a.sent();
249
+ if (res.code)
250
+ throw res;
251
+ return [2, __assign(__assign({}, res), { deleted: EJSON.parse(res.deleted) })];
252
+ }
253
+ });
254
+ });
255
+ };
6
256
  return Query;
7
257
  }());
8
258
  export { Query };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/database",
3
- "version": "0.11.0",
3
+ "version": "0.12.1",
4
4
  "description": "database for (node.)js sdk ",
5
5
  "main": "dist/commonjs/index.js",
6
6
  "module": "dist/esm/index.js",
package/src/collection.ts CHANGED
@@ -42,11 +42,12 @@ export class CollectionReference extends Query {
42
42
  }
43
43
 
44
44
  /**
45
- * 添加一篇文档
45
+ * 添加一篇或多篇文档
46
46
  *
47
- * @param data - 数据
47
+ * @param data - 单个文档数据或文档数据数组
48
+ * @param callback - 回调函数
48
49
  */
49
- add(data: Object, callback?: any): Promise<any> {
50
+ add(data: Object | Object[], callback?: any): Promise<any> {
50
51
  let docRef = new DocumentReference(this._db, this._coll, undefined)
51
52
  return docRef.create(data, callback)
52
53
  }
package/src/document.ts CHANGED
@@ -64,21 +64,22 @@ export class DocumentReference {
64
64
  }
65
65
 
66
66
  /**
67
- * 创建一篇文档
67
+ * 创建一篇或多篇文档
68
68
  *
69
- * @param data - 文档数据
69
+ * @param data - 文档数据,支持单个对象或对象数组
70
70
  * @internal
71
71
  */
72
72
  create(data: any, callback?: any): Promise<any> {
73
73
  callback = callback || createPromiseCallback()
74
74
 
75
+ const isBatch = Array.isArray(data)
76
+
75
77
  let params = {
76
78
  collectionName: this._coll,
77
- // data: Util.encodeDocumentDataForReq(data, false, false)
78
- data: serialize(data)
79
+ data: isBatch ? data.map(item => serialize(item)) : serialize(data)
79
80
  }
80
81
 
81
- if (this.id) {
82
+ if (!isBatch && this.id) {
82
83
  params['_id'] = this.id
83
84
  }
84
85
 
@@ -88,10 +89,17 @@ export class DocumentReference {
88
89
  if (res.code) {
89
90
  callback(0, res)
90
91
  } else {
91
- callback(0, {
92
- id: res.data._id,
93
- requestId: res.requestId
94
- })
92
+ if (isBatch) {
93
+ callback(0, {
94
+ ids: res.data?.insertedIds || [],
95
+ requestId: res.requestId
96
+ })
97
+ } else {
98
+ callback(0, {
99
+ id: res.data._id,
100
+ requestId: res.requestId
101
+ })
102
+ }
95
103
  }
96
104
  })
97
105
  .catch(err => {
@@ -1,8 +1,59 @@
1
1
  import { Transaction } from './index'
2
+ import { EJSON } from 'bson'
3
+ import { OrderByDirection, ErrorCode } from '../constant'
4
+ import { Validate } from '../validate'
5
+ import { QuerySerializer } from '../serializer/query'
6
+ import { UpdateSerializer } from '../serializer/update'
7
+ import { Util } from '../util'
8
+
9
+ const GET_DOC = 'database.getInTransaction'
10
+ const UPDATE_DOC = 'database.updateDocInTransaction'
11
+ const DELETE_DOC = 'database.deleteDocInTransaction'
12
+
13
+ interface QueryOrder {
14
+ field?: string
15
+ direction?: 'asc' | 'desc'
16
+ }
17
+
18
+ interface QueryOption {
19
+ limit?: number
20
+ offset?: number
21
+ projection?: Object
22
+ }
23
+
24
+ interface TransactionAPI {
25
+ send(interfaceName: string, param?: any)
26
+ }
27
+
28
+ interface GetResult {
29
+ data: any[]
30
+ requestId: string
31
+ total?: number
32
+ limit?: number
33
+ offset?: number
34
+ }
35
+
36
+ interface UpdateResult {
37
+ requestId: string
38
+ updated: number
39
+ }
40
+
41
+ interface DeleteResult {
42
+ requestId: string
43
+ deleted: number | string
44
+ }
45
+
46
+ interface TcbError {
47
+ requestId: string
48
+ code: string
49
+ message: string
50
+ stack?: string
51
+ }
2
52
 
3
53
  /**
4
- * 查询模块
54
+ * 事务查询模块
5
55
  *
56
+ * 支持 where 条件查询在事务中使用
6
57
  */
7
58
  export class Query {
8
59
  /**
@@ -14,8 +65,310 @@ export class Query {
14
65
 
15
66
  protected _transaction: Transaction
16
67
 
17
- constructor(transaction: Transaction, coll: string) {
68
+ /**
69
+ * 过滤条件
70
+ *
71
+ * @internal
72
+ */
73
+ private _fieldFilters: Object
74
+
75
+ /**
76
+ * 排序条件
77
+ *
78
+ * @internal
79
+ */
80
+ private _fieldOrders: QueryOrder[]
81
+
82
+ /**
83
+ * 查询条件
84
+ *
85
+ * @internal
86
+ */
87
+ private _queryOptions: QueryOption
88
+
89
+ /**
90
+ * 请求实例
91
+ *
92
+ * @internal
93
+ */
94
+ private _request: TransactionAPI
95
+
96
+ /**
97
+ * 事务ID
98
+ *
99
+ * @internal
100
+ */
101
+ private _transactionId: string
102
+
103
+ constructor(
104
+ transaction: Transaction,
105
+ coll: string,
106
+ fieldFilters?: Object,
107
+ fieldOrders?: QueryOrder[],
108
+ queryOptions?: QueryOption
109
+ ) {
18
110
  this._coll = coll
19
111
  this._transaction = transaction
112
+ this._fieldFilters = fieldFilters
113
+ this._fieldOrders = fieldOrders || []
114
+ this._queryOptions = queryOptions || {}
115
+ this._request = this._transaction.getRequestMethod()
116
+ this._transactionId = this._transaction.getTransactionId()
117
+ }
118
+
119
+ /**
120
+ * 查询条件
121
+ *
122
+ * @param query - 查询条件对象
123
+ */
124
+ public where(query: object): Query {
125
+ if (Object.prototype.toString.call(query).slice(8, -1) !== 'Object') {
126
+ throw Error(ErrorCode.QueryParamTypeError)
127
+ }
128
+
129
+ const keys = Object.keys(query)
130
+ const checkFlag = keys.some(item => {
131
+ return query[item] !== undefined
132
+ })
133
+
134
+ if (keys.length && !checkFlag) {
135
+ throw Error(ErrorCode.QueryParamValueError)
136
+ }
137
+
138
+ return new Query(
139
+ this._transaction,
140
+ this._coll,
141
+ QuerySerializer.encode(query),
142
+ this._fieldOrders,
143
+ this._queryOptions
144
+ )
145
+ }
146
+
147
+ /**
148
+ * 设置排序方式
149
+ *
150
+ * @param fieldPath - 字段路径
151
+ * @param directionStr - 排序方式
152
+ */
153
+ public orderBy(fieldPath: string, directionStr: OrderByDirection): Query {
154
+ Validate.isFieldPath(fieldPath)
155
+ Validate.isFieldOrder(directionStr)
156
+
157
+ const newOrder: QueryOrder = {
158
+ field: fieldPath,
159
+ direction: directionStr
160
+ }
161
+ const combinedOrders = this._fieldOrders.concat(newOrder)
162
+
163
+ return new Query(
164
+ this._transaction,
165
+ this._coll,
166
+ this._fieldFilters,
167
+ combinedOrders,
168
+ this._queryOptions
169
+ )
170
+ }
171
+
172
+ /**
173
+ * 设置查询条数
174
+ *
175
+ * @param limit - 限制条数
176
+ */
177
+ public limit(limit: number): Query {
178
+ Validate.isInteger('limit', limit)
179
+
180
+ let option = { ...this._queryOptions }
181
+ option.limit = limit
182
+
183
+ return new Query(
184
+ this._transaction,
185
+ this._coll,
186
+ this._fieldFilters,
187
+ this._fieldOrders,
188
+ option
189
+ )
190
+ }
191
+
192
+ /**
193
+ * 设置偏移量
194
+ *
195
+ * @param offset - 偏移量
196
+ */
197
+ public skip(offset: number): Query {
198
+ Validate.isInteger('offset', offset)
199
+
200
+ let option = { ...this._queryOptions }
201
+ option.offset = offset
202
+
203
+ return new Query(
204
+ this._transaction,
205
+ this._coll,
206
+ this._fieldFilters,
207
+ this._fieldOrders,
208
+ option
209
+ )
210
+ }
211
+
212
+ /**
213
+ * 指定要返回的字段
214
+ *
215
+ * @param projection
216
+ */
217
+ public field(projection: any): Query {
218
+ for (let k in projection) {
219
+ if (projection[k]) {
220
+ if (typeof projection[k] !== 'object') {
221
+ projection[k] = 1
222
+ }
223
+ } else {
224
+ projection[k] = 0
225
+ }
226
+ }
227
+
228
+ let option = { ...this._queryOptions }
229
+ option.projection = projection
230
+
231
+ return new Query(
232
+ this._transaction,
233
+ this._coll,
234
+ this._fieldFilters,
235
+ this._fieldOrders,
236
+ option
237
+ )
238
+ }
239
+
240
+ /**
241
+ * 发起请求获取文档列表(事务内)
242
+ */
243
+ public async get(): Promise<GetResult> {
244
+ let newOrder = []
245
+ if (this._fieldOrders) {
246
+ this._fieldOrders.forEach(order => {
247
+ newOrder.push(order)
248
+ })
249
+ }
250
+
251
+ let param: any = {
252
+ collectionName: this._coll,
253
+ transactionId: this._transactionId
254
+ }
255
+
256
+ if (this._fieldFilters) {
257
+ param.query = this._fieldFilters
258
+ }
259
+ if (newOrder.length > 0) {
260
+ param.order = newOrder
261
+ }
262
+ if (this._queryOptions.offset) {
263
+ param.offset = this._queryOptions.offset
264
+ }
265
+ if (this._queryOptions.limit) {
266
+ param.limit = this._queryOptions.limit < 1000 ? this._queryOptions.limit : 1000
267
+ } else {
268
+ param.limit = 100
269
+ }
270
+ if (this._queryOptions.projection) {
271
+ param.projection = this._queryOptions.projection
272
+ }
273
+
274
+ const res = await this._request.send(GET_DOC, param)
275
+ if (res.code) throw res
276
+
277
+ const data = res.data !== 'null' ? EJSON.parse(res.data) : null
278
+ const documents = data ? (Array.isArray(data) ? Util.formatResDocumentData(data) : [Util.formatField(data)]) : []
279
+
280
+ const result: GetResult = {
281
+ data: documents,
282
+ requestId: res.requestId
283
+ }
284
+ if (res.total !== undefined) result.total = res.total
285
+ if (res.limit !== undefined) result.limit = res.limit
286
+ if (res.offset !== undefined) result.offset = res.offset
287
+
288
+ return result
289
+ }
290
+
291
+ /**
292
+ * 获取总数(事务内)
293
+ */
294
+ public async count(): Promise<{ requestId: string; total: number }> {
295
+ let param: any = {
296
+ collectionName: this._coll,
297
+ transactionId: this._transactionId
298
+ }
299
+
300
+ if (this._fieldFilters) {
301
+ param.query = this._fieldFilters
302
+ }
303
+
304
+ const res = await this._request.send(GET_DOC, param)
305
+ if (res.code) throw res
306
+
307
+ const data = res.data !== 'null' ? EJSON.parse(res.data) : null
308
+ const total = Array.isArray(data) ? data.length : (data ? 1 : 0)
309
+
310
+ return {
311
+ requestId: res.requestId,
312
+ total: res.total !== undefined ? res.total : total
313
+ }
314
+ }
315
+
316
+ /**
317
+ * 发起请求批量更新文档(事务内)
318
+ *
319
+ * @param data - 更新数据
320
+ */
321
+ public async update(data: Object): Promise<UpdateResult> {
322
+ if (!data || typeof data !== 'object') {
323
+ throw new Error('参数必需是非空对象')
324
+ }
325
+
326
+ if (data.hasOwnProperty('_id')) {
327
+ throw new Error('不能更新_id的值')
328
+ }
329
+
330
+ const param = {
331
+ collectionName: this._coll,
332
+ transactionId: this._transactionId,
333
+ query: this._fieldFilters,
334
+ data: EJSON.stringify(
335
+ UpdateSerializer.encode(data),
336
+ { relaxed: false }
337
+ )
338
+ }
339
+
340
+ const res = await this._request.send(UPDATE_DOC, param)
341
+ if (res.code) throw res
342
+
343
+ return {
344
+ ...res,
345
+ updated: EJSON.parse(res.updated)
346
+ }
347
+ }
348
+
349
+ /**
350
+ * 条件删除文档(事务内)
351
+ */
352
+ public async remove(): Promise<DeleteResult> {
353
+ if (Object.keys(this._queryOptions).length > 0) {
354
+ console.warn('`offset`, `limit` and `projection` are not supported in remove() operation')
355
+ }
356
+ if (this._fieldOrders.length > 0) {
357
+ console.warn('`orderBy` is not supported in remove() operation')
358
+ }
359
+
360
+ const param = {
361
+ collectionName: this._coll,
362
+ transactionId: this._transactionId,
363
+ query: this._fieldFilters
364
+ }
365
+
366
+ const res: DeleteResult | TcbError = await this._request.send(DELETE_DOC, param)
367
+ if ((res as TcbError).code) throw res
368
+
369
+ return {
370
+ ...res,
371
+ deleted: EJSON.parse((res as DeleteResult).deleted as any) as any
372
+ }
20
373
  }
21
374
  }