Reputation: 2023
I am using the below to fetch Database rows to my Adapter, however I want to return rows from multi-filtered single query using either "LIKE" and/or "WHERE" and basically all sql query filter types, I can do one filter via MutableLiveData<String>()
;
end result would be like ...
@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' postcode LIKE '%' || :postcode || '%' BETWEEN firstDate AND lastDate")
fun getFilteredRows(
suburb: String?,
postcode: String?,
firstDate: String?,
lastDate: String?): LiveData<List<MyTable>>
As per below, currently way only can pass one filter var.
ViewModel Class
class MyViewModel internal constructor(repository: MyRepository) : ViewModel()
//filter by suburb
var suburb = MutableLiveData<String>().apply {
//do I set as HashMap??
value = SUBURB
}
//LiveData Observer access
val filteredRows: LiveData<List<MyTable>> = suburb.switchMap {
//pass multiple filters to repository here
//but currently only can pass one string to repository
repository.getFilteredRows(it)
}
//MyViewModel function to set the suburb value
fun setSuburb(_suburb: String) {
suburb.value = _suburb
}
//companion object
companion object {
var SUBURB: String? = null
}
Repository Class
class Repository private constructor(private val dao: Dao)
//basic repo to dao communtication
fun getFilteredRows(suburb: String?) = dao.getFilteredRows(suburb)
Dao Interface
@Dao
interface Dao
//here I want to receive multiple Strings to do filtering within the query
@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%'")
fun getFilteredRows(suburb: String?): LiveData<List<MyTable>>
I have tried with passing basic var Strings with no luck, seems only MutableLiveData
is the way to pass variable to the Dao via ViewModel
& Repository
Upvotes: 1
Views: 3057
Reputation: 2023
** See Edit Below **
Not ideal to say the least, actually would not recommend, however, current work around is to "loop" through multiple MutableLiveData
variables
ViewModel Class
var suburb = MutableLiveData<String>().apply { value = SUBURB }
var postcode = MutableLiveData<String>().apply { value = POSTCODE }
var limit = MutableLiveData<Int>().apply { value = LIMIT }
val filteredRows: LiveData<List<MyTable>> =
suburb.switchMap {
//set suburb MutableLiveData
var suburb = it
postcode.switchMap {
//set postcode MutableLiveData
var postcode = it
}
limit.switchMap {
//set limit MutableLiveData
var limit = it
}
repository.getFilteredRows(suburb, postcode, limit)
}
/// EDIT ANSWER ///
Using HashMap to pass multiple filters (Strings) to Dao SQl Query. Tested a returned what was expected, so confirming this works.
Foreseeable issue is when needing to pass Strings & Int etc, may have to refer back to passing as Strings only & then do parse.ToInt() etc on Int String Values
build HashMap in my Fragment to pass to MyViewModel
lateinit var myModel: LiveData<MyTable>
var filters = HashMap<String, String>()
filters.put("suburb", myModel.value!!.suburb)
filters.put("postcode", myModel.value!!.postcode)
with(viewModel) {
//pass my HashMap to my ViewModel for update/change/set on filters MutableLiveData HashMap variable
setFilters(filters)
}
MyViewModel Class
//initilise filters MutableLiveData HashMap variable
var filters = MutableLiveData<HashMap<String, String>>().apply { value = FILTERS }
//function to update/change/set filters MutableLiveData HashMap variable
//see setFilters(filters) used in above Fragment
fun setFilters(_filters: HashMap<String, String>) {
filters.value = _filters
}
//foreach on passed HashMap via switchMap{}
val filtered: LiveData<List<MyTable>> = filters.switchMap {
//initilise variables
var suburb = ""
var postcode = ""
//foreach loop on HashCookie :)
for (filter in it) {
if(filter.key.equals("suburb")){
suburb = filter.value
}else if(filter.key.equals("postcode")) {
postcode = filter.value
}
}
//pass strings to Dao
repository.getFiltered(suburb, postcode)
}
//companion object
companion object {
var FILTERS: HashMap<String, String>? = null
}
Repository Class
//send variables to the Dao Interface
fun getFiltered(suburb: String?, postcode: String?) = dao.getFiltered(suburb, postcode)
Dao Interface
@Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' AND postcode LIKE '%' || :postcode || '%' ")
fun getFiltered(suburb: String?, postcode: String?): LiveData<List<MyTable>>
Upvotes: 1