The following code is from "Kotlin for Android Developers", you can access it at https://github.com/antoniolg/Kotlin-for-Android-Developers
In order to insert a row data into CityForecastTable.NAME
, I have to pass a vararg
values by Source Code fun SQLiteDatabase.insert
1: The author make a extension toVarargArray()
to convert a MutableMap<String, Any?>
to Pair<String, Any?>
, I don't know whether there is a better way to do that. Do I need to use a extension function?
2: The author have to use the code it.value!!
in Code C , I don't know if the code fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V?>> = map({ Pair(it.key, it.value) }).toTypedArray()
is right?
3: I don't know whether the app will crash when I insert a row data of which a column include null value.
import org.jetbrains.anko.db.*
class ForecastDb(private val forecastDbHelper: ForecastDbHelper = ForecastDbHelper.instance,
private val dataMapper: DbDataMapper = DbDataMapper()) : ForecastDataSource {
fun saveForecast(forecast: ForecastList) = forecastDbHelper.use {
//dataMapper.convertFromDomain(forecast) will return CityForecast object
with(dataMapper.convertFromDomain(forecast)) {
insert(CityForecastTable.NAME, *map.toVarargArray())
}
}
}
class CityForecast(val map: MutableMap<String, Any?>, val dailyForecast: List<DayForecast>) {
var _id: Long by map
var city: String by map
var country: String by map
constructor(id: Long, city: String, country: String, dailyForecast: List<DayForecast>)
: this(HashMap(), dailyForecast) {
this._id = id
this.city = city
this.country = country
}
}
Code C
fun <K, V : Any> Map<K, V?>.toVarargArray(): Array<out Pair<K, V>> =
map({ Pair(it.key, it.value!!) }).toTypedArray()
Source Code
fun SQLiteDatabase.insert(tableName: String, vararg values: Pair<String, Any?>): Long {
return insert(tableName, null, values.toContentValues())
}
You have pretty much everything there
Use the asterisk *
operator also known as spread operator to spread your array to vararg
inside function.
https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs
Add ? to the value and you are ready to go
fun <K, V : Any> Map<K, V?>.toVarargArray() = map { it.key to it.value }.toTypedArray()
insert("", *mapOf("k" to "v").toVarargArray())
No, you do not really need an extension function for that. It may make sense to have something in place if you are calling the insert
-method (or any other which requires arrays instead of a Map
) often. However depending on what you call more often, you may rather supply an extension function for the specific method with the Map
as parameter instead.
If you do not want to have the extension function you can call the following directly (if you aleady have a map):
*map.map { it.key to it.value }.toTypedArray()
I wonder why the author allows Any?
on the CityForecast
-class as values but then decides to use value!!
. I would rather recommend either using Any
, that way no null
values are allowed or otherwise falling back to a default, e.g. value?:""
. Note that if you use Any
, you probably need to ensure that your data in the database is not containing any null
-values (column created with NOT NULL
constraint).
You really should try it out. If it crashes you get familiar on how to deal with errors. I assume that it crashes (or at least throws a NullPointerException
somewhere ;-)) if you use null
values in the map and keep the mentioned extension function as then the value!!
-call will fail. And note: you can always come back here to ask new questions, if there is an issue you can't resolve or you do not find any good sources for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With