Trim whitespace from custom filter criteria

Whitespace was causing parsing error
pull/1132/head
Alex Baker 4 years ago
parent daef79eb66
commit 42037e513a

@ -1,8 +1,5 @@
package com.todoroo.astrid.core package com.todoroo.astrid.core
import com.google.common.base.Joiner
import com.google.common.base.Splitter
import com.google.common.collect.Lists
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.CustomFilterCriterion import com.todoroo.astrid.api.CustomFilterCriterion
import com.todoroo.astrid.api.MultipleSelectCriterion import com.todoroo.astrid.api.MultipleSelectCriterion
@ -72,14 +69,13 @@ class CriterionInstance {
private fun serialize(): String { private fun serialize(): String {
// criterion|entry|text|type|sql // criterion|entry|text|type|sql
return Joiner.on(AndroidUtilities.SERIALIZATION_SEPARATOR) return listOf(
.join( escape(criterion.identifier),
listOf( escape(valueFromCriterion),
escape(criterion.identifier), escape(criterion.text),
escape(valueFromCriterion), type,
escape(criterion.text), criterion.sql ?: "")
type, .joinToString(AndroidUtilities.SERIALIZATION_SEPARATOR)
if (criterion.sql == null) "" else criterion.sql))
} }
override fun toString(): String { override fun toString(): String {
@ -126,9 +122,10 @@ class CriterionInstance {
return emptyList() return emptyList()
} }
val entries: MutableList<CriterionInstance> = ArrayList() val entries: MutableList<CriterionInstance> = ArrayList()
for (row in criterion.split("\n".toRegex()).toTypedArray()) { for (row in criterion.trim().split("\n")) {
val split = Lists.transform( val split = row
Splitter.on(AndroidUtilities.SERIALIZATION_SEPARATOR).splitToList(row)) { item: String? -> unescape(item) } .split(AndroidUtilities.SERIALIZATION_SEPARATOR)
.map { unescape(it) }
if (split.size != 4 && split.size != 5) { if (split.size != 4 && split.size != 5) {
Timber.e("invalid row: %s", row) Timber.e("invalid row: %s", row)
return emptyList() return emptyList()
@ -141,7 +138,7 @@ class CriterionInstance {
} else if (entry.criterion is MultipleSelectCriterion) { } else if (entry.criterion is MultipleSelectCriterion) {
val multipleSelectCriterion = entry.criterion as MultipleSelectCriterion? val multipleSelectCriterion = entry.criterion as MultipleSelectCriterion?
if (multipleSelectCriterion!!.entryValues != null) { if (multipleSelectCriterion!!.entryValues != null) {
entry.selectedIndex = listOf(*multipleSelectCriterion.entryValues).indexOf(value) entry.selectedIndex = multipleSelectCriterion.entryValues.indexOf(value)
} }
} else { } else {
Timber.d("Ignored value %s for %s", value, entry.criterion) Timber.d("Ignored value %s for %s", value, entry.criterion)
@ -167,8 +164,10 @@ class CriterionInstance {
AndroidUtilities.SEPARATOR_ESCAPE, AndroidUtilities.SERIALIZATION_SEPARATOR) AndroidUtilities.SEPARATOR_ESCAPE, AndroidUtilities.SERIALIZATION_SEPARATOR)
} }
fun serialize(criterion: List<CriterionInstance>?): String { fun serialize(criterion: List<CriterionInstance>): String {
return Joiner.on("\n").join(Lists.transform<CriterionInstance, String?>(criterion!!) { obj: CriterionInstance? -> obj!!.serialize() }) return criterion
.joinToString("\n") { it.serialize() }
.trim()
} }
} }
} }

@ -69,6 +69,11 @@ class Upgrader @Inject constructor(
} }
run(from, V9_7) { googleTaskListDao.resetOrders() } run(from, V9_7) { googleTaskListDao.resetOrders() }
run(from, V9_7_3) { googleTaskDao.updateParents() } run(from, V9_7_3) { googleTaskDao.updateParents() }
run(from, V10_0_2) {
filterDao.getAll()
.filter { it.getSql().trim() == "WHERE" }
.forEach { filterDao.delete(it) }
}
preferences.setBoolean(R.string.p_just_updated, true) preferences.setBoolean(R.string.p_just_updated, true)
} }
preferences.setCurrentVersion(to) preferences.setCurrentVersion(to)
@ -315,6 +320,7 @@ class Upgrader @Inject constructor(
const val V9_6 = 90600 const val V9_6 = 90600
const val V9_7 = 90700 const val V9_7 = 90700
const val V9_7_3 = 90704 const val V9_7_3 = 90704
const val V10_0_2 = 100012
@JvmStatic @JvmStatic
fun getAndroidColor(context: Context, index: Int): Int { fun getAndroidColor(context: Context, index: Int): Int {

@ -91,12 +91,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
setCriteria(CriterionInstance.fromString( setCriteria(CriterionInstance.fromString(
filterCriteriaProvider, intent.getStringExtra(EXTRA_CRITERIA)!!)) filterCriteriaProvider, intent.getStringExtra(EXTRA_CRITERIA)!!))
} }
else -> { else -> setCriteria(universe())
val instance = CriterionInstance()
instance.criterion = filterCriteriaProvider.startingUniverse
instance.type = CriterionInstance.TYPE_UNIVERSE
setCriteria(mutableListOf(instance))
}
} }
recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = LinearLayoutManager(this)
ItemTouchHelper( ItemTouchHelper(
@ -108,8 +103,15 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
updateTheme() updateTheme()
} }
private fun universe() = listOf(CriterionInstance().apply {
criterion = filterCriteriaProvider.startingUniverse
type = CriterionInstance.TYPE_UNIVERSE
})
private fun setCriteria(criteria: List<CriterionInstance>) { private fun setCriteria(criteria: List<CriterionInstance>) {
this.criteria = criteria.toMutableList() this.criteria = criteria
.ifEmpty { universe() }
.toMutableList()
adapter = CustomFilterAdapter(criteria, locale) { replaceId: String -> onClick(replaceId) } adapter = CustomFilterAdapter(criteria, locale) { replaceId: String -> onClick(replaceId) }
recyclerView.adapter = adapter recyclerView.adapter = adapter
fab.isExtended = isNew || adapter.itemCount <= 1 fab.isExtended = isNew || adapter.itemCount <= 1
@ -246,6 +248,9 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
f.setIcon(selectedIcon) f.setIcon(selectedIcon)
f.values = AndroidUtilities.mapToSerializedString(values) f.values = AndroidUtilities.mapToSerializedString(values)
f.criterion = CriterionInstance.serialize(criteria) f.criterion = CriterionInstance.serialize(criteria)
if (f.criterion.isNullOrBlank()) {
throw RuntimeException("Criterion cannot be empty")
}
f.setSql(sql) f.setSql(sql)
if (isNew) { if (isNew) {
f.id = filterDao.insert(f) f.id = filterDao.insert(f)
@ -272,7 +277,9 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
(!Strings.isNullOrEmpty(newName) (!Strings.isNullOrEmpty(newName)
|| selectedColor != 0 || selectedIcon != -1 || criteria.size > 1) || selectedColor != 0 || selectedIcon != -1 || criteria.size > 1)
} else newName != filter!!.listingTitle } else newName != filter!!.listingTitle
|| selectedColor != filter!!.tint || selectedIcon != filter!!.icon || CriterionInstance.serialize(criteria) != filter!!.criterion || selectedColor != filter!!.tint
|| selectedIcon != filter!!.icon
|| CriterionInstance.serialize(criteria) != filter!!.criterion.trim()
|| values != filter!!.valuesForNewTasks || values != filter!!.valuesForNewTasks
|| sql != filter!!.originalSqlQuery || sql != filter!!.originalSqlQuery
} }

@ -1,9 +1,6 @@
package org.tasks.data package org.tasks.data
import androidx.room.Dao import androidx.room.*
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.FilterListItem.NO_ORDER
@Dao @Dao
@ -14,6 +11,9 @@ interface FilterDao {
@Query("DELETE FROM filters WHERE _id = :id") @Query("DELETE FROM filters WHERE _id = :id")
suspend fun delete(id: Long) suspend fun delete(id: Long)
@Delete
suspend fun delete(filter: Filter)
@Query("SELECT * FROM filters WHERE title = :title COLLATE NOCASE LIMIT 1") @Query("SELECT * FROM filters WHERE title = :title COLLATE NOCASE LIMIT 1")
suspend fun getByName(title: String): Filter? suspend fun getByName(title: String): Filter?

Loading…
Cancel
Save