Functional programming rocks. However, legacy Java libraries prevent us to stay in such an ideal world. The job objective of Scaloid is to help write Android code in more elegant style. Although Scaloid doing good job on layout building, I haven't do much things about databases yet.

There are many DB frameworks for Scala. If you writing an app relying on DB extensively, I recommend to use one of them. But when you are using the built-in Sqlite just for storing some casual data, it is not a bad idea that using Android APIs for database access. The biggest problem in this case is that the code is not neat, because of its API architecture. Let's see a common example:

We have to use variable for the return object because the android.database.Cursor does not provide Scala-compatible iterator. Another clutter is close() call in try-finally section. This can be reduced in more functional-style:

By declaring implicit def cursor2RichCursor(c: Cursor) = new RichCursor(c), or extending the trait org.scaloid.common.DatabaseImplicits to your class, The android.database.Cursor implicitly converted into RichCursor, which implements Iterable[Cursor]. Now, we can use many useful iterator methods such as map, foreach, and foldLeft.

I also introduce a function closeAfter[T](body: RichCursor => T):T that closes the cursor after evaluating its parameter.

One of the important thing that can be missed is to convert the mapped result into a List. Iterator.map returns another Iterator that evaluate the original iterator(RichCursor in this case) on demand. The implementation of Iterator.map looks like this:

So if we missed to convert the iterator to List or other form, newly created Iterator generated from the mapping will evaluate the Cursor that is already closed, and vomit the exception. This issue is too detailed, and very easy to miss at first. What we just need is iterate each rows and map a row with a domain object, and forget about cursor. So I created a wrapper function that does this mission simply:

As the name of the function implies, it does very simple form of Object-Relation-Mapping.

In other cases, we often need just one record from the query result. For example, getting count of something, or retrieving some column about a particular user. Even such a simple requirement, we have to write a verbose code as: