I am trying to follow the Asynchronous iterators example from the wiki
Am getting the following error:
value slice is not a member of play.api.libs.iteratee.Enumerator
Any input into what the issue is greatly appreciated.
This is so that I can paginate results from a large collection
libraryDependencies ++= Seq(
"com.websudos" %% "phantom-dsl" % 1.22.0,
"com.websudos" %% "phantom-reactivestreams" % 1.22.0
)
import com.datastax.driver.core.{ResultSet, Row}
import com.websudos.phantom.CassandraTable
import com.websudos.phantom.dsl._
import com.websudos.phantom.iteratee.Iteratee
import org.dyne.danielsan.openblockchain.data.entity.Block
import scala.concurrent.Future
import com.websudos.phantom.reactivestreams._
import scala.concurrent.Await
import scala.concurrent.duration._
sealed class BlocksModel extends CassandraTable[BlocksModel, Block] {
override def fromRow(row: Row): Block = {
Block(
hash(row),
height(row)
}
object hash extends StringColumn(this) with PartitionKey[String]
object height extends IntColumn(this) with ClusteringOrder[Int] with Descending
object order_id extends LongColumn(this) with ClusteringOrder[Long] with Descending
abstract class ConcreteBlocksModel extends BlocksModel with RootConnector {
override val tableName = "blocks"
def getBlocks(start: Int, limit: Int): Future[Set[Block]] = {
select.fetchEnumerator.slice(start, limit).collect
}
}
Slightly wrong syntax, when you want to use methods on enumerator here's what you need:
abstract class ConcreteBlocksModel extends BlocksModel with RootConnector {
override val tableName = "blocks"
def getBlocks(start: Int, limit: Int): Future[Iterator[Block]] = {
select.fetchEnumerator run Iterator.slice(start, limit)
}
}
If you want to paginate your records, there's a different way to do that in Cassandra with automated pagination though.
def getPage(limit: Int, paging: Option[PagingState] = None): Future[ListResult[JodaRow]] = {
select.limit(limit).fetchRecord(paging)
}
And basically you need to provide a paging state for the next query to run. The Future
now being returned will have a ListResult
item inside of it, which means you get 2 methods:
def records: List[R] // the list of records from the db, just like fetch()
def pagingState: PagingState // the state you care about.
Basically pagingState
has a toString
method which will give you back a token you will need to store on the client side. When the user wants to get "the next page", you need to provide the pagingState
string from the previous page, think of the paging state as a pointer to a particular location in the Cassandra table, so that way Cassandra knows how to "jump" or "skip pages".
So your next API call, assuming you start from page 0, should include a pagingState
as a string.
You can then you PagingState.fromString(pagingState)
and pass the result of this to get the "next page".
I will add an example of this in phantom, but this should basically solve your current problem.