You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
6.8 KiB
172 lines
6.8 KiB
package net.pokeranalytics.android.model
|
|
|
|
import io.realm.Realm
|
|
import io.realm.Sort
|
|
import io.realm.kotlin.where
|
|
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
|
|
import net.pokeranalytics.android.model.filter.QueryCondition
|
|
import net.pokeranalytics.android.model.interfaces.Identifiable
|
|
import net.pokeranalytics.android.model.realm.*
|
|
import java.util.*
|
|
|
|
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 conditions:List<QueryCondition>): Criteria() {
|
|
fun comparison(): List<QueryCondition> {
|
|
return conditions
|
|
}
|
|
}
|
|
|
|
abstract class StaticCriteria : Criteria() {
|
|
inline fun <reified T:QueryCondition.StaticDataQueryCondition> comparison(): List<QueryCondition> {
|
|
QueryCondition.distinct<Session, T>()?.let {
|
|
val values = it.mapNotNull { session ->
|
|
when (this) {
|
|
is Limits -> session.limit
|
|
is TournamentTypes -> session.tournamentType
|
|
is TableSizes -> session.tableSize
|
|
//is TournamentFees -> session.tournamentEntryFee
|
|
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 TableSizes: StaticCriteria()
|
|
object TournamentTypes: StaticCriteria()
|
|
object monthOfYear: SimpleCriteria(List(12) { index -> QueryCondition.MONTH().apply { intValue = index } })
|
|
object dayOfWeek: SimpleCriteria(List(7) { index -> QueryCondition.DAY_OF_WEEK().apply { intValue = index } })
|
|
object SessionType: SimpleCriteria(listOf(QueryCondition.CASH, QueryCondition.TOURNAMENT))
|
|
object BankrollType: SimpleCriteria(listOf(QueryCondition.LIVE, QueryCondition.ONLINE))
|
|
object dayPeriod: SimpleCriteria(listOf(QueryCondition.WEEK_DAY, QueryCondition.WEEK_END))
|
|
object Year: Criteria()
|
|
object Blinds: Criteria()
|
|
//object TournamentFees: StaticCriteria()
|
|
|
|
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>()
|
|
is TableSizes -> comparison<QueryCondition.TABLE_SIZE>()
|
|
is Year -> {
|
|
val years = arrayListOf<QueryCondition.YEAR>()
|
|
val calendar = Calendar.getInstance()
|
|
calendar.time = Date()
|
|
val yearNow = calendar.get(Calendar.YEAR)
|
|
val realm = Realm.getDefaultInstance()
|
|
realm.where<Session>().sort("year", Sort.ASCENDING).findFirst()?.year?.let {
|
|
for (index in 0..(yearNow - it)) {
|
|
years.add(QueryCondition.YEAR().apply {
|
|
intValue = yearNow - index
|
|
})
|
|
}
|
|
}
|
|
realm.close()
|
|
years
|
|
}
|
|
is Blinds -> {
|
|
val blinds = arrayListOf<QueryCondition.BLIND>()
|
|
val realm = Realm.getDefaultInstance()
|
|
realm.where<Session>().distinct("blinds", "bankroll.currency.code").findAll().sort("cgSmallBlind", Sort.ASCENDING).map {
|
|
it.blinds?.let { stake ->
|
|
blinds.add(QueryCondition.BLIND().apply {
|
|
blind = stake
|
|
hasDefaultCurrency = it.hasDefaultCurrency
|
|
})
|
|
}
|
|
}
|
|
realm.close()
|
|
blinds
|
|
}
|
|
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.StaticDataQueryCondition > compare(values:List<Int>): List<S> {
|
|
val objects = arrayListOf<S>()
|
|
values.forEach {
|
|
objects.add((S::class.java.newInstance()).apply {
|
|
intValues.add(it)
|
|
})
|
|
}
|
|
return objects
|
|
}
|
|
}
|
|
|
|
fun List<Criteria>.combined(): List<List<QueryCondition>> {
|
|
val comparatorList = ArrayList<List<QueryCondition>>()
|
|
this.forEach {
|
|
comparatorList.add(it.queryConditions)
|
|
}
|
|
return getCombinations(comparatorList)
|
|
}
|
|
|
|
private fun <T> getCombinations(lists: List<List<T>>): List<List<T>> {
|
|
var combinations: MutableSet<List<T>> = LinkedHashSet()
|
|
var newCombinations: MutableSet<List<T>>
|
|
|
|
var index = 0
|
|
|
|
// extract each of the integers in the first list
|
|
// and add each to ints as a new list
|
|
if (lists.isNotEmpty()) {
|
|
for (i in lists[0]) {
|
|
val newList = ArrayList<T>()
|
|
newList.add(i)
|
|
combinations.add(newList)
|
|
}
|
|
index++
|
|
}
|
|
while (index < lists.size) {
|
|
val nextList = lists[index]
|
|
newCombinations = LinkedHashSet()
|
|
for (first in combinations) {
|
|
for (second in nextList) {
|
|
val newList = ArrayList<T>()
|
|
newList.addAll(first)
|
|
newList.add(second)
|
|
newCombinations.add(newList)
|
|
}
|
|
}
|
|
combinations = newCombinations
|
|
|
|
index++
|
|
}
|
|
|
|
return combinations.toList()
|
|
}
|
|
} |