Scala: while comprehension

In scala, you can do for comprehensions like so:

import scala.collection.JavaConverters._

for (x <- myCollection) 
  yield x.someFunction

Weirdly you can't do this:

while (myCollection.hasNext) 
  yield x.next

This is a common problem with JDBC - ideally the language should let you do this:

val query = """
  | select col1, col2 from my_table;
"""

val resultSet = runQuery(query)
val results: Iterable[Iterable[String]] =
  while (resultSet.hasNext) 
    resultSet.columns.map(
      (columnName) => 
        resultSet.get(columnName)
    )

Obviously this doesn't work, or you wouldn't be here.

To do this the scala way, you can use "Iterator.continually", like so:

import scala.collection.JavaConverters._

val data =
  Iterator.continually {
    resultSet.next()
  }.takeWhile(
    (x) => x
  ).map(
    (x) => {
      resultSet.getColumnNames.asScala.map(
        (x) => resultSet.getString(x)
      )
    }
  )

This will give you the dataset you wanted - you can also remove the types from the above example, they are included so that this is easier to understand.

You can also wrap the above command in a try {}. If you do this, you may wish to realize the results right away, by adding a ".toList" at the end of the collection, so that you don't hold on to an iterator that is operating on a closed database connection.

One Reply to “Scala: while comprehension”

Leave a Reply

Your email address will not be published. Required fields are marked *