I want to use Room database to store data about my Itineraries, but the problem is that my Itinerary data class is really complex due to the large amount of data from API call. What is an optimal way of writing type converter for these types of classes?
Main class stored in Room
data class ItineraryModel(
@PrimaryKey(autoGenerate = true)
val itineraryId: Int = 0,
@ColumnInfo(name = "price_details")
@TypeConverters(PriceDetailsModelConverter::class)
val priceDetails: PriceDetailsModel? = null,
@ColumnInfo(name = "slice_data")
@TypeConverters(SliceDataModelConverter::class)
val sliceData: SliceDataModel? = null
)
SliceDataModel
data class SliceDataModel(
val slice: SliceModel
)
SliceModel
data class SliceModel(
val info: InfoSliceModel,
val airline: AirlineModel,
val arrival: ArrivalModel,
val departure: DepartureModel,
val flightData: FlightDataModel
)
InfoSliceModel
data class InfoSliceModel(
val connectionCount: Int,
val duration: String,
val id: Int,
val stopCount: Int
)
AirlineModel
data class AirlineModel(
val logo: String,
val name: String
)
Arrival/Departure Models (the same)
data class ArrivalModel(
val airport: AirportModel,
val datetime: DatetimeModel
)
AirportModel
data class AirportModel(
val city: String,
val code: String,
val country: String,
val name: String,
)
DatetimeModel
data class DatetimeModel(
val date: String,
val dateDisplay: String,
val time24h: String,
)
FlightDataModel
data class FlightDataModel(
val flights: List<FlightModel>
)
FlightModel
data class FlightModel(
val arrival: ArrivalModel,
val departure: DepartureModel,
val info: InfoModel
)
InfoModel
data class InfoModel(
val aircraft: String,
val aircraftType: String,
val cabinClass: String,
val cabinName: String,
val duration: String,
val stopCount: Int
)
As you can see, there's a lot of data. How can I convert it optimally?
One easy solution to this is to use a serialization library, which allows converting big and complex objects into a String
JSON, so you can store them in your Room database easily. I recommend using Kotlinx.serialization library, you can follow this link to setup with Gradle.
After installing the library, annotate all your data class with @Serializable
. For example:
@Serializable
@Entity
data class ItineraryModel(
@PrimaryKey(autoGenerate = true)
val itineraryId: Int = 0,
@ColumnInfo(name = "price_details")
@TypeConverters(PriceDetailsModelConverter::class)
val priceDetails: PriceDetailsModel? = null,
@ColumnInfo(name = "slice_data")
@TypeConverters(SliceDataModelConverter::class)
val sliceData: SliceDataModel? = null
)
Do the same thing with all other data classes that are involved in your model. After doing this, go to your type converters:
PriceDetailsModelConverter:
class PriceDetailsModelConverter {
@TypeConverter
fun convertToJsonString(priceDetails: PriceDetailsModel?): String {
return Json.encodeToString(priceDetails)
}
@TypeConverter
fun convertToObject(json: String): PriceDetailsModel? {
return Json.decodeFromString(json)
}
}
SliceDataModelConverter:
class SliceDataModelConverter {
@TypeConverter
fun convertToJsonString(sliceDetails: SliceDataModel?): String {
return Json.encodeToString(sliceDetails)
}
@TypeConverter
fun convertToObject(json: String): SliceDataModel? {
return Json.decodeFromString(json)
}
}
And everything is OK, when store the big model object, priceDetails
and sliceDetails
will be stored in the form of String JSON, when you query the database, you will receive them as model objects.
Later on, if you want to select rows based on a price condition for example, you have to use LIKE
sql operator since the priceDetails
is stored as String, this maybe the only drawback of this approach.