I know Anko provides the functions parseSingle, parseOpt and parseList , I don't understand why the code of Android Developers (the book) need to design extensions parseList again.
Could you tell me? Thanks!
https://github.com/antoniolg/Kotlin-for-Android-Developers/blob/master/app/src/main/java/com/antonioleiva/weatherapp/data/db/ForecastDb.kt
override fun requestForecastByZipCode(zipCode: Long, date: Long) = forecastDbHelper.use {
val dailyRequest = "${DayForecastTable.CITY_ID} = ? AND ${DayForecastTable.DATE} >= ?"
val dailyForecast = select(DayForecastTable.NAME)
.whereSimple(dailyRequest, zipCode.toString(), date.toString())
.parseList { DayForecast(HashMap(it)) }
}
https://github.com/antoniolg/Kotlin-for-Android-Developers/blob/master/app/src/main/java/com/antonioleiva/weatherapp/extensions/DatabaseExtensions.kt
fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T): List<T> =
parseList(object : MapRowParser<T> {
override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
})
Anko's parseList
takes a MapRowParser
, not a function. This simplifies usage. With Anko version you'd write
.parseList { mapRowParser { DayForecast(HashMap(it)) } }
instead. That's assuming there is a constructor function like mapRowParser
which I can't find in their sources; otherwise, you could write it quite trivially.
Or rather, it's already written for you in the example code, just not as a separate function:
fun <T> mapRowParser(parser: (Map<String, Any?>) -> T): MapRowParser<T> =
object : MapRowParser<T> {
override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
}
I am honestly really surprised if this function doesn't exist already (maybe called something else, but what?). OTOH, if it does exist, Leiva should have used it.
If you expected simple single column rows result, you can use ready-made Anko parsers:
- ShortParser
- IntParser
- LongParser
- FloatParser
- DoubleParser
- StringParser
- BlobParser
Your code might be:
val dailyForecast = select(DayForecastTable.NAME)
.whereSimple(dailyRequest, zipCode.toString(), date.toString())
.parseList(StringParser)
Or you can implement your own parser. Here below sample for three columns result (Int, String, String):
val userParser = rowParser { id: Int, name: String, email: String ->
Triple(id, name, email)
}