Cool Monday - Exploration of dynamic db acces from scala
I use scala on Android and I don’t like the integrated database API. It’s very verbose and very stateful. I had written my own ORM(DAO would be a more appropriate tag) a while back, before I used scala but it’s not enough anymore. So now I’m on a quest for a better database API. My dream is something small that handles schema for me and is type-safe. A nice DSL that is converted to SQL at compile time and does code generation. So it’s fast like hand writing everything. But reduces code footprint by an order of magnitude(at least). Scala SLICK looks promising. It fits most requirements. But it’s kinda big for android projects(you need scala library too!) and has not yet hit a stable version so I wouldn’t be comfortable shipping it. Will definitely give it a thorough test when scala 2.10 is stable and SLICK is released. Oh, and it needs a third party JDBC driver for Android. This is another level of abstraction and therefore another source of slowness. I contemplated writing my own clone targeted at Android but never came around to actually doing it(yet!). It seems like a herculean task for single developer working in spare time.
Meanwhile
Yesterday I stared thinking how dynamic languages handle databases. And I got an idea. Scala has type Dynamic that does compilation magic to provide syntactic sugar for working with dynamic languages or objects. Here’s an idea: do queries in plain SQL and perform extraction of data in a dynamic way.
And how to do this? Just wrap up Cursor to provide necessary methods.
|
|
Why I need this? Cake pattern of course, Dynamic cursor get’s mixed in.
|
|
I targeted API level 14(Ice Cream Sandwich) since getType(method on Cursor) is available from 11 on. Key method here is getColumn that abstracts over types. So you can read a column and do pattern matching on it. Or you are evil and use implicit conversions from Any to String, Long etc… Or use implicit conversion to “converter”
|
|
But the real deal is selectDynamic. This allows you to write code like this
|
|
This compiles down to selectDynamic(“someColumn”) that calls getColumn and finally implicit conversion is inserted that allows for terse cast to Long. And I threw in a conversion from row to Seq that does a snapshot of current row. This allows pattern matching on rows. Any you can now construct a Stream that will handle Cursor state and lazily evaluate and store these snapshots. Therefore you can abstract away all mutability and handle cursor as immutable collection.
Said conversion to stream
|
|
And some more implicits to help
|
|
All the source is in the project on github https://github.com/edofic/dynamic-db-android (work in progress).
Last modified on 2012-12-10
Previous Homework - functional style (outer sorting)Next Union types in scala