WIP criteria object to centralize query,filter,comparator stuff

feature/top10
Razmig Sarkissian 7 years ago
parent 65711c8369
commit f43714213b
  1. 90
      app/src/main/java/net/pokeranalytics/android/model/Criteria.kt
  2. 53
      app/src/main/java/net/pokeranalytics/android/model/comparison/Comparator.kt
  3. 2
      app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt
  4. 60
      app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/ComputableResult.kt
  6. 52
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt

@ -0,0 +1,90 @@
package net.pokeranalytics.android.model
import io.realm.Realm
import io.realm.RealmResults
import io.realm.Sort
import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.filter.FilterHelper
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.*
sealed class Criteria {
abstract class RealmCriteria : Criteria() {
inline fun <reified T:Identifiable> comparison(): List<QueryCondition> {
return compare < QueryCondition.QueryDataCondition<Identifiable>, T >()
}
}
abstract class SimpleCriteria(private val condition:QueryCondition): Criteria() {
fun comparison(): List<QueryCondition> {
return listOf(condition)
}
}
abstract class StaticCriteria : Criteria() {
inline fun <reified T:QueryCondition.SingleValueQueryCondition> comparison(): List<QueryCondition> {
QueryCondition.distinct<Session, T>()?.let {
val values = it.mapNotNull { session ->
when (this) {
is Limits -> session.limit
else -> null
}
}
return compare<T>(values)
}
return listOf<T>()
}
}
object Bankrolls: RealmCriteria()
object Games: RealmCriteria()
object TournamentNames: RealmCriteria()
object Locations: RealmCriteria()
object TournamentFeatures: RealmCriteria()
object Limits: StaticCriteria()
object TournamentTypes : StaticCriteria()
object Tournament : SimpleCriteria(QueryCondition.TOURNAMENT)
val queryConditions: List<QueryCondition>
get() {
return when (this) {
is Bankrolls -> comparison<Bankroll>()
is Games -> comparison<Game>()
is TournamentFeatures-> comparison<TournamentFeature>()
is TournamentNames-> comparison<TournamentName>()
is Locations -> comparison<Location>()
is SimpleCriteria -> comparison()
is Limits -> comparison<QueryCondition.LIMIT>()
is TournamentTypes -> comparison<QueryCondition.TOURNAMENT_TYPE>()
else -> throw PokerAnalyticsException.QueryTypeUnhandled
}
}
companion object {
inline fun < reified S : QueryCondition.QueryDataCondition<Identifiable>, reified T : Identifiable > compare(): List<S> {
val objects = arrayListOf<S>()
val realm = Realm.getDefaultInstance()
realm.where<T>().findAll().forEach {
objects.add((QueryCondition.getInstance<T>() as S).apply {
setObject(it)
})
}
realm.close()
return objects
}
inline fun < reified S : QueryCondition.SingleValueQueryCondition > compare(values:List<Int>): List<S> {
val objects = arrayListOf<S>()
values.forEach {
objects.add((S::class.java.newInstance()).apply {
setValue(it)
})
}
return objects
}
}
}

@ -5,6 +5,7 @@ import io.realm.RealmQuery
import io.realm.Sort import io.realm.Sort
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
@ -38,7 +39,7 @@ enum class Comparator {
TOURNAMENT_ENTRY_FEE -> { TOURNAMENT_ENTRY_FEE -> {
val fees = arrayListOf<QueryCondition.BETWEEN_TOURNAMENT_FEE>() val fees = arrayListOf<QueryCondition.BETWEEN_TOURNAMENT_FEE>()
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
val fieldName = Session.fieldNameForQueryType(QueryCondition.BETWEEN_TOURNAMENT_FEE()) val fieldName = Session.fieldNameForQueryType(QueryCondition.BETWEEN_TOURNAMENT_FEE::class.java)!!
realm.where<Session>().distinct(fieldName).findAll().sort(fieldName, Sort.ASCENDING).map { realm.where<Session>().distinct(fieldName).findAll().sort(fieldName, Sort.ASCENDING).map {
it.tournamentEntryFee?.let { fee -> it.tournamentEntryFee?.let { fee ->
fees.add(QueryCondition.BETWEEN_TOURNAMENT_FEE().apply { between(fee, fee) }) fees.add(QueryCondition.BETWEEN_TOURNAMENT_FEE().apply { between(fee, fee) })
@ -79,51 +80,11 @@ enum class Comparator {
realm.close() realm.close()
blinds blinds
} }
GAME -> { BANKROLL -> Criteria.Bankrolls.queryConditions
val objects = arrayListOf<QueryCondition.GAME>() GAME -> Criteria.Games.queryConditions
val realm = Realm.getDefaultInstance() TOURNAMENT_NAME-> Criteria.TournamentNames.queryConditions
realm.where<Game>().findAll().forEach { TOURNAMENT_FEATURE-> Criteria.TournamentFeatures.queryConditions
objects.add(QueryCondition.GAME().apply { setObjectId(it.id)}) LOCATION-> Criteria.Locations.queryConditions
}
realm.close()
objects
}
BANKROLL -> {
val objects = arrayListOf<QueryCondition.BANKROLL>()
val realm = Realm.getDefaultInstance()
realm.where<Bankroll>().findAll().forEach {
objects.add(QueryCondition.BANKROLL().apply { setObjectId(it.id)})
}
realm.close()
objects
}
LOCATION -> {
val objects = arrayListOf<QueryCondition.LOCATION>()
val realm = Realm.getDefaultInstance()
realm.where<Location>().findAll().forEach {
objects.add(QueryCondition.LOCATION().apply { setObjectId(it.id)})
}
realm.close()
objects
}
TOURNAMENT_NAME -> {
val objects = arrayListOf<QueryCondition.TOURNAMENT_NAME>()
val realm = Realm.getDefaultInstance()
realm.where<TournamentName>().findAll().forEach {
objects.add(QueryCondition.TOURNAMENT_NAME().apply { setObjectId(it.id)})
}
realm.close()
objects
}
TOURNAMENT_FEATURE -> {
val objects = arrayListOf<QueryCondition.ANY_TOURNAMENT_FEATURES>()
val realm = Realm.getDefaultInstance()
realm.where<TournamentFeature>().findAll().forEach {
objects.add(QueryCondition.ANY_TOURNAMENT_FEATURES().apply { setObjectId(it.id)})
}
realm.close()
objects
}
LIMIT_TYPE -> { LIMIT_TYPE -> {
val limits = arrayListOf<QueryCondition.LIMIT>() val limits = arrayListOf<QueryCondition.LIMIT>()
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()

@ -51,7 +51,7 @@ class FilterHelper {
companion object { companion object {
inline fun <reified T : Filterable> fieldNameForQueryType(queryCondition: QueryCondition): String? { inline fun <reified T : Filterable > fieldNameForQueryType(queryCondition: Class< out QueryCondition>): String? {
return when (T::class.java) { return when (T::class.java) {
Session::class.java -> Session.fieldNameForQueryType(queryCondition) Session::class.java -> Session.fieldNameForQueryType(queryCondition)

@ -1,12 +1,13 @@
package net.pokeranalytics.android.model.filter package net.pokeranalytics.android.model.filter
import io.realm.RealmQuery import io.realm.*
import io.realm.internal.Table import io.realm.internal.Table
import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.Limit
import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TableSize
import net.pokeranalytics.android.model.realm.FilterCondition import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.util.extensions.endOfDay import net.pokeranalytics.android.util.extensions.endOfDay
import net.pokeranalytics.android.util.extensions.startOfDay import net.pokeranalytics.android.util.extensions.startOfDay
import java.util.* import java.util.*
@ -24,10 +25,12 @@ fun List<QueryCondition>.name() : String {
sealed class QueryCondition(var operator: Operator? = null) { sealed class QueryCondition(var operator: Operator? = null) {
abstract class QueryDataCondition : QueryCondition() abstract class QueryDataCondition < T: Identifiable> : QueryCondition() {
fun setObjectId(id:String) { fun setObject(dataObject:T) {
this.valueMap = mapOf("ids" to id) this.valueMap = mapOf("ids" to arrayListOf(dataObject.id))
} }
}
class MoreQueryCondition : QueryCondition(Operator.MORE) class MoreQueryCondition : QueryCondition(Operator.MORE)
class LessQueryCondition : QueryCondition(Operator.LESS) class LessQueryCondition : QueryCondition(Operator.LESS)
@ -38,6 +41,25 @@ sealed class QueryCondition(var operator: Operator? = null) {
val instance = kClass.objectInstance ?: kClass.java.newInstance() val instance = kClass.objectInstance ?: kClass.java.newInstance()
return instance as QueryCondition return instance as QueryCondition
} }
inline fun <reified T:Identifiable>getInstance(): QueryCondition {
return when (T::class.java) {
is Bankroll -> BANKROLL()
else -> throw PokerAnalyticsException.QueryTypeUnhandled
}
}
inline fun < reified T: Filterable, reified S: QueryCondition>distinct(): RealmResults<T>? {
FilterHelper.fieldNameForQueryType<T>(S::class.java)?.let {
val realm = Realm.getDefaultInstance()
val distincts = realm.where<T>().distinct(it).findAll().sort(it, Sort.ASCENDING)
realm.close()
return distincts
}
return null
}
} }
val name: String = this::class.simpleName ?: throw PokerAnalyticsException.FilterElementUnknownName val name: String = this::class.simpleName ?: throw PokerAnalyticsException.FilterElementUnknownName
@ -51,29 +73,35 @@ sealed class QueryCondition(var operator: Operator? = null) {
; ;
} }
open class SingleValueQueryCondition : QueryCondition() {
fun setValue(value:Int) {
this.valueMap = mapOf("values" to arrayListOf(value))
}
}
object LIVE : QueryCondition() object LIVE : QueryCondition()
object CASH : QueryCondition() object CASH : QueryCondition()
object ONLINE : QueryCondition() object ONLINE : QueryCondition()
object TOURNAMENT: QueryCondition() object TOURNAMENT: QueryCondition()
class BANKROLL: QueryDataCondition() class BANKROLL: QueryDataCondition<Bankroll>()
class GAME: QueryCondition() class GAME: QueryDataCondition<Game>()
class TOURNAMENT_NAME: QueryCondition() class TOURNAMENT_NAME: QueryDataCondition<TournamentName>()
class ANY_TOURNAMENT_FEATURES: QueryCondition() class ANY_TOURNAMENT_FEATURES: QueryDataCondition<TournamentFeature>()
class ALL_TOURNAMENT_FEATURES: QueryCondition() class ALL_TOURNAMENT_FEATURES: QueryDataCondition<TournamentFeature>()
class LOCATION: QueryCondition() class LOCATION: QueryDataCondition<Location>()
class LIMIT: QueryCondition() { class LIMIT: SingleValueQueryCondition() {
fun setLimitType(limitType: Int) { fun setLimitType(limitType: Int) {
this.valueMap = mapOf("values" to limitType) this.valueMap = mapOf("values" to limitType)
} }
} }
class TABLE_SIZE: QueryCondition() { class TABLE_SIZE: SingleValueQueryCondition() {
fun setNumberOfPlayer(numberOfPlayer: Int) { fun setNumberOfPlayer(numberOfPlayer: Int) {
this.valueMap = mapOf("values" to numberOfPlayer) this.valueMap = mapOf("values" to numberOfPlayer)
} }
} }
class TOURNAMENT_TYPE: QueryCondition() { class TOURNAMENT_TYPE: SingleValueQueryCondition() {
fun setTournamentType(tournamentType:Int) { fun setTournamentType(tournamentType:Int) {
this.valueMap = mapOf("values" to tournamentType) this.valueMap = mapOf("values" to tournamentType)
} }
@ -195,7 +223,7 @@ sealed class QueryCondition(var operator: Operator? = null) {
* providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery] * providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery]
*/ */
inline fun <reified T : Filterable> filter(realmQuery: RealmQuery<T>): RealmQuery<T> { inline fun <reified T : Filterable> filter(realmQuery: RealmQuery<T>): RealmQuery<T> {
val fieldName = FilterHelper.fieldNameForQueryType<T>(this) val fieldName = FilterHelper.fieldNameForQueryType<T>(this::class.java)
fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown
when (operator) { when (operator) {
Operator.LESS -> { Operator.LESS -> {

@ -56,7 +56,7 @@ open class ComputableResult() : RealmObject(), Computable, Filterable {
companion object { companion object {
fun fieldNameForQueryType(queryCondition: QueryCondition): String? { fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? {
return "session." + Session.fieldNameForQueryType(queryCondition) return "session." + Session.fieldNameForQueryType(queryCondition)
} }

@ -62,33 +62,33 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return realm.copyToRealm(session) return realm.copyToRealm(session)
} }
fun fieldNameForQueryType(queryCondition: QueryCondition): String? { fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? {
return when (queryCondition) { return when (queryCondition) {
LIVE, ONLINE -> "bankroll.live" LIVE::class, ONLINE::class -> "bankroll.live"
CASH, TOURNAMENT -> "type" CASH::class, TOURNAMENT::class -> "type"
is BANKROLL -> "bankroll.id" BANKROLL::class -> "bankroll.id"
is GAME -> "game.id" GAME::class -> "game.id"
is TOURNAMENT_NAME -> "tournamentName.id" TOURNAMENT_NAME::class -> "tournamentName.id"
is ANY_TOURNAMENT_FEATURES, is ALL_TOURNAMENT_FEATURES -> "tournamentFeatures.id" ANY_TOURNAMENT_FEATURES::class, ALL_TOURNAMENT_FEATURES::class -> "tournamentFeatures.id"
is LOCATION -> "location.id" LOCATION::class -> "location.id"
is LIMIT -> "limit" LIMIT::class -> "limit"
is TABLE_SIZE -> "tableSize" TABLE_SIZE::class -> "tableSize"
is TOURNAMENT_TYPE -> "tournamentType" TOURNAMENT_TYPE::class -> "tournamentType"
is BLIND -> "blinds" BLIND::class -> "blinds"
is COMMENT -> "comment" COMMENT::class -> "comment"
is BETWEEN_NUMBER_OF_TABLE, is MORE_NUMBER_OF_TABLE, is LESS_NUMBER_OF_TABLE -> "numberOfTable" BETWEEN_NUMBER_OF_TABLE::class, MORE_NUMBER_OF_TABLE::class, LESS_NUMBER_OF_TABLE::class -> "numberOfTable"
is MORE_THAN_NET_RESULT, is LESS_THAN_NET_RESULT -> "computableResults.ratedNet" MORE_THAN_NET_RESULT::class, LESS_THAN_NET_RESULT::class -> "computableResults.ratedNet"
is MORE_THAN_BUY_IN, is LESS_THAN_BUY_IN -> "result.buyin" MORE_THAN_BUY_IN::class, LESS_THAN_BUY_IN::class -> "result.buyin"
is MORE_THAN_CASH_OUT, is LESS_THAN_CASH_OUT -> "result.cashout" MORE_THAN_CASH_OUT::class, LESS_THAN_CASH_OUT::class -> "result.cashout"
is MORE_THAN_TIPS, is LESS_THAN_TIPS -> "result.tips" MORE_THAN_TIPS::class, LESS_THAN_TIPS::class -> "result.tips"
is MORE_THAN_NUMBER_OF_PLAYER, is LESS_THAN_NUMBER_OF_PLAYER, is BETWEEN_NUMBER_OF_PLAYER -> "tournamentNumberOfPlayers" MORE_THAN_NUMBER_OF_PLAYER::class, LESS_THAN_NUMBER_OF_PLAYER::class, BETWEEN_NUMBER_OF_PLAYER::class -> "tournamentNumberOfPlayers"
is MORE_THAN_TOURNAMENT_FEE, is LESS_THAN_TOURNAMENT_FEE, is BETWEEN_TOURNAMENT_FEE -> "tournamentEntryFee" MORE_THAN_TOURNAMENT_FEE::class, LESS_THAN_TOURNAMENT_FEE::class, BETWEEN_TOURNAMENT_FEE::class -> "tournamentEntryFee"
is STARTED_FROM_DATE, is STARTED_TO_DATE -> "startDate" STARTED_FROM_DATE::class, STARTED_TO_DATE::class -> "startDate"
is ENDED_FROM_DATE, is ENDED_TO_DATE -> "endDate" ENDED_FROM_DATE::class, ENDED_TO_DATE::class -> "endDate"
is DAY_OF_WEEK, is WEEK_END, is WEEK_DAY -> "dayOfWeek" DAY_OF_WEEK::class, WEEK_END::class, WEEK_DAY::class -> "dayOfWeek"
is MONTH -> "month" MONTH::class -> "month"
is YEAR -> "year" YEAR::class -> "year"
TODAY, YESTERDAY, TODAY_AND_YESTERDAY, THIS_YEAR, THIS_MONTH, THIS_WEEK -> "startDate" TODAY::class, YESTERDAY::class, TODAY_AND_YESTERDAY::class, THIS_YEAR::class, THIS_MONTH::class, THIS_WEEK::class -> "startDate"
else -> null else -> null
} }
} }

@ -120,7 +120,7 @@ open class SessionSet() : RealmObject(), Timed, Filterable {
return realm.copyToRealm(sessionSet) return realm.copyToRealm(sessionSet)
} }
fun fieldNameForQueryType(queryCondition: QueryCondition): String? { fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? {
return "sessions." + Session.fieldNameForQueryType(queryCondition) return "sessions." + Session.fieldNameForQueryType(queryCondition)
} }

Loading…
Cancel
Save