Skip to content

QueryToken 的设计笔记 #5

@Brooooooklyn

Description

@Brooooooklyn

按照设计,ReactiveDB 中 Database 类的 get 方法将会返回一个 QueryToken 对象,它是通过 Observable<Selector> 构造的。
这个对象并不直接包含查询的结果,而是提供 values, changes, concatcombine 四个方法供调用者使用。

QueryToken 有两个状态,初始状态和被消费状态,QueryToken 从一个状态转移到另一个状态后状态再不可改变。

valueschanges 方法都会使 QueryToken 从初始状态变为被消费状态。对一个被消费过的 QueryToken 调用这两个方法中的其中一个会抛出异常。
concat 方法则是将两个 任意状态QueryToken 合并成一个新的初始状态的 QueryToken
旧的两个 QueryToken 将会被自动销毁。

这几个方法的实现:

  • values 方法返回一个只包含一个值的 Observable
  • changes 方法则是监听一个 query 并返回一个包含 N 个值的 Observable

这两个方法使用 lovefield 可以很容易实现。

concatcombine 方法单独使用 lovefield 的接口无法直接实现。

concat 方法的行为是将两个 select, predicatelimit 部分相同,但 skip 不同的 query 合并为一个 query,并且可以对这个新的 query 进行 valueschanges 操作。(query = select + where + limit + skip)

实现的思路是:
queryselect, predicate, limitskip 部分拆分成多个属性存在 Selector 类中,取值的时候总是复制 select 与 predicate (select 是类 jQuery 的链式调用,调用过 where 后会改变自身的状态)

select.clone()
  .where(predicate.copy())
  .exec()

concat 的时候先判断 select, predicatelimit 是否相同:

const equal = selectMetas.every(m =>
  m.limit === this.limit &&
  m.select === this.select &&
  m.predicateProvider.toString() === this.predicateProvider.toString()
)
if (!equal) throw TOKEN_CONCAT_ERR()

concat 实质上是取两个 QueryToken limit 的总和

这样就能产生新的 Observable<Selector>,再通过这个 Observable<Selector> 产生新的 QueryToken 并返回。

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions