@cloudbase/database 1.4.3 → 1.5.0
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/dist/commonjs/ObjectId/index.d.ts +1 -1
- package/dist/commonjs/ObjectId/index.js +16 -9
- package/dist/commonjs/aggregate.js +126 -75
- package/dist/commonjs/collection.d.ts +3 -2
- package/dist/commonjs/collection.js +131 -58
- package/dist/commonjs/command.d.ts +5 -5
- package/dist/commonjs/command.js +181 -154
- package/dist/commonjs/commands/logic.js +30 -20
- package/dist/commonjs/commands/query.d.ts +1 -1
- package/dist/commonjs/commands/query.js +85 -65
- package/dist/commonjs/commands/update.js +9 -7
- package/dist/commonjs/config/error.config.js +1 -0
- package/dist/commonjs/const/code.js +1 -0
- package/dist/commonjs/constant.d.ts +7 -7
- package/dist/commonjs/constant.js +13 -11
- package/dist/commonjs/document.d.ts +10 -6
- package/dist/commonjs/document.js +305 -193
- package/dist/commonjs/geo/index.js +20 -9
- package/dist/commonjs/geo/lineString.d.ts +1 -1
- package/dist/commonjs/geo/lineString.js +62 -33
- package/dist/commonjs/geo/multiLineString.d.ts +1 -1
- package/dist/commonjs/geo/multiLineString.js +71 -32
- package/dist/commonjs/geo/multiPoint.d.ts +1 -1
- package/dist/commonjs/geo/multiPoint.js +58 -29
- package/dist/commonjs/geo/multiPolygon.d.ts +1 -1
- package/dist/commonjs/geo/multiPolygon.js +96 -36
- package/dist/commonjs/geo/point.d.ts +1 -1
- package/dist/commonjs/geo/point.js +30 -23
- package/dist/commonjs/geo/polygon.d.ts +1 -1
- package/dist/commonjs/geo/polygon.js +78 -39
- package/dist/commonjs/helper/symbol.js +17 -5
- package/dist/commonjs/index.d.ts +8 -2
- package/dist/commonjs/index.js +73 -20
- package/dist/commonjs/lib/util.d.ts +1 -0
- package/dist/commonjs/lib/util.js +26 -0
- package/dist/commonjs/operator-map.js +7 -6
- package/dist/commonjs/query.d.ts +8 -4
- package/dist/commonjs/query.js +308 -201
- package/dist/commonjs/regexp/index.d.ts +1 -1
- package/dist/commonjs/regexp/index.js +16 -9
- package/dist/commonjs/serializer/common.d.ts +2 -2
- package/dist/commonjs/serializer/common.js +59 -22
- package/dist/commonjs/serializer/datatype.d.ts +2 -2
- package/dist/commonjs/serializer/datatype.js +58 -21
- package/dist/commonjs/serializer/query.d.ts +1 -1
- package/dist/commonjs/serializer/query.js +137 -127
- package/dist/commonjs/serializer/update.d.ts +1 -1
- package/dist/commonjs/serializer/update.js +83 -78
- package/dist/commonjs/serverDate/index.d.ts +1 -1
- package/dist/commonjs/serverDate/index.js +16 -9
- package/dist/commonjs/transaction/collection.d.ts +7 -0
- package/dist/commonjs/transaction/collection.js +49 -0
- package/dist/commonjs/transaction/document.d.ts +27 -0
- package/dist/commonjs/transaction/document.js +205 -0
- package/dist/commonjs/transaction/index.js +196 -86
- package/dist/commonjs/transaction/query.d.ts +43 -0
- package/dist/commonjs/transaction/query.js +261 -0
- package/dist/commonjs/typings/index.d.ts +4 -4
- package/dist/commonjs/typings/realtime.d.ts +16 -16
- package/dist/commonjs/util.js +123 -92
- package/dist/commonjs/utils/error.d.ts +2 -1
- package/dist/commonjs/utils/error.js +74 -38
- package/dist/commonjs/utils/symbol.js +33 -14
- package/dist/commonjs/utils/type.d.ts +1 -1
- package/dist/commonjs/utils/type.js +25 -13
- package/dist/commonjs/utils/utils.d.ts +4 -1
- package/dist/commonjs/utils/utils.js +93 -22
- package/dist/commonjs/validate.js +79 -63
- package/dist/esm/ObjectId/index.d.ts +1 -1
- package/dist/esm/ObjectId/index.js +15 -8
- package/dist/esm/aggregate.js +118 -66
- package/dist/esm/collection.d.ts +3 -2
- package/dist/esm/collection.js +125 -52
- package/dist/esm/command.d.ts +5 -5
- package/dist/esm/command.js +175 -147
- package/dist/esm/commands/logic.js +30 -20
- package/dist/esm/commands/query.d.ts +1 -1
- package/dist/esm/commands/query.js +91 -71
- package/dist/esm/commands/update.js +8 -6
- package/dist/esm/config/error.config.js +1 -1
- package/dist/esm/const/code.js +1 -1
- package/dist/esm/constant.d.ts +7 -7
- package/dist/esm/constant.js +12 -11
- package/dist/esm/document.d.ts +10 -6
- package/dist/esm/document.js +297 -185
- package/dist/esm/geo/interface.js +1 -0
- package/dist/esm/geo/lineString.d.ts +1 -1
- package/dist/esm/geo/lineString.js +57 -28
- package/dist/esm/geo/multiLineString.d.ts +1 -1
- package/dist/esm/geo/multiLineString.js +66 -27
- package/dist/esm/geo/multiPoint.d.ts +1 -1
- package/dist/esm/geo/multiPoint.js +53 -24
- package/dist/esm/geo/multiPolygon.d.ts +1 -1
- package/dist/esm/geo/multiPolygon.js +91 -31
- package/dist/esm/geo/point.d.ts +1 -1
- package/dist/esm/geo/point.js +26 -19
- package/dist/esm/geo/polygon.d.ts +1 -1
- package/dist/esm/geo/polygon.js +73 -34
- package/dist/esm/helper/symbol.js +13 -13
- package/dist/esm/index.d.ts +8 -2
- package/dist/esm/index.js +62 -9
- package/dist/esm/lib/util.d.ts +1 -0
- package/dist/esm/lib/util.js +22 -0
- package/dist/esm/operator-map.js +4 -4
- package/dist/esm/query.d.ts +8 -4
- package/dist/esm/query.js +299 -192
- package/dist/esm/regexp/index.d.ts +1 -1
- package/dist/esm/regexp/index.js +15 -8
- package/dist/esm/serializer/common.d.ts +2 -2
- package/dist/esm/serializer/common.js +49 -13
- package/dist/esm/serializer/datatype.d.ts +2 -2
- package/dist/esm/serializer/datatype.js +44 -8
- package/dist/esm/serializer/query.d.ts +1 -1
- package/dist/esm/serializer/query.js +112 -102
- package/dist/esm/serializer/update.d.ts +1 -1
- package/dist/esm/serializer/update.js +69 -64
- package/dist/esm/serverDate/index.d.ts +1 -1
- package/dist/esm/serverDate/index.js +15 -8
- package/dist/esm/transaction/collection.d.ts +7 -0
- package/dist/esm/transaction/collection.js +46 -0
- package/dist/esm/transaction/document.d.ts +27 -0
- package/dist/esm/transaction/document.js +202 -0
- package/dist/esm/transaction/index.js +191 -81
- package/dist/esm/transaction/query.d.ts +43 -0
- package/dist/esm/transaction/query.js +258 -0
- package/dist/esm/typings/index.d.ts +4 -4
- package/dist/esm/typings/index.js +1 -0
- package/dist/esm/typings/realtime.d.ts +16 -16
- package/dist/esm/typings/realtime.js +1 -0
- package/dist/esm/util.js +121 -90
- package/dist/esm/utils/error.d.ts +2 -1
- package/dist/esm/utils/error.js +70 -35
- package/dist/esm/utils/symbol.js +33 -14
- package/dist/esm/utils/type.d.ts +1 -1
- package/dist/esm/utils/type.js +12 -12
- package/dist/esm/utils/utils.d.ts +4 -1
- package/dist/esm/utils/utils.js +78 -16
- package/dist/esm/validate.js +65 -49
- package/jest.config.js +14 -0
- package/package.json +14 -10
- package/src/aggregate.ts +1 -5
- package/src/collection.ts +15 -2
- package/src/document.ts +45 -34
- package/src/index.ts +51 -4
- package/src/query.ts +33 -29
- package/src/serializer/query.ts +18 -6
- package/src/transaction/index.ts +1 -1
- package/src/typings/index.ts +0 -4
- package/src/utils/utils.ts +46 -0
- package/src/validate.ts +3 -6
- package/tests/gateway-contract.test.ts +180 -0
- package/tests/index.test.ts +283 -0
- package/tests/transaction-query.test.ts +207 -0
- package/tsconfig.esm.json +4 -2
- package/tsconfig.json +16 -6
- package/tsconfig.test.json +15 -0
- package/dist/commonjs/realtime/error.d.ts +0 -7
- package/dist/commonjs/realtime/error.js +0 -11
- package/dist/commonjs/realtime/listener.d.ts +0 -14
- package/dist/commonjs/realtime/listener.js +0 -17
- package/dist/commonjs/realtime/message.d.ts +0 -3
- package/dist/commonjs/realtime/message.js +0 -10
- package/dist/commonjs/realtime/snapshot.d.ts +0 -16
- package/dist/commonjs/realtime/snapshot.js +0 -42
- package/dist/commonjs/realtime/virtual-websocket-client.d.ts +0 -63
- package/dist/commonjs/realtime/virtual-websocket-client.js +0 -736
- package/dist/commonjs/realtime/websocket-client.d.ts +0 -78
- package/dist/commonjs/realtime/websocket-client.js +0 -567
- package/dist/commonjs/realtime/ws-event.d.ts +0 -126
- package/dist/commonjs/realtime/ws-event.js +0 -139
- package/dist/commonjs/transaction.d.ts +0 -42
- package/dist/commonjs/transaction.js +0 -126
- package/dist/esm/realtime/error.d.ts +0 -7
- package/dist/esm/realtime/error.js +0 -8
- package/dist/esm/realtime/listener.d.ts +0 -14
- package/dist/esm/realtime/listener.js +0 -14
- package/dist/esm/realtime/message.d.ts +0 -3
- package/dist/esm/realtime/message.js +0 -6
- package/dist/esm/realtime/snapshot.d.ts +0 -16
- package/dist/esm/realtime/snapshot.js +0 -39
- package/dist/esm/realtime/virtual-websocket-client.d.ts +0 -63
- package/dist/esm/realtime/virtual-websocket-client.js +0 -733
- package/dist/esm/realtime/websocket-client.d.ts +0 -78
- package/dist/esm/realtime/websocket-client.js +0 -564
- package/dist/esm/realtime/ws-event.d.ts +0 -126
- package/dist/esm/realtime/ws-event.js +0 -137
- package/dist/esm/transaction.d.ts +0 -42
- package/dist/esm/transaction.js +0 -121
- package/src/realtime/error.ts +0 -19
- package/src/realtime/listener.ts +0 -35
- package/src/realtime/message.ts +0 -14
- package/src/realtime/snapshot.ts +0 -60
- package/src/realtime/virtual-websocket-client.ts +0 -1195
- package/src/realtime/websocket-client.ts +0 -995
- package/src/realtime/ws-event.ts +0 -163
- package/src/transaction.ts +0 -190
package/src/index.ts
CHANGED
|
@@ -5,8 +5,16 @@ import { Command } from './command'
|
|
|
5
5
|
import { ServerDateConstructor } from './serverDate/index'
|
|
6
6
|
import { RegExpConstructor } from './regexp/index'
|
|
7
7
|
import { startTransaction, runTransaction } from './transaction/index'
|
|
8
|
+
import { LogicCommand } from './commands/logic'
|
|
9
|
+
import { QueryCommand } from './commands/query'
|
|
10
|
+
import { UpdateCommand } from './commands/update'
|
|
8
11
|
import { ObjectIdConstructor } from './ObjectId/index'
|
|
9
12
|
|
|
13
|
+
/**
|
|
14
|
+
* 数据库配置接口(兼容旧名,实际为完整的 CloudBase 配置)
|
|
15
|
+
*/
|
|
16
|
+
export type IDbConfig = ICloudBaseConfig
|
|
17
|
+
|
|
10
18
|
/**
|
|
11
19
|
* 地理位置类型
|
|
12
20
|
*/
|
|
@@ -18,7 +26,7 @@ export { Query } from './query'
|
|
|
18
26
|
export { CollectionReference } from './collection'
|
|
19
27
|
export { DocumentReference } from './document'
|
|
20
28
|
|
|
21
|
-
interface ICloudBaseConfig {
|
|
29
|
+
export interface ICloudBaseConfig {
|
|
22
30
|
timeout?: number
|
|
23
31
|
isHttp?: boolean
|
|
24
32
|
secretId?: string
|
|
@@ -68,12 +76,18 @@ export class Db {
|
|
|
68
76
|
|
|
69
77
|
runTransaction: any
|
|
70
78
|
|
|
79
|
+
logicCommand: any
|
|
80
|
+
|
|
81
|
+
updateCommand: any
|
|
82
|
+
|
|
83
|
+
queryCommand: any
|
|
84
|
+
|
|
71
85
|
/**
|
|
72
86
|
* 初始化
|
|
73
87
|
*
|
|
74
88
|
* 默认是 `default` 数据库,为今后扩展使用
|
|
75
89
|
*
|
|
76
|
-
* @param config
|
|
90
|
+
* @param config - 数据库配置
|
|
77
91
|
*/
|
|
78
92
|
config: ICloudBaseConfig
|
|
79
93
|
|
|
@@ -83,6 +97,8 @@ export class Db {
|
|
|
83
97
|
|
|
84
98
|
static wsClass: any
|
|
85
99
|
|
|
100
|
+
static wsClientClass: any
|
|
101
|
+
|
|
86
102
|
// 创建签名的工具函数,由jssdk传入
|
|
87
103
|
static createSign: Function
|
|
88
104
|
|
|
@@ -94,7 +110,33 @@ export class Db {
|
|
|
94
110
|
// 应用签名信息,由jssdk传入
|
|
95
111
|
static appSecretInfo: any
|
|
96
112
|
|
|
97
|
-
|
|
113
|
+
// 创建请求实例的包装方法,自动添加instance和database参数
|
|
114
|
+
static createRequest(config: ICloudBaseConfig): any {
|
|
115
|
+
const request = new Db.reqClass(config)
|
|
116
|
+
const originalSend = request.send
|
|
117
|
+
|
|
118
|
+
// 包装send方法,自动添加instance和database参数;
|
|
119
|
+
// 剩余参数(如 2.0 引擎的 getReqOpts,含 per-request timeout)原样透传
|
|
120
|
+
request.send = function(action: string, data: any, ...args: any[]): any {
|
|
121
|
+
// data 可能为空(如事务 startTransaction 不带参数),注入前需防护
|
|
122
|
+
if (data) {
|
|
123
|
+
// 如果配置中包含instance或database参数,添加到请求数据中
|
|
124
|
+
if (config.instance) {
|
|
125
|
+
data.instance = config.instance
|
|
126
|
+
}
|
|
127
|
+
if (config.database) {
|
|
128
|
+
data.database = config.database
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 调用原始的send方法
|
|
133
|
+
return originalSend.call(this, action, data, ...args)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return request
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
constructor(config?: ICloudBaseConfig) {
|
|
98
140
|
this.config = config
|
|
99
141
|
this.Geo = Geo
|
|
100
142
|
this.serverDate = ServerDateConstructor
|
|
@@ -103,6 +145,11 @@ export class Db {
|
|
|
103
145
|
this.ObjectId = ObjectIdConstructor
|
|
104
146
|
this.startTransaction = startTransaction
|
|
105
147
|
this.runTransaction = runTransaction
|
|
148
|
+
|
|
149
|
+
// 暴露command类 给新sdk灰度兼容用
|
|
150
|
+
this.logicCommand = LogicCommand
|
|
151
|
+
this.updateCommand = UpdateCommand
|
|
152
|
+
this.queryCommand = QueryCommand
|
|
106
153
|
}
|
|
107
154
|
|
|
108
155
|
/**
|
|
@@ -121,7 +168,7 @@ export class Db {
|
|
|
121
168
|
* 创建集合
|
|
122
169
|
*/
|
|
123
170
|
createCollection(collName: string) {
|
|
124
|
-
let request =
|
|
171
|
+
let request = Db.createRequest(this.config)
|
|
125
172
|
|
|
126
173
|
const params = {
|
|
127
174
|
collectionName: collName
|
package/src/query.ts
CHANGED
|
@@ -9,9 +9,8 @@ import { QuerySerializer } from './serializer/query'
|
|
|
9
9
|
import { UpdateSerializer } from './serializer/update'
|
|
10
10
|
// import { WSClient } from "./websocket/wsclient"
|
|
11
11
|
import { IWatchOptions, DBRealtimeListener } from './typings/index'
|
|
12
|
-
import { RealtimeWebSocketClient } from './realtime/websocket-client'
|
|
13
12
|
import { ErrorCode } from './constant'
|
|
14
|
-
import { getReqOpts, stringifyByEJSON, processReturn } from './utils/utils'
|
|
13
|
+
import { getWsInstance, getReqOpts, stringifyByEJSON, processReturn, withCallback } from './utils/utils'
|
|
15
14
|
import { ERRORS } from './const/code'
|
|
16
15
|
import { EJSON } from 'bson'
|
|
17
16
|
|
|
@@ -156,7 +155,7 @@ export class Query {
|
|
|
156
155
|
this._fieldFilters = fieldFilters
|
|
157
156
|
this._apiOptions = apiOptions || {}
|
|
158
157
|
/* eslint-disable new-cap */
|
|
159
|
-
this._request =
|
|
158
|
+
this._request = Db.createRequest(this._db.config)
|
|
160
159
|
this._transactionId = transactionId
|
|
161
160
|
}
|
|
162
161
|
|
|
@@ -166,7 +165,11 @@ export class Query {
|
|
|
166
165
|
* - 默认获取集合下全部文档数据
|
|
167
166
|
* - 可以把通过 `orderBy`、`where`、`skip`、`limit`设置的数据添加请求参数上
|
|
168
167
|
*/
|
|
169
|
-
public
|
|
168
|
+
public get(callback?: any): Promise<GetRes> {
|
|
169
|
+
return withCallback(this._get(), callback) as Promise<GetRes>
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private async _get(): Promise<GetRes> {
|
|
170
173
|
/* eslint-disable no-param-reassign */
|
|
171
174
|
|
|
172
175
|
const order = (this._apiOptions as QueryOption).order
|
|
@@ -176,7 +179,7 @@ export class Query {
|
|
|
176
179
|
transactionId?: string
|
|
177
180
|
query?: Object
|
|
178
181
|
queryType: QueryType
|
|
179
|
-
order?: string
|
|
182
|
+
order?: string
|
|
180
183
|
offset?: number
|
|
181
184
|
limit?: number
|
|
182
185
|
projection?: Object
|
|
@@ -200,14 +203,8 @@ export class Query {
|
|
|
200
203
|
if (offset) {
|
|
201
204
|
param.offset = offset
|
|
202
205
|
}
|
|
203
|
-
|
|
204
206
|
const limit = (this._apiOptions as QueryOption).limit
|
|
205
207
|
|
|
206
|
-
// if (this._queryOptions.limit) {
|
|
207
|
-
// param.limit = this._queryOptions.limit < 1000 ? this._queryOptions.limit : 1000
|
|
208
|
-
// } else {
|
|
209
|
-
// param.limit = 100
|
|
210
|
-
// }
|
|
211
208
|
if (limit) {
|
|
212
209
|
param.limit = limit < 1000 ? limit : 1000
|
|
213
210
|
} else {
|
|
@@ -252,7 +249,11 @@ export class Query {
|
|
|
252
249
|
/**
|
|
253
250
|
* 获取总数
|
|
254
251
|
*/
|
|
255
|
-
public
|
|
252
|
+
public count(callback?: any) {
|
|
253
|
+
return withCallback(this._count(), callback)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private async _count() {
|
|
256
257
|
interface Param {
|
|
257
258
|
collectionName: string
|
|
258
259
|
query?: Object
|
|
@@ -348,7 +349,6 @@ export class Query {
|
|
|
348
349
|
const order = (this._apiOptions as QueryOption).order || {}
|
|
349
350
|
|
|
350
351
|
const newApiOption = Object.assign({}, this._apiOptions, {
|
|
351
|
-
// order: order.concat(newOrder)
|
|
352
352
|
order: Object.assign({}, order, newOrder)
|
|
353
353
|
})
|
|
354
354
|
|
|
@@ -390,7 +390,11 @@ export class Query {
|
|
|
390
390
|
*
|
|
391
391
|
* @param data 数据
|
|
392
392
|
*/
|
|
393
|
-
public
|
|
393
|
+
public update(data: Object, callback?: any): Promise<any> {
|
|
394
|
+
return withCallback(this._update(data), callback)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private async _update(data: Object): Promise<any> {
|
|
394
398
|
if (!data || typeof data !== 'object') {
|
|
395
399
|
return processReturn(this._db.config.throwOnCode, {
|
|
396
400
|
...ERRORS.INVALID_PARAM,
|
|
@@ -419,6 +423,10 @@ export class Query {
|
|
|
419
423
|
data: UpdateSerializer.encodeEJSON(data, this._apiOptions.raw || false)
|
|
420
424
|
}
|
|
421
425
|
|
|
426
|
+
if (this._transactionId) {
|
|
427
|
+
param.transactionId = this._transactionId
|
|
428
|
+
}
|
|
429
|
+
|
|
422
430
|
if (this._fieldFilters) {
|
|
423
431
|
param.query = this._fieldFilters
|
|
424
432
|
}
|
|
@@ -481,7 +489,11 @@ export class Query {
|
|
|
481
489
|
/**
|
|
482
490
|
* 条件删除文档
|
|
483
491
|
*/
|
|
484
|
-
public
|
|
492
|
+
public remove(callback?: any) {
|
|
493
|
+
return withCallback(this._remove(), callback)
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
private async _remove() {
|
|
485
497
|
// if (Object.keys(this._queryOptions).length > 0) {
|
|
486
498
|
// console.warn('`offset`, `limit` and `projection` are not supported in remove() operation')
|
|
487
499
|
// }
|
|
@@ -504,12 +516,15 @@ export class Query {
|
|
|
504
516
|
let { multiple } = this._apiOptions as UpdateOption
|
|
505
517
|
const multi = multiple === undefined ? true : multiple // where remove 不传multi默认为true
|
|
506
518
|
|
|
507
|
-
const param = {
|
|
519
|
+
const param: any = {
|
|
508
520
|
collectionName: this._coll,
|
|
509
521
|
query: this._fieldFilters,
|
|
510
522
|
queryType: QueryType.WHERE,
|
|
511
523
|
multi
|
|
512
524
|
}
|
|
525
|
+
if (this._transactionId) {
|
|
526
|
+
param.transactionId = this._transactionId
|
|
527
|
+
}
|
|
513
528
|
const res = await this._request.send(
|
|
514
529
|
'database.removeDocument',
|
|
515
530
|
param,
|
|
@@ -579,22 +594,11 @@ export class Query {
|
|
|
579
594
|
* 监听query对应的doc变化
|
|
580
595
|
*/
|
|
581
596
|
watch = (options: IWatchOptions): DBRealtimeListener => {
|
|
582
|
-
|
|
583
|
-
Db.ws = new RealtimeWebSocketClient({
|
|
584
|
-
context: {
|
|
585
|
-
appConfig: {
|
|
586
|
-
docSizeLimit: 1000,
|
|
587
|
-
realtimePingInterval: 10000,
|
|
588
|
-
realtimePongWaitTimeout: 5000,
|
|
589
|
-
request: this._request
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
})
|
|
593
|
-
}
|
|
597
|
+
const ws = getWsInstance(this._db)
|
|
594
598
|
|
|
595
599
|
const { limit, order } = this._apiOptions as QueryOption
|
|
596
600
|
|
|
597
|
-
return
|
|
601
|
+
return ws.watch({
|
|
598
602
|
...options,
|
|
599
603
|
envId: this._db.config.env,
|
|
600
604
|
collectionName: this._coll,
|
package/src/serializer/query.ts
CHANGED
|
@@ -4,15 +4,27 @@ import {
|
|
|
4
4
|
QUERY_COMMANDS_LITERAL,
|
|
5
5
|
QueryCommand
|
|
6
6
|
} from '../commands/query'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
isLogicCommand,
|
|
9
|
+
LOGIC_COMMANDS_LITERAL,
|
|
10
|
+
LogicCommand
|
|
11
|
+
} from '../commands/logic'
|
|
8
12
|
import { SYMBOL_UNSET_FIELD_NAME, SYMBOL_GEO_POINT } from '../helper/symbol'
|
|
9
13
|
import { getType, isObject, isArray, isRegExp, isDate } from '../utils/type'
|
|
10
14
|
import { operatorToString } from '../operator-map'
|
|
11
|
-
import {
|
|
12
|
-
|
|
15
|
+
import {
|
|
16
|
+
flattenQueryObject,
|
|
17
|
+
isConversionRequired,
|
|
18
|
+
encodeInternalDataType
|
|
19
|
+
} from './common'
|
|
20
|
+
import {
|
|
21
|
+
IGeoNearOptions,
|
|
22
|
+
IGeoWithinOptions,
|
|
23
|
+
IGeoIntersectsOptions
|
|
24
|
+
} from '../commands/query'
|
|
13
25
|
import { stringifyByEJSON } from '../utils/utils'
|
|
14
26
|
import { Validate } from '../validate'
|
|
15
|
-
import { Point } from '../geo'
|
|
27
|
+
import { Point } from '../geo/index'
|
|
16
28
|
|
|
17
29
|
export type IQueryCondition = Record<string, any> | LogicCommand
|
|
18
30
|
|
|
@@ -39,10 +51,10 @@ class QueryEncoder {
|
|
|
39
51
|
} else if (isQueryCommand(query)) {
|
|
40
52
|
return this.encodeQueryCommand(query)
|
|
41
53
|
} else if (isRegExp(query)) {
|
|
42
|
-
//
|
|
54
|
+
// /xxx/ 形式
|
|
43
55
|
return { [key]: this.encodeRegExp(query) }
|
|
44
56
|
} else if (isDate(query)) {
|
|
45
|
-
return { [key]: query }
|
|
57
|
+
return { [key]: encodeInternalDataType(query) }
|
|
46
58
|
} else {
|
|
47
59
|
return { [key]: this.encodeQueryObject(query) }
|
|
48
60
|
}
|
package/src/transaction/index.ts
CHANGED
package/src/typings/index.ts
CHANGED
package/src/utils/utils.ts
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
|
+
import { Db } from '../'
|
|
1
2
|
import { QueryOption, UpdateOption } from '../query'
|
|
2
3
|
import { EJSON } from 'bson'
|
|
3
4
|
import { isObject } from './type'
|
|
4
5
|
|
|
5
6
|
export const sleep = (ms: number = 0) => new Promise(r => setTimeout(r, ms))
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* 兼容旧版 callback 调用风格(对齐 0.12.x 行为):
|
|
10
|
+
* - 传入 callback:成功时 callback(0, result)、失败时 callback(err),方法返回 undefined
|
|
11
|
+
* - 不传 callback:原样返回 promise
|
|
12
|
+
*
|
|
13
|
+
* 注意用 then(f, g) 而非 then(f).catch(g),保证派生 promise 为 resolved,
|
|
14
|
+
* 避免 callback 模式下产生 unhandled rejection。
|
|
15
|
+
*/
|
|
16
|
+
export function withCallback<T>(promise: Promise<T>, callback?: any): Promise<T> | undefined {
|
|
17
|
+
if (typeof callback === 'function') {
|
|
18
|
+
promise.then(
|
|
19
|
+
(res: any) => callback(0, res),
|
|
20
|
+
(err: any) => callback(err)
|
|
21
|
+
)
|
|
22
|
+
return undefined
|
|
23
|
+
}
|
|
24
|
+
return promise
|
|
25
|
+
}
|
|
26
|
+
|
|
7
27
|
const counters: Record<string, number> = {}
|
|
8
28
|
|
|
9
29
|
export const autoCount = (domain: string = 'any'): number => {
|
|
@@ -13,6 +33,32 @@ export const autoCount = (domain: string = 'any'): number => {
|
|
|
13
33
|
return counters[domain]++
|
|
14
34
|
}
|
|
15
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 工厂模式创建 ws 实例
|
|
38
|
+
*/
|
|
39
|
+
const wsList = {}
|
|
40
|
+
export function getWsInstance(db: Db) {
|
|
41
|
+
if(!Db.wsClientClass){
|
|
42
|
+
throw new Error('to use realtime you must import realtime module first')
|
|
43
|
+
}
|
|
44
|
+
const { env } = db.config
|
|
45
|
+
|
|
46
|
+
if (!wsList[env]) {
|
|
47
|
+
wsList[env] = new Db.wsClientClass({
|
|
48
|
+
context: {
|
|
49
|
+
appConfig: {
|
|
50
|
+
docSizeLimit: 1000,
|
|
51
|
+
realtimePingInterval: 10000,
|
|
52
|
+
realtimePongWaitTimeout: 5000,
|
|
53
|
+
request: Db.createRequest(db.config)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return wsList[env]
|
|
60
|
+
}
|
|
61
|
+
|
|
16
62
|
export const getReqOpts = (apiOptions: QueryOption | UpdateOption): any => {
|
|
17
63
|
// 影响底层request的暂时只有timeout
|
|
18
64
|
if (apiOptions.timeout !== undefined) {
|
package/src/validate.ts
CHANGED
|
@@ -11,9 +11,8 @@ import { QueryOption, UpdateOption } from './query'
|
|
|
11
11
|
import { ERRORS } from './const/code'
|
|
12
12
|
import { E } from './utils/utils'
|
|
13
13
|
import { getType } from './utils/type'
|
|
14
|
-
import { Point } from './geo'
|
|
14
|
+
import { Point } from './geo/index'
|
|
15
15
|
import { CenterSphere } from './typings'
|
|
16
|
-
|
|
17
16
|
import { SYMBOL_GEO_POINT } from './helper/symbol'
|
|
18
17
|
|
|
19
18
|
const validOptionsKeys = ['limit', 'offset', 'projection', 'order', 'multiple', 'timeout', 'raw']
|
|
@@ -243,11 +242,9 @@ export class Validate {
|
|
|
243
242
|
}
|
|
244
243
|
|
|
245
244
|
/**
|
|
245
|
+
* 校验 centerSphere 结构
|
|
246
246
|
*
|
|
247
|
-
* @
|
|
248
|
-
* @param {[Point, number]} param
|
|
249
|
-
* @returns {Boolean}
|
|
250
|
-
* @memberof Validate
|
|
247
|
+
* @param param - [Point, number] 或 [[number, number], number]
|
|
251
248
|
*/
|
|
252
249
|
static isCentersPhere(param: CenterSphere): Boolean {
|
|
253
250
|
if (Array.isArray(param) && param.length === 2) {
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { EJSON } from 'bson'
|
|
2
|
+
import { Db } from '../src/index'
|
|
3
|
+
import { Transaction } from '../src/transaction/index'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* GATEWAY 模式接口名契约测试
|
|
7
|
+
*
|
|
8
|
+
* js-sdk(packages/cloudbase/database/src/index.ts 的 gateWayFunc)在
|
|
9
|
+
* endPointMode === 'GATEWAY' 时按 action 名查表路由到 RESTful 网关,
|
|
10
|
+
* 表外的 action 会 fallback 到 super.send() 走老通道,导致网关被绕过。
|
|
11
|
+
*
|
|
12
|
+
* 本测试用与 js-sdk gateWayFunc 相同的接口名集合模拟 GATEWAY 分发,
|
|
13
|
+
* 验证 2.0 引擎发出的所有 action 都能命中映射表,
|
|
14
|
+
* 任何一侧改名/新增接口而另一侧未同步时,此测试会失败。
|
|
15
|
+
*/
|
|
16
|
+
describe('GATEWAY 模式接口名契约(与 js-sdk gateWayFunc 对齐)', () => {
|
|
17
|
+
// 与 js-sdk gateWayFunc 的 key 保持一致
|
|
18
|
+
const GATEWAY_ACTIONS = [
|
|
19
|
+
// 旧接口名(0.12.x 引擎)
|
|
20
|
+
'database.queryDocument',
|
|
21
|
+
'database.addDocument',
|
|
22
|
+
'database.updateDocument',
|
|
23
|
+
'database.deleteDocument',
|
|
24
|
+
'database.countDocument',
|
|
25
|
+
'database.addCollection',
|
|
26
|
+
'database.aggregate',
|
|
27
|
+
// 事务(新旧引擎同名)
|
|
28
|
+
'database.startTransaction',
|
|
29
|
+
'database.commitTransaction',
|
|
30
|
+
'database.abortTransaction',
|
|
31
|
+
'database.getInTransaction',
|
|
32
|
+
'database.updateDocInTransaction',
|
|
33
|
+
'database.deleteDocInTransaction',
|
|
34
|
+
'database.insertDocInTransaction',
|
|
35
|
+
'database.runCommands',
|
|
36
|
+
// 新接口名(2.0 引擎,js-sdk gateWayFunc 已添加映射)
|
|
37
|
+
'database.getDocument',
|
|
38
|
+
'database.insertDocument',
|
|
39
|
+
'database.modifyDocument',
|
|
40
|
+
'database.removeDocument',
|
|
41
|
+
'database.calculateDocument',
|
|
42
|
+
'database.aggregateDocuments'
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
let hitActions: string[]
|
|
46
|
+
|
|
47
|
+
class MockGatewayReq {
|
|
48
|
+
async send(action: string) {
|
|
49
|
+
if (GATEWAY_ACTIONS.indexOf(action) < 0) {
|
|
50
|
+
throw new Error(`GATEWAY 模式下无此接口映射: ${action}`)
|
|
51
|
+
}
|
|
52
|
+
hitActions.push(action)
|
|
53
|
+
|
|
54
|
+
// 按接口返回 2.0 引擎期望的最小响应结构
|
|
55
|
+
switch (action) {
|
|
56
|
+
case 'database.getDocument':
|
|
57
|
+
return {
|
|
58
|
+
data: { list: [EJSON.stringify({ _id: 'doc1', name: 'Alice' })] },
|
|
59
|
+
requestId: 'gw-req-get'
|
|
60
|
+
}
|
|
61
|
+
case 'database.insertDocument':
|
|
62
|
+
return {
|
|
63
|
+
data: { insertedIds: ['new-id'] },
|
|
64
|
+
requestId: 'gw-req-insert'
|
|
65
|
+
}
|
|
66
|
+
case 'database.modifyDocument':
|
|
67
|
+
return {
|
|
68
|
+
data: { updated: 1, upsert_id: 'doc1' },
|
|
69
|
+
requestId: 'gw-req-modify'
|
|
70
|
+
}
|
|
71
|
+
case 'database.removeDocument':
|
|
72
|
+
return {
|
|
73
|
+
data: { deleted: 1 },
|
|
74
|
+
requestId: 'gw-req-remove'
|
|
75
|
+
}
|
|
76
|
+
case 'database.calculateDocument':
|
|
77
|
+
return {
|
|
78
|
+
data: { total: 5 },
|
|
79
|
+
requestId: 'gw-req-count'
|
|
80
|
+
}
|
|
81
|
+
case 'database.aggregateDocuments':
|
|
82
|
+
return {
|
|
83
|
+
data: { list: [EJSON.stringify({ total: 1 })] },
|
|
84
|
+
requestId: 'gw-req-agg'
|
|
85
|
+
}
|
|
86
|
+
case 'database.startTransaction':
|
|
87
|
+
return { transactionId: 'gw-tx-001' }
|
|
88
|
+
case 'database.commitTransaction':
|
|
89
|
+
case 'database.abortTransaction':
|
|
90
|
+
return { requestId: 'gw-req-tx' }
|
|
91
|
+
default:
|
|
92
|
+
return { data: { ok: 1 }, requestId: 'gw-req-default' }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
hitActions = []
|
|
99
|
+
Db.reqClass = MockGatewayReq as any
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
function createDb() {
|
|
103
|
+
return new Db({ env: 'test-env' })
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function createInitedTransaction(db: Db) {
|
|
107
|
+
const tx = new Transaction(db)
|
|
108
|
+
await tx.init()
|
|
109
|
+
return tx
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
it('collection CRUD 应全部命中网关映射表', async () => {
|
|
113
|
+
const db = createDb()
|
|
114
|
+
const coll = db.collection('users')
|
|
115
|
+
|
|
116
|
+
await coll.where({ age: 18 }).get()
|
|
117
|
+
await coll.where({ age: 18 }).count()
|
|
118
|
+
await coll.where({ age: 18 }).update({ age: 19 })
|
|
119
|
+
await coll.where({ age: 18 }).remove()
|
|
120
|
+
await coll.add({ name: 'New' })
|
|
121
|
+
await coll
|
|
122
|
+
.aggregate()
|
|
123
|
+
.match({ age: { $gt: 10 } })
|
|
124
|
+
.end()
|
|
125
|
+
|
|
126
|
+
expect(hitActions).toEqual([
|
|
127
|
+
'database.getDocument',
|
|
128
|
+
'database.calculateDocument',
|
|
129
|
+
'database.modifyDocument',
|
|
130
|
+
'database.removeDocument',
|
|
131
|
+
'database.insertDocument',
|
|
132
|
+
'database.aggregateDocuments'
|
|
133
|
+
])
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('document CRUD 应全部命中网关映射表', async () => {
|
|
137
|
+
const db = createDb()
|
|
138
|
+
const doc = db.collection('users').doc('doc1')
|
|
139
|
+
|
|
140
|
+
await doc.get()
|
|
141
|
+
await doc.create({ name: 'Alice' })
|
|
142
|
+
await doc.set({ name: 'Alice2' })
|
|
143
|
+
await doc.update({ name: 'Alice3' })
|
|
144
|
+
await doc.remove()
|
|
145
|
+
|
|
146
|
+
expect(hitActions).toEqual([
|
|
147
|
+
'database.getDocument',
|
|
148
|
+
'database.insertDocument',
|
|
149
|
+
'database.modifyDocument',
|
|
150
|
+
'database.modifyDocument',
|
|
151
|
+
'database.removeDocument'
|
|
152
|
+
])
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('事务操作应全部命中网关映射表', async () => {
|
|
156
|
+
const db = createDb()
|
|
157
|
+
const tx = await createInitedTransaction(db)
|
|
158
|
+
|
|
159
|
+
await tx.collection('users').where({ age: 18 }).get()
|
|
160
|
+
await tx.collection('users').where({ age: 18 }).update({ age: 19 })
|
|
161
|
+
await tx.collection('users').add({ name: 'TxNew' })
|
|
162
|
+
await tx.collection('users').doc('doc1').set({ name: 'TxSet' })
|
|
163
|
+
await tx.commit()
|
|
164
|
+
|
|
165
|
+
expect(hitActions).toEqual([
|
|
166
|
+
'database.startTransaction',
|
|
167
|
+
'database.getDocument',
|
|
168
|
+
'database.modifyDocument',
|
|
169
|
+
'database.insertDocument',
|
|
170
|
+
'database.modifyDocument',
|
|
171
|
+
'database.commitTransaction'
|
|
172
|
+
])
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('createCollection 应命中网关映射表', async () => {
|
|
176
|
+
const db = createDb()
|
|
177
|
+
await db.createCollection('new-coll')
|
|
178
|
+
expect(hitActions).toEqual(['database.addCollection'])
|
|
179
|
+
})
|
|
180
|
+
})
|