I am putting the following in the local DB of our Android app:
fun registerExperiment(experiment: Experiment) {
DBManager("experiments", config).create {
val doc = MutableDocument()
doc.setString("name", experiment.name)
doc.setDate("start_date", experiment.duration.startDate)
doc.setDate("end_date", experiment.duration.endDate)
doc.setString("status", experiment.status.toString())
val sensorsDictionary = MutableDictionary()
experiment.sensorsInfo.forEachIndexed { index, _ ->
sensorsDictionary.setString(experiment.sensorsInfo[index].label, experiment.sensorsInfo[index].value)
}
doc.setDictionary("internal_environment", sensorsDictionary)
}
}
From this method, you see, I’m putting in an experiment entry: metadata consisting of names, start and end dates, and a status (queued, finished, etc). The create() function is a higher-order function that takes in whatever that results in a mutable document, so don’t think too much about when execute() is performed, it’s done somewhere else. Anyway, you can also see a dictionary containing the actual sensor information (humidity, co2, water level, pH, etc), however, I just can’t flatten it along with the metadata because the user is allowed to not have an entry for a certain sensor, that’s why I stored it as a Couchbase Dictionary. The SensorInfo model class simply looks like this:
@Parcelize
data class SensorInfo (val label: String, var value: String) : Parcelable
How do I query for this dictionary I stored and how do I extract its data? Here’s how I read the data so far:
fun getExperiments(): MutableList<Experiment> {
val resultSet: ResultSet? = DBManager("experiments", config).read { currentDatabase ->
QueryBuilder.select(SelectResult.property("name"),
SelectResult.property("start_date"),
SelectResult.property("end_date"),
SelectResult.property("status"),
SelectResult.property("internal_environment"))
.from(DataSource.database(currentDatabase))
}
val experiments = mutableListOf<Experiment>()
resultSet?.let {
it.forEach { result ->
val experiment = Experiment(result.getString("name"),
enumValueOf(result.getString("status")),
Duration(result.getDate("start_date"), result.getDate("end_date")))
/* TODO: fill in the sensor info list with data from dictionary */
experiments.add(experiment)
}
}
return experiments
}
Thank you.
P.S.
If you need to see how create() and read() are implemented, here it is: (feel free to criticize it if you want, but so far, this pattern has served me well with my CRUD operations):
override fun create(customCreate: () -> MutableDocument) {
openDB()
val doc = customCreate()
try {
currentDatabase.save(doc)
currentDatabase.close()
} catch (e: CouchbaseLiteException) {
e.printStackTrace()
}
}
override fun read(customQuery: (database: Database) -> Query): ResultSet {
openDB()
val query = customQuery(currentDatabase)
lateinit var resultSet: ResultSet
try {
resultSet = query.execute()
//currentDatabase.close()
} catch (e: CouchbaseLiteException){
e.printStackTrace()
}
return resultSet
}