我在我的代码中看到了一个常见的模式。我已经对数据库中的结果进行了排序,我需要以嵌套结构发出它们。我希望它能够流式传输,因此我希望一次在内存中拥有尽可能少的记录。使用 TravesableLike.groupBy 假定数据未排序,因此它不必要地填充可变映射。我想保持这种真正的流媒体。scalaz-stream 在这里有用吗?
val sql = """select grandparent_id, parent_id, child_id
from children
where grandparent_id = ?
order by grandparent_id, parent_id, child_id"""
def elementsR[P, R](invoker: Invoker[P, R], param: P): Process[Task, R] =
// Invoker.elements returns trait CloseableIterator[+T] extends Iterator[T] with Closeable
resource(Task.delay(invoker.elements(param)))(
src => Task.delay(src.close)) { src =>
Task.delay { if (src.hasNext) src.next else throw End }
}
def dbWookie {
// grandparent_id, (grandparent_id, parent_id, child_id)
val invoker = Q.query[Int, (Int, Int, Int)](sql)
val es = elementsR(invoker, 42)
// ?, ?, ?
// nested emits (42, ((35, (1, 3, 7)), (36, (8, 9, 12))))
}
我没有在 Process 上看到太多函数,如 foldLeft 和 scanLeft,所以我不确定如何检测 grandparent_id、parent_id 或 child_id 何时更改并发出组。有任何想法吗?