From ea728a1cf277ffdb9e2a1e738a259d3f735420ca Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Sat, 23 Mar 2019 14:48:39 +0100 Subject: [PATCH] filter cleanup --- .../filter/BlindFilterInstrumentedTest.kt | 63 ++++---- .../filter/DateFilterInstrumentedUnitTest.kt | 59 ++++--- .../filter/ExceptionFilterInstrumentedTest.kt | 32 ++-- .../filter/RealmFilterInstrumentedUnitTest.kt | 8 +- .../SessionFilterInstrumentedUnitTest.kt | 134 +++++++++++----- .../android/calculus/Calculator.kt | 4 +- .../android/calculus/ComputableGroup.kt | 2 +- .../pokeranalytics/android/calculus/Stat.kt | 4 +- .../android/exceptions/Exceptions.kt | 4 +- ...ilterEntityDataSource.kt => Filterable.kt} | 16 +- .../filter/{FilterType.kt => QueryType.kt} | 106 ++++++------- .../{filter => }/interfaces/TimeFilterable.kt | 8 +- .../android/model/realm/Filter.kt | 35 +++-- .../android/model/realm/FilterComponent.kt | 81 ---------- .../android/model/realm/FilterElement.kt | 144 ++++++++++++++++++ .../android/model/realm/FilterElementBlind.kt | 8 + .../android/model/realm/Session.kt | 16 +- .../ui/adapter/RowRepresentableDataSource.kt | 2 +- .../ui/fragment/FilterDetailsFragment.kt | 2 +- .../android/ui/view/RowRepresentable.kt | 2 +- .../view/rowrepresentable/FilterElementRow.kt | 110 ++++++------- .../view/rowrepresentable/FilterSectionRow.kt | 7 +- 22 files changed, 499 insertions(+), 348 deletions(-) rename app/src/main/java/net/pokeranalytics/android/model/filter/{FilterEntityDataSource.kt => Filterable.kt} (73%) rename app/src/main/java/net/pokeranalytics/android/model/filter/{FilterType.kt => QueryType.kt} (73%) rename app/src/main/java/net/pokeranalytics/android/model/{filter => }/interfaces/TimeFilterable.kt (69%) delete mode 100644 app/src/main/java/net/pokeranalytics/android/model/realm/FilterComponent.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/model/realm/FilterElement.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt diff --git a/app/src/androidTest/java/net/pokeranalytics/android/filter/BlindFilterInstrumentedTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/filter/BlindFilterInstrumentedTest.kt index cfd3ce64..91ec0cb2 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/filter/BlindFilterInstrumentedTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/filter/BlindFilterInstrumentedTest.kt @@ -1,9 +1,9 @@ package net.pokeranalytics.android.filter -import net.pokeranalytics.android.model.filter.FilterType -import net.pokeranalytics.android.model.realm.Bankroll -import net.pokeranalytics.android.model.realm.Filter -import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.filter.QueryType +import net.pokeranalytics.android.model.realm.* +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import org.junit.Assert import org.junit.Test import java.util.* @@ -37,12 +37,11 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.BLINDS - filter.valueMap = mapOf("blinds" to arrayOf(mapOf( - "sb" to 0.5, - "bb" to 1.0, - "code" to null - ))) + val filter = QueryType.BLINDS + val blind = FilterElementRow.Blind(0.5, 1.0, null) + blind.filterSectionRow = FilterSectionRow.BLINDS + val filterElement = FilterElement(filterElementRows = arrayListOf(blind)) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -84,12 +83,12 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.BLINDS - filter.valueMap = mapOf("blinds" to arrayOf(mapOf( - "sb" to null, - "bb" to 1.0, - "code" to null - ))) + val filter = QueryType.BLINDS + val blind = FilterElementRow.Blind(null, 1.0, null) + blind.filterSectionRow = FilterSectionRow.BLINDS + + val filterElement = FilterElement(filterElementRows = arrayListOf(blind)) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -131,12 +130,12 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.BLINDS - filter.valueMap = mapOf("blinds" to arrayOf(mapOf( - "sb" to 1.0, - "bb" to 2.0, - "code" to "AUD" - ))) + val filter = QueryType.BLINDS + val blind = FilterElementRow.Blind(1.0, 2.0, "AUD") + blind.filterSectionRow = FilterSectionRow.BLINDS + + val filterElement = FilterElement(filterElementRows = arrayListOf(blind)) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -178,18 +177,14 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.BLINDS - filter.valueMap = mapOf("blinds" to arrayOf( - mapOf( - "sb" to 1.0, - "bb" to 2.0, - "code" to null - ), - mapOf( - "sb" to 0.5, - "bb" to 1.0, - "code" to null - ))) + val filter = QueryType.BLINDS + val blind1 = FilterElementRow.Blind(1.0, 2.0, null) + blind1.filterSectionRow = FilterSectionRow.BLINDS + + val blind2 = FilterElementRow.Blind(0.5, 1.0, null) + blind2.filterSectionRow = FilterSectionRow.BLINDS + val filterElement = FilterElement(filterElementRows = arrayListOf(blind1, blind2)) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, diff --git a/app/src/androidTest/java/net/pokeranalytics/android/filter/DateFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/filter/DateFilterInstrumentedUnitTest.kt index ca6f2f21..3f506258 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/filter/DateFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/filter/DateFilterInstrumentedUnitTest.kt @@ -1,9 +1,13 @@ package net.pokeranalytics.android.filter import androidx.test.ext.junit.runners.AndroidJUnit4 -import net.pokeranalytics.android.model.filter.FilterType +import io.realm.RealmList +import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.model.realm.Filter +import net.pokeranalytics.android.model.realm.FilterElement import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -25,9 +29,13 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, cal.time) realm.commitTransaction() - val filter = FilterType.DAY_OF_WEEK + val filter = QueryType.DAY_OF_WEEK cal.time = s1.startDate - filter.valueMap = mapOf("dayOfWeek" to cal.get(Calendar.DAY_OF_WEEK)) + + val filterElementRow = FilterElementRow.Day(cal.get(Calendar.DAY_OF_WEEK)) + filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE + val filterElement = FilterElement(filterElementRow) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -54,9 +62,13 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, cal.time) realm.commitTransaction() - val filter = FilterType.MONTH + val filter = QueryType.MONTH cal.time = s1.startDate - filter.valueMap = mapOf("month" to cal.get(Calendar.MONTH)) + + val filterElementRow = FilterElementRow.Month(cal.get(Calendar.MONTH)) + filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE + val filterElement = FilterElement(filterElementRow) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -83,9 +95,12 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(100.0, true, cal.time) realm.commitTransaction() - val filter = FilterType.YEAR + val filter = QueryType.YEAR cal.time = s1.startDate - filter.valueMap = mapOf("year" to cal.get(Calendar.YEAR)) + val filterElementRow = FilterElementRow.Year(cal.get(Calendar.YEAR)) + filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE + val filterElement = FilterElement(filterElementRow) + filter.updateValueMap(filterElement) val sessions = Filter.queryOn( realm, @@ -116,7 +131,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.WEEK_END) + arrayListOf(QueryType.WEEK_END) ) Assert.assertEquals(1, sessions.size) @@ -141,7 +156,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.WEEK_DAY) + arrayListOf(QueryType.WEEK_DAY) ) Assert.assertEquals(1, sessions.size) @@ -165,8 +180,11 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val s2 = Session.testInstance(100.0, true, cal.time, 1) realm.commitTransaction() - val filter = FilterType.STARTED_FROM_DATE - filter.valueMap = mapOf("date" to s2.startDate) + val filter = QueryType.STARTED_FROM_DATE + val filterElementRow = FilterElementRow.From(s2.startDate!!) + filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE + filter.updateValueMap(FilterElement(filterElementRow)) + val sessions = Filter.queryOn( realm, @@ -195,8 +213,10 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.STARTED_TO_DATE - filter.valueMap = mapOf("date" to s1.startDate) + val filter = QueryType.STARTED_TO_DATE + val filterElementRow = FilterElementRow.From(s1.startDate!!) + filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE + filter.updateValueMap(FilterElement(filterElementRow)) val sessions = Filter.queryOn( realm, @@ -226,8 +246,10 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.ENDED_FROM_DATE - filter.valueMap = mapOf("date" to s2.endDate) + val filter = QueryType.ENDED_FROM_DATE + val filterElementRow = FilterElementRow.From(s2.endDate()) + filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE + filter.updateValueMap(FilterElement(filterElementRow)) val sessions = Filter.queryOn( realm, @@ -257,8 +279,11 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = FilterType.ENDED_TO_DATE - filter.valueMap = mapOf("date" to s1.endDate) + val filter = QueryType.ENDED_TO_DATE + val filterElementRow = FilterElementRow.From(s1.endDate()) + filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE + filter.updateValueMap(FilterElement(filterElementRow)) + val sessions = Filter.queryOn( realm, diff --git a/app/src/androidTest/java/net/pokeranalytics/android/filter/ExceptionFilterInstrumentedTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/filter/ExceptionFilterInstrumentedTest.kt index 1e9aeeea..b484a920 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/filter/ExceptionFilterInstrumentedTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/filter/ExceptionFilterInstrumentedTest.kt @@ -1,10 +1,14 @@ package net.pokeranalytics.android.filter import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.realm.RealmList import net.pokeranalytics.android.exceptions.FilterValueMapException -import net.pokeranalytics.android.model.filter.FilterType +import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.model.realm.Filter +import net.pokeranalytics.android.model.realm.FilterElement import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import org.junit.Test import org.junit.runner.RunWith import java.util.* @@ -14,8 +18,9 @@ class ExceptionFilterInstrumentedTest: BaseFilterInstrumentedUnitTest() { @Test(expected = FilterValueMapException::class) fun testValueKeyFilterException() { - val filter = FilterType.STARTED_FROM_DATE - filter.valueMap = mapOf("bob" to Date()) + val filter = QueryType.STARTED_FROM_DATE + val filterElement = FilterElement() + filter.updateValueMap(filterElement) val realm = this.mockRealm Filter.queryOn( @@ -26,29 +31,14 @@ class ExceptionFilterInstrumentedTest: BaseFilterInstrumentedUnitTest() { } @Test(expected = FilterValueMapException::class) - fun testSubValueKeyFilterException() { - val filter = FilterType.BLINDS - filter.valueMap = mapOf("map" to arrayOf(mapOf( - "bob" to 0.5, - "bb" to 1.0, - "code" to null - ))) - + fun testFilterException() { val realm = this.mockRealm + val filter = QueryType.BLINDS + filter.updateValueMap(FilterElement()) Filter.queryOn( realm, Session, arrayListOf(filter) ) } - - @Test(expected = FilterValueMapException::class) - fun testXFilterException() { - val realm = this.mockRealm - Filter.queryOn( - realm, - Session, - arrayListOf(FilterType.BLINDS) - ) - } } \ No newline at end of file diff --git a/app/src/androidTest/java/net/pokeranalytics/android/filter/RealmFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/filter/RealmFilterInstrumentedUnitTest.kt index 712cc6ad..107433a3 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/filter/RealmFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/filter/RealmFilterInstrumentedUnitTest.kt @@ -1,7 +1,7 @@ package net.pokeranalytics.android.filter import androidx.test.ext.junit.runners.AndroidJUnit4 -import net.pokeranalytics.android.model.filter.FilterType +import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.model.realm.Filter import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow @@ -25,7 +25,7 @@ class RealmFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElement = FilterElementRow.Cash filterElement.filterSectionRow = FilterSectionRow.CASH_TOURNAMENT - filter.componentsFrom(arrayListOf(filterElement)) + filter.createOrUpdateFilterElements(arrayListOf(filterElement)) val useCount = filter.countBy(FilterCategoryRow.GENERAL) Assert.assertEquals(1, useCount) @@ -33,10 +33,10 @@ class RealmFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val isCash = filter.contains(filterElement) Assert.assertEquals(true, isCash) - val filterComponent = filter.components.first() + val filterComponent = filter.filterElements.first() filterComponent?.let { - Assert.assertEquals(FilterType.CASH, FilterType.valueOf(it.filterName)) + Assert.assertEquals(QueryType.CASH, QueryType.valueOf(it.filterName)) } ?: run { Assert.fail() } diff --git a/app/src/androidTest/java/net/pokeranalytics/android/filter/SessionFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/filter/SessionFilterInstrumentedUnitTest.kt index 86513d6f..0c125b6c 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/filter/SessionFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/filter/SessionFilterInstrumentedUnitTest.kt @@ -2,8 +2,11 @@ package net.pokeranalytics.android.filter import androidx.test.ext.junit.runners.AndroidJUnit4 import io.realm.RealmList -import net.pokeranalytics.android.model.filter.FilterType +import net.pokeranalytics.android.model.TableSize +import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.model.realm.* +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -25,7 +28,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.CASH) + arrayListOf(QueryType.CASH) ) Assert.assertEquals(1, sessions.size) @@ -47,7 +50,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.TOURNAMENT) + arrayListOf(QueryType.TOURNAMENT) ) Assert.assertEquals(1, sessions.size) @@ -74,7 +77,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.LIVE) + arrayListOf(QueryType.LIVE) ) Assert.assertEquals(1, sessions.size) @@ -100,7 +103,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val sessions = Filter.queryOn( realm, Session, - arrayListOf(FilterType.ONLINE) + arrayListOf(QueryType.ONLINE) ) Assert.assertEquals(1, sessions.size) @@ -121,8 +124,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(bankroll = b2) realm.commitTransaction() - val filter = FilterType.BANKROLL - filter.valueMap = mapOf("ids" to arrayOf(b1.id)) + val filter = QueryType.BANKROLL + val filterElementRow = FilterElementRow.Bankroll(b1) + filterElementRow.filterSectionRow = FilterSectionRow.BANKROLL + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow))) val sessions = Filter.queryOn( realm, @@ -154,8 +159,13 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(bankroll = b3) realm.commitTransaction() - val filter = FilterType.BANKROLL - filter.valueMap = mapOf("ids" to arrayOf(b1.id, b2.id)) + val filter = QueryType.BANKROLL + val filterElementRow = FilterElementRow.Bankroll(b1) + filterElementRow.filterSectionRow = FilterSectionRow.BANKROLL + + val filterElementRow2 = FilterElementRow.Bankroll(b2) + filterElementRow2.filterSectionRow = FilterSectionRow.BANKROLL + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) val sessions = Filter.queryOn( realm, @@ -182,8 +192,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(game = g2) realm.commitTransaction() - val filter = FilterType.GAME - filter.valueMap = mapOf("ids" to arrayOf(g2.id)) + val filter = QueryType.GAME + val filterElementRow = FilterElementRow.Game(g2) + filterElementRow.filterSectionRow = FilterSectionRow.GAME + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow))) val sessions = Filter.queryOn( realm, @@ -215,8 +227,13 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(game = g3) realm.commitTransaction() - val filter = FilterType.GAME - filter.valueMap = mapOf("ids" to arrayOf(g2.id, g3.id)) + val filter = QueryType.GAME + + val filterElementRow = FilterElementRow.Game(g2) + filterElementRow.filterSectionRow = FilterSectionRow.GAME + val filterElementRow2 = FilterElementRow.Game(g3) + filterElementRow2.filterSectionRow = FilterSectionRow.GAME + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) val sessions = Filter.queryOn( realm, @@ -243,8 +260,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(location = l2) realm.commitTransaction() - val filter = FilterType.LOCATION - filter.valueMap = mapOf("ids" to arrayOf(l1.id)) + val filter = QueryType.LOCATION + val filterElementRow = FilterElementRow.Location(l1) + filterElementRow.filterSectionRow = FilterSectionRow.LOCATION + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow))) val sessions = Filter.queryOn( realm, @@ -276,8 +295,14 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(location = l3) realm.commitTransaction() - val filter = FilterType.LOCATION - filter.valueMap = mapOf("ids" to arrayOf(l1.id, l3.id)) + val filter = QueryType.LOCATION + + val filterElementRow = FilterElementRow.Location(l1) + filterElementRow.filterSectionRow = FilterSectionRow.LOCATION + val filterElementRow2 = FilterElementRow.Location(l3) + filterElementRow2.filterSectionRow = FilterSectionRow.LOCATION + + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) val sessions = Filter.queryOn( realm, @@ -304,8 +329,11 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tournamentName = t2) realm.commitTransaction() - val filter = FilterType.TOURNAMENT_NAME - filter.valueMap = mapOf("ids" to arrayOf(t1.id)) + val filter = QueryType.TOURNAMENT_NAME + + val filterElementRow = FilterElementRow.TournamentName(t1) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_NAME + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow))) val sessions = Filter.queryOn( realm, @@ -337,8 +365,12 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tournamentName = t3) realm.commitTransaction() - val filter = FilterType.TOURNAMENT_NAME - filter.valueMap = mapOf("ids" to arrayOf(t1.id, t2.id)) + val filter = QueryType.TOURNAMENT_NAME + val filterElementRow = FilterElementRow.TournamentName(t1) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_NAME + val filterElementRow2 = FilterElementRow.TournamentName(t2) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_NAME + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) val sessions = Filter.queryOn( realm, @@ -373,8 +405,14 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tournamentFeatures = RealmList(t1)) realm.commitTransaction() - val filter = FilterType.ALL_TOURNAMENT_FEATURES - filter.valueMap = mapOf("ids" to arrayOf(t1.id, t2.id, t3.id, t4.id)) + val filter = QueryType.ALL_TOURNAMENT_FEATURES + val filterElementRow = FilterElementRow.AllTournamentFeature(t1) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + val filterElementRow2 = FilterElementRow.AllTournamentFeature(t2) + filterElementRow2.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + val filterElementRow3 = FilterElementRow.AllTournamentFeature(t4) + filterElementRow3.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3))) val sessions = Filter.queryOn( realm, @@ -406,8 +444,16 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tournamentFeatures = RealmList(t1)) realm.commitTransaction() - val filter = FilterType.ANY_TOURNAMENT_FEATURES - filter.valueMap = mapOf("ids" to arrayOf(t1.id, t2.id, t3.id, t4.id)) + val filter = QueryType.ANY_TOURNAMENT_FEATURES + val filterElementRow = FilterElementRow.AnyTournamentFeature(t1) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + val filterElementRow2 = FilterElementRow.AnyTournamentFeature(t2) + filterElementRow2.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + val filterElementRow3 = FilterElementRow.AnyTournamentFeature(t3) + filterElementRow3.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + val filterElementRow4 = FilterElementRow.AnyTournamentFeature(t4) + filterElementRow4.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2, filterElementRow3, filterElementRow4))) val sessions = Filter.queryOn( realm, @@ -436,8 +482,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tournamentFeatures = RealmList(t1)) realm.commitTransaction() - val filter = FilterType.ANY_TOURNAMENT_FEATURES - filter.valueMap = mapOf("ids" to arrayOf(t2.id)) + val filter = QueryType.ANY_TOURNAMENT_FEATURES + val filterElementRow = FilterElementRow.AnyTournamentFeature(t2) + filterElementRow.filterSectionRow = FilterSectionRow.TOURNAMENT_FEATURE + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow))) val sessions = Filter.queryOn( realm, @@ -463,8 +511,12 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(tableSize = 10) realm.commitTransaction() - val filter = FilterType.TABLE_SIZE - filter.valueMap = mapOf("values" to arrayOf(2,4)) + val filter = QueryType.TABLE_SIZE + val filterElementRow = FilterElementRow.TableSize(TableSize(2)) + filterElementRow.filterSectionRow = FilterSectionRow.TABLE_SIZE + val filterElementRow2 = FilterElementRow.TableSize(TableSize(4)) + filterElementRow.filterSectionRow = FilterSectionRow.TABLE_SIZE + filter.updateValueMap(FilterElement(filterElementRows = arrayListOf(filterElementRow, filterElementRow2))) val sessions = Filter.queryOn( realm, @@ -490,8 +542,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val s2 = Session.testInstance(netResult = 570.0) realm.commitTransaction() - val filter = FilterType.MORE_THAN_NET_RESULT - filter.valueMap = mapOf("value" to 204.0) + val filter = QueryType.MORE_THAN_NET_RESULT + val filterElementRow = FilterElementRow.ResultMoreThan(204.0) + filterElementRow.filterSectionRow = FilterSectionRow.VALUE + filter.updateValueMap(FilterElement(filterElementRow)) val sessions = Filter.queryOn( realm, @@ -517,8 +571,10 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(netResult = 570.0) realm.commitTransaction() - val filter = FilterType.LESS_THAN_NET_RESULT - filter.valueMap = mapOf("value" to 540.0) + val filter = QueryType.LESS_THAN_NET_RESULT + val filterElementRow = FilterElementRow.ResultLessThan(540.0) + filterElementRow.filterSectionRow = FilterSectionRow.VALUE + filter.updateValueMap(FilterElement(filterElementRow)) val sessions = Filter.queryOn( realm, @@ -544,11 +600,15 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Session.testInstance(netResult = 570.0) realm.commitTransaction() - val filterMore = FilterType.MORE_THAN_NET_RESULT - filterMore.valueMap = mapOf("value" to 200.0) + val filterMore = QueryType.MORE_THAN_NET_RESULT + val filterElementRow = FilterElementRow.ResultMoreThan(200.0) + filterElementRow.filterSectionRow = FilterSectionRow.VALUE + filterMore.updateValueMap(FilterElement(filterElementRow)) - val filterLess = FilterType.LESS_THAN_NET_RESULT - filterLess.valueMap = mapOf("value" to 400.0) + val filterLess = QueryType.LESS_THAN_NET_RESULT + val filterElementRow2 = FilterElementRow.ResultLessThan(400.0) + filterElementRow2.filterSectionRow = FilterSectionRow.VALUE + filterLess.updateValueMap(FilterElement(filterElementRow2)) val sessions = Filter.queryOn( realm, diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index b8173952..f657b5d3 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -28,7 +28,7 @@ class Calculator { } /** - * The type of evolution values + * The type of evolution numericValues */ enum class EvolutionValues { NONE, @@ -82,7 +82,7 @@ class Calculator { results.computeStatVariations(comparedResults) } - results.finalize(options) // later treatment, such as evolution values sorting + results.finalize(options) // later treatment, such as evolution numericValues sorting computedResults.add(results) val e = Date() diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/ComputableGroup.kt b/app/src/main/java/net/pokeranalytics/android/calculus/ComputableGroup.kt index 211af750..d0653c92 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/ComputableGroup.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/ComputableGroup.kt @@ -51,7 +51,7 @@ class ComputedResults(group: ComputableGroup) { // The computed stats of the sessionGroup private var _computedStats: MutableMap = mutableMapOf() - // The map containing all evolution values for all stats + // The map containing all evolution numericValues for all stats private var _evolutionValues: MutableMap> = mutableMapOf() fun allStats() : Collection { diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 41e15ef2..e3f557c9 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -35,7 +35,7 @@ enum class Stat : RowRepresentable { HANDS_PLAYED; /** - * Returns whether the stat evolution values requires a distribution sorting + * Returns whether the stat evolution numericValues requires a distribution sorting */ fun hasDistributionSorting() : Boolean { return when (this) { @@ -129,7 +129,7 @@ class ComputedStat(var stat: Stat, var value: Double, var currency: Currency? = val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red return TextFormat(numberFormat.format(this.value), color) } - // Red/green values + // Red/green numericValues Stat.HOURLY_RATE_BB, Stat.AVERAGE_NET_BB, Stat.NET_BB_PER_100_HANDS -> { val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red return TextFormat(this.value.formatted(), color) diff --git a/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt index deefbc3c..5a4ae6cf 100644 --- a/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt +++ b/app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt @@ -13,5 +13,7 @@ class RowRepresentableEditDescriptorException(message: String) : Exception(messa } class FilterValueMapException(message: String) : Exception(message) { - + init { + println("FilterValueMapException(): $message") + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/FilterEntityDataSource.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt similarity index 73% rename from app/src/main/java/net/pokeranalytics/android/model/filter/FilterEntityDataSource.kt rename to app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt index ce8e0a2a..8d19eb7e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/FilterEntityDataSource.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt @@ -21,21 +21,29 @@ import io.realm.RealmObject * - multiple field filters should be handled as 'AND' * - multiple '=' filters as 'OR' * - multiple 'Greater than', 'less than' as 'AND' - * - multiple values as 'OR' + * - multiple numericValues as 'OR' * * Also: * A filter should be able to be converted into a Realm query * */ -interface FilterEntityDataSource { + +/** + * Interface to set at companion object level of a realm object to provide the entity and the fieldName (eg: parameter's path) + */ +interface Filterable { + val relatedEntity: Class - fun fieldNameForQueryType(filterType: FilterType) : String? + /** + * return the path of the parameter used in the [QueryType] related to this entity + */ + fun fieldNameForQueryType(queryType: QueryType) : String? } // -//fun MutableList.filter(filter: FilterComponent) : List { +//fun MutableList.filter(filter: FilterElement) : List { // // return this.filter { f -> // return@filter true diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/FilterType.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryType.kt similarity index 73% rename from app/src/main/java/net/pokeranalytics/android/model/filter/FilterType.kt rename to app/src/main/java/net/pokeranalytics/android/model/filter/QueryType.kt index f7e8bdf4..34641b73 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/FilterType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryType.kt @@ -1,39 +1,22 @@ package net.pokeranalytics.android.model.filter +import io.realm.RealmList import io.realm.RealmObject import io.realm.RealmQuery import net.pokeranalytics.android.exceptions.FilterValueMapException -import net.pokeranalytics.android.model.realm.FilterComponent +import net.pokeranalytics.android.model.realm.FilterElementBlind +import net.pokeranalytics.android.model.realm.FilterElement import net.pokeranalytics.android.model.realm.Session import java.util.* + /** - * We want to be able to store filters in the database: - * - filters can be a combination of sub filters - * - filters can be applied to different type of objects: Sessions, Hands, Transactions... - * - filters can be applied to a list of different type of objects (feed) - * - * A filter is described by the following: - * - a data type: Session, Hands... - * - a field: table size of a Session - * - an operator: equal, >=, <... - * - a value: an id, a number, a date... - * - * We can decide to have a collection of [operator, value] for a field - * - * Combination: - * - multiple datatype filters should be handled as 'OR' - * - multiple field filters should be handled as 'AND' - * - multiple '=' filters as 'OR' - * - multiple 'Greater than', 'less than' as 'AND' - * - multiple values as 'OR' - * - * Also: - * A filter should be able to be converted into a Realm query - * + * Enum describing the way a query should be handled + * Some queries requires a value to be checked upon through equals, in, more, less, between + * To handle that, the enum has a public [valueMap] variable + * A new type should also set the expected numericValues required in the [filterValuesExpectedKeys] */ - -enum class FilterType(private var subType:SubType? = null) { +enum class QueryType(private var subType:SubType? = null) { LIVE, CASH, ONLINE, @@ -100,7 +83,7 @@ enum class FilterType(private var subType:SubType? = null) { } } return when (this) { - BANKROLL, GAME, LOCATION, ANY_TOURNAMENT_FEATURES, ALL_TOURNAMENT_FEATURES -> arrayOf("ids") + BANKROLL, GAME, LOCATION, ANY_TOURNAMENT_FEATURES, ALL_TOURNAMENT_FEATURES, TOURNAMENT_NAME -> arrayOf("ids") LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> arrayOf("values") BLINDS -> arrayOf("blinds") STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> arrayOf("date") @@ -111,43 +94,37 @@ enum class FilterType(private var subType:SubType? = null) { } } - fun filter(realmQuery: RealmQuery, filterEntityDataSource: FilterEntityDataSource): RealmQuery { + /** + * main method of the enum + * providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery] + */ + fun filter(realmQuery: RealmQuery, filterable: Filterable): RealmQuery { when { this == BLINDS -> { - val smallBlindFieldName = filterEntityDataSource.fieldNameForQueryType(SMALL_BLIND) - val bigBlindFieldName = filterEntityDataSource.fieldNameForQueryType(BIG_BLIND) - val currencyCodeFieldName = filterEntityDataSource.fieldNameForQueryType(CURRENCY_CODE) + val smallBlindFieldName = filterable.fieldNameForQueryType(SMALL_BLIND) + val bigBlindFieldName = filterable.fieldNameForQueryType(BIG_BLIND) + val currencyCodeFieldName = filterable.fieldNameForQueryType(CURRENCY_CODE) smallBlindFieldName ?: throw FilterValueMapException("fieldName is missing") bigBlindFieldName ?: throw FilterValueMapException("fieldName is missing") currencyCodeFieldName ?: throw FilterValueMapException("fieldName is missing") - val blinds: Array> by valueMap - val expectedSubKeys = arrayOf("sb", "bb", "code") - blinds.forEachIndexed { index, subMap -> - val missingKeys = subMap.keys.filter { !expectedSubKeys.contains(it) } - if (subMap.keys.size == expectedSubKeys.size && missingKeys.isNotEmpty()) { - throw FilterValueMapException("subValueMap does not contain $missingKeys") - } - - val sb: Double? by subMap - val bb: Double? by subMap - val code: String? by subMap - + val blinds: RealmList by valueMap + blinds.forEachIndexed {index, blind -> realmQuery .beginGroup() - sb?.let { + blind.sb?.let { realmQuery - .equalTo(smallBlindFieldName, sb) + .equalTo(smallBlindFieldName, it) .and() } realmQuery - .equalTo(bigBlindFieldName, bb) + .equalTo(bigBlindFieldName, blind.bb) .and() - code?.let { - realmQuery.equalTo(currencyCodeFieldName, code) + blind.code?.let { + realmQuery.equalTo(currencyCodeFieldName, it) } ?: run { realmQuery.isNull(currencyCodeFieldName) } @@ -160,11 +137,11 @@ enum class FilterType(private var subType:SubType? = null) { } return realmQuery } - this == ONLINE -> return LIVE.filter(realmQuery.not(), filterEntityDataSource) - this == TOURNAMENT -> return CASH.filter(realmQuery.not(), filterEntityDataSource) - this == WEEK_DAY -> return WEEK_END.filter(realmQuery.not(), filterEntityDataSource) + this == ONLINE -> return LIVE.filter(realmQuery.not(), filterable) + this == TOURNAMENT -> return CASH.filter(realmQuery.not(), filterable) + this == WEEK_DAY -> return WEEK_END.filter(realmQuery.not(), filterable) else -> { - val fieldName = filterEntityDataSource.fieldNameForQueryType(this) + val fieldName = filterable.fieldNameForQueryType(this) fieldName ?: throw FilterValueMapException("fieldName is missing") this.subType?.let { subType -> @@ -247,7 +224,7 @@ enum class FilterType(private var subType:SubType? = null) { } - fun setValueFrom(filterComponent: FilterComponent) { + fun updateValueMap(filterElement: FilterElement) { if (filterValuesExpectedKeys == null) { return } @@ -255,38 +232,39 @@ enum class FilterType(private var subType:SubType? = null) { this.subType?.let { subType -> valueMap = when (subType) { SubType.LESS, SubType.MORE -> { - mapOf("value" to filterComponent.value) + mapOf("value" to filterElement.value) } SubType.BETWEEN -> { mapOf( - "leftValue" to filterComponent.leftValue, - "rightValue" to filterComponent.rightValue + "leftValue" to filterElement.leftValue, + "rightValue" to filterElement.rightValue ) } } + return } when (this) { ALL_TOURNAMENT_FEATURES, ANY_TOURNAMENT_FEATURES, BANKROLL, GAME, LOCATION, TOURNAMENT_NAME -> { - valueMap = mapOf("ids" to filterComponent.ids) + valueMap = mapOf("ids" to filterElement.ids) } LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> { - valueMap = mapOf("values" to filterComponent.values) + valueMap = mapOf("values" to filterElement.values) } BLINDS -> { - valueMap = mapOf("blinds" to filterComponent.blinds) + valueMap = mapOf("blinds" to filterElement.blinds) } STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> { - valueMap = mapOf("date" to filterComponent.date) + valueMap = mapOf("date" to filterElement.date) } DAY_OF_WEEK -> { - valueMap = mapOf("dayOfWeek" to filterComponent.dayOfWeek) + valueMap = mapOf("dayOfWeek" to filterElement.dayOfWeek) } MONTH -> { - valueMap = mapOf("month" to filterComponent.month) + valueMap = mapOf("month" to filterElement.month) } YEAR -> { - valueMap = mapOf("year" to filterComponent.year) + valueMap = mapOf("year" to filterElement.year) } else -> { throw FilterValueMapException("filter type not handled") @@ -308,5 +286,7 @@ enum class FilterType(private var subType:SubType? = null) { } return field } + private set + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/interfaces/TimeFilterable.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/TimeFilterable.kt similarity index 69% rename from app/src/main/java/net/pokeranalytics/android/model/filter/interfaces/TimeFilterable.kt rename to app/src/main/java/net/pokeranalytics/android/model/interfaces/TimeFilterable.kt index f4713e4b..a83cc2e1 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/interfaces/TimeFilterable.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/TimeFilterable.kt @@ -1,7 +1,10 @@ -package net.pokeranalytics.android.model.filter.interfaces +package net.pokeranalytics.android.model.interfaces import java.util.* +/** + * Interface to let an object be filtered through specific time parameters + */ interface TimeFilterable { var dayOfWeek : Int? @@ -9,6 +12,9 @@ interface TimeFilterable { var month : Int? var year : Int? + /** + * Call this method whenever the date of the object is modified + */ fun updateTimeParameter(startDate: Date?) { startDate?.let { val cal = Calendar.getInstance() diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index 4567c982..37481aaf 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -2,17 +2,24 @@ package net.pokeranalytics.android.model.realm import io.realm.* import io.realm.annotations.PrimaryKey -import net.pokeranalytics.android.model.filter.FilterEntityDataSource -import net.pokeranalytics.android.model.filter.FilterType +import net.pokeranalytics.android.model.filter.Filterable +import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow +import org.jetbrains.annotations.TestOnly import java.util.* +/** + * A [Filter] is the top level representation of the filtering system + * It contains a list of [FilterElement] describing the complete query to launch + * The [Filter] is working closely with a [Filterable] interface providing the entity we want the query being launched on + */ open class Filter : RealmObject() { companion object { - fun queryOn(realm: Realm, entity: FilterEntityDataSource, queries:List): RealmResults<*> { + @TestOnly + fun queryOn(realm: Realm, entity: Filterable, queries:List): RealmResults<*> { var realmQuery : RealmQuery = realm.where(entity.relatedEntity) queries.forEach { realmQuery = (it.filter(realmQuery, entity)) @@ -31,11 +38,11 @@ open class Filter : RealmObject() { // for MutableRealmInteger, see https://realm.io/docs/java/latest/#counters val usageCount: MutableRealmInteger = MutableRealmInteger.valueOf(0) - var components: RealmList = RealmList() + var filterElements: RealmList = RealmList() private set - fun componentsFrom(filterElementRows: ArrayList) { - components.clear() + fun createOrUpdateFilterElements(filterElementRows: ArrayList) { + filterElements.clear() filterElementRows .map { it.filterSectionRow @@ -47,26 +54,28 @@ open class Filter : RealmObject() { it.filterSectionRow == section } .apply { + if (this.size == 1) { - components.add(FilterComponent(this.first())) + filterElements.add(FilterElement(this.first())) } else { val casted = arrayListOf() casted.addAll(this) - components.add(FilterComponent(casted)) + filterElements.add(FilterElement(casted)) } + } } } fun countBy(filterCategoryRow: FilterCategoryRow) : Int { val sections = filterCategoryRow.filterSectionRows - return components.count { + return filterElements.count { sections.contains(FilterSectionRow.valueOf(it.sectionName)) } } fun contains(filterElementRow:FilterElementRow) : Boolean { - val filtered = components.filter { + val filtered = filterElements.filter { it.filterName == filterElementRow.filterName } if (filtered.isEmpty()) { @@ -75,10 +84,10 @@ open class Filter : RealmObject() { return filterElementRow.contains(filtered) } - fun queryOn(entity: FilterEntityDataSource) : RealmResults<*> { + fun queryOn(entity: Filterable) : RealmResults<*> { var realmQuery : RealmQuery = realm.where(entity.relatedEntity) - this.components.map { - it.filterType + this.filterElements.map { + it.queryType }.forEach { realmQuery = (it.filter(realmQuery, entity)) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterComponent.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterComponent.kt deleted file mode 100644 index 4330ba9e..00000000 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterComponent.kt +++ /dev/null @@ -1,81 +0,0 @@ -package net.pokeranalytics.android.model.realm - -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.Ignore -import net.pokeranalytics.android.model.filter.FilterType -import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow -import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow.* -import java.util.* -import kotlin.collections.ArrayList - -open class FilterComponent(var filterName : String = "", var sectionName: String = "") : RealmObject() { - - constructor(filterElementRows: ArrayList) : this(filterElementRows.first().filterName, filterElementRows.first().filterSectionRow.name) { - this.ids = when (FilterType.valueOf(this.filterName)) { - FilterType.GAME -> { - RealmList().apply { - this.addAll(filterElementRows.map { - (it as FilterElementRow.Game).game.id - }) - } - } - else -> null - } - - this.values = when (FilterType.valueOf(filterName)) { - FilterType.LIMIT -> { - RealmList().apply { - this.addAll(filterElementRows.map { - (it as FilterElementRow.Limit).limit.ordinal - }) - } - } - else -> null - } - } - - constructor(filterElementRow:FilterElementRow) : this(filterElementRow.filterName, filterElementRow.filterSectionRow.name) { - when (filterElementRow) { - is From -> date = filterElementRow.date - is To -> date = filterElementRow.date - } - } - - val filterType : FilterType - get() = FilterType.valueOf(filterName) - .apply { - this.setValueFrom(this@FilterComponent) - } - - var date : Date? = null - var values : RealmList? = null - var ids : RealmList? = null - - @Ignore - val value : Double? = null - - @Ignore - val leftValue : Double? = null - - @Ignore - val rightValue : Double? = null - - @Ignore - val blinds : Array>? = null - - @Ignore - val dayOfWeek : Int? = null - - @Ignore - val month : Int? = null - - @Ignore - val year : Int? = null -} - -open class BlindFilterComponent : RealmObject() { - var sb : Double? = null - var bb : Double? = null - var code : String? = null -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElement.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElement.kt new file mode 100644 index 00000000..be590588 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElement.kt @@ -0,0 +1,144 @@ +package net.pokeranalytics.android.model.realm + +import io.realm.RealmList +import io.realm.RealmObject +import net.pokeranalytics.android.exceptions.FilterValueMapException +import net.pokeranalytics.android.model.filter.QueryType +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow +import net.pokeranalytics.android.ui.view.rowrepresentable.FilterElementRow.* +import java.util.* +import kotlin.collections.ArrayList + +open class FilterElement(var filterName : String = "", var sectionName: String = "") : RealmObject() { + + constructor(filterElementRows: ArrayList) : this(filterElementRows.first().filterName, filterElementRows.first().filterSectionRow.name) { + this.stringValues = when (QueryType.valueOf(this.filterName)) { + QueryType.GAME, QueryType.BANKROLL, QueryType.TOURNAMENT_NAME, QueryType.ALL_TOURNAMENT_FEATURES, QueryType.ANY_TOURNAMENT_FEATURES, QueryType.LOCATION -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as DataFilterElementRow).id + }) + } + } + else -> null + } + + this.numericValues = when (QueryType.valueOf(filterName)) { + QueryType.LIMIT -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as FilterElementRow.Limit).limit.ordinal.toDouble() + }) + } + } + QueryType.TABLE_SIZE -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as FilterElementRow.TableSize).tableSize.numberOfPlayer.toDouble() + }) + } + } + QueryType.YEAR, QueryType.MONTH, QueryType.DAY_OF_WEEK -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as SingleValueFilterElementRow).value.toDouble() + }) + } + } + QueryType.LESS_THAN_NET_RESULT -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as ResultLessThan).value + }) + } + } + QueryType.MORE_THAN_NET_RESULT -> { + RealmList().apply { + this.addAll(filterElementRows.map { + (it as ResultMoreThan).value + }) + } + } + else -> null + } + + this.blindValues = when (QueryType.valueOf(filterName)) { + QueryType.BLINDS -> { + RealmList().apply { + this.addAll(filterElementRows.map { + FilterElementBlind((it as FilterElementRow.Blind).sb, it.bb, it.code) + }) + } + } + else -> null + } + } + + constructor(filterElementRow:FilterElementRow) : this(arrayListOf(filterElementRow)) { + when (filterElementRow) { + is From -> dateValue = filterElementRow.date + is To -> dateValue= filterElementRow.date + } + } + + val queryType : QueryType + get() = QueryType.valueOf(filterName) + .apply { + this.updateValueMap(this@FilterElement) + } + + private var numericValues: RealmList? = null + private var dateValue : Date? = null + private var stringValues : RealmList? = null + private var blindValues : RealmList? = null + + val ids : Array + get() = stringValues?.toTypedArray()?: throw FilterValueMapException("filter type not handled") + + val blinds : RealmList + get() { + blindValues?.let { + if (it.isNotEmpty()) { + return it + } else { + throw FilterValueMapException("filter is empty or null") + } + } + throw FilterValueMapException("filter is empty or null") + } + + + val date : Date + get() = dateValue?: throw FilterValueMapException("filter type not handled") + + + val values : Array + get() = numericValues?.map { + it.toInt() + }?.toTypedArray()?: throw FilterValueMapException("filter type not handled") + + + val value : Double + get() = numericValues?.first()?: throw FilterValueMapException("filter type not handled") + + + val leftValue : Double + get() = numericValues?.first()?: throw FilterValueMapException("filter type not handled") + + + val rightValue : Double + get() = numericValues?.last()?: throw FilterValueMapException("filter type not handled") + + + val dayOfWeek : Int + get() = numericValues?.first()?.toInt()?: throw FilterValueMapException("filter type not handled") + + + val month : Int + get() = numericValues?.first()?.toInt()?: throw FilterValueMapException("filter type not handled") + + + val year : Int + get() = numericValues?.first()?.toInt()?: throw FilterValueMapException("filter type not handled") + +} diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt new file mode 100644 index 00000000..fb615cbb --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt @@ -0,0 +1,8 @@ +package net.pokeranalytics.android.model.realm + +import io.realm.RealmObject + +open class FilterElementBlind(var sb : Double? = null, + var bb : Double? = null, + var code : String? = null +) : RealmObject() \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 2d403971..b70e7c67 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -20,10 +20,10 @@ import net.pokeranalytics.android.model.TableSize import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.extensions.SessionState import net.pokeranalytics.android.model.extensions.getState -import net.pokeranalytics.android.model.filter.FilterEntityDataSource -import net.pokeranalytics.android.model.filter.FilterType -import net.pokeranalytics.android.model.filter.FilterType.* -import net.pokeranalytics.android.model.filter.interfaces.TimeFilterable +import net.pokeranalytics.android.model.filter.Filterable +import net.pokeranalytics.android.model.filter.QueryType +import net.pokeranalytics.android.model.filter.QueryType.* +import net.pokeranalytics.android.model.interfaces.TimeFilterable import net.pokeranalytics.android.model.interfaces.Manageable import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.model.utils.SessionSetManager @@ -43,14 +43,14 @@ import java.util.Currency import kotlin.collections.ArrayList open class Session : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Timed, - TimeFilterable { + TimeFilterable { enum class Type { CASH_GAME, TOURNAMENT } - companion object : FilterEntityDataSource { + companion object : Filterable { fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null): Session { val session = Session() session.result = Result() @@ -65,8 +65,8 @@ open class Session : RealmObject(), Manageable, StaticRowRepresentableDataSource override val relatedEntity: Class = Session::class.java - override fun fieldNameForQueryType(filterType: FilterType): String? { - return when (filterType) { + override fun fieldNameForQueryType(queryType: QueryType): String? { + return when (queryType) { LIVE -> "bankroll.live" CASH -> "type" BANKROLL -> "bankroll.id" diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt index e313e0cd..ca6b308e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt @@ -102,7 +102,7 @@ class UnmanagedRowRepresentableException(message: String) : Exception(message) { * - string * - booleans * - actionIcon - * to display the appropriate values in graphical components, such as labels, textfields, switchs... + * to display the appropriate numericValues in graphical filterElements, such as labels, textfields, switchs... */ interface DisplayableDataSource { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt index c41b27d9..1542a281 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt @@ -199,7 +199,7 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta /* this.dataType = dataType - this.liveDataType = LiveData.values()[dataType] + this.liveDataType = LiveData.numericValues()[dataType] this.primaryKey = primaryKey */ } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt index ca2c818e..866bb937 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt @@ -29,7 +29,7 @@ interface DefaultEditable : Editable, Localizable { } /** - * An interface used so that enums values can be represented visually + * An interface used so that enums numericValues can be represented visually * as rows in RecyclerViews */ interface Displayable : Localizable { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt index 35cecdf6..7a899662 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt @@ -2,8 +2,9 @@ package net.pokeranalytics.android.ui.view.rowrepresentable import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FilterValueMapException -import net.pokeranalytics.android.model.filter.FilterType -import net.pokeranalytics.android.model.realm.FilterComponent +import net.pokeranalytics.android.model.filter.QueryType +import net.pokeranalytics.android.model.interfaces.Manageable +import net.pokeranalytics.android.model.realm.FilterElement import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType @@ -24,76 +25,78 @@ sealed class FilterElementRow : RowRepresentable { object Weekday: FilterElementRow() object Weekend : FilterElementRow() + open class DataFilterElementRow(data:Manageable) : FilterElementRow() { + val id : String = data.id + val name : String = (data as RowRepresentable).getDisplayName() + } + + open class SingleValueFilterElementRow(val value:Int) : FilterElementRow() + + data class Blind(var sb: Double? = null, var bb: Double? = null, var code: String? = null) : FilterElementRow() data class From(var date: Date = Date()) : FilterElementRow() data class To(var date: Date = Date()) : FilterElementRow() - data class Year(val day: Int) : FilterElementRow() - data class Month(val day: Int) : FilterElementRow() - data class Day(val day: Int) : FilterElementRow() + data class Year(val year: Int) : SingleValueFilterElementRow(year) + data class Month(val month: Int) : SingleValueFilterElementRow(month) + data class Day(val day: Int) : SingleValueFilterElementRow(day) data class PastDays(var lastDays : Int = 0) : FilterElementRow() data class Limit(val limit : net.pokeranalytics.android.model.Limit) : FilterElementRow() data class TableSize(val tableSize : net.pokeranalytics.android.model.TableSize) : FilterElementRow() - data class Bankroll(val bankroll: net.pokeranalytics.android.model.realm.Bankroll) : FilterElementRow() - data class Game(val game: net.pokeranalytics.android.model.realm.Game) : FilterElementRow() - data class Location(val location: net.pokeranalytics.android.model.realm.Location) : FilterElementRow() - data class TournamentName(val tournamentName: net.pokeranalytics.android.model.realm.TournamentName) : FilterElementRow() - data class TournamentFeature(val tournamentFeature: net.pokeranalytics.android.model.realm.TournamentFeature) : FilterElementRow() + data class Bankroll(val bankroll: Manageable) : DataFilterElementRow(bankroll) + data class Game(val game: Manageable) : DataFilterElementRow(game) + data class Location(val location: Manageable) : DataFilterElementRow(location) + data class TournamentName(val tournamentName: Manageable) : DataFilterElementRow(tournamentName) + data class AllTournamentFeature(val tournamentFeature: Manageable) : DataFilterElementRow(tournamentFeature) + data class AnyTournamentFeature(val tournamentFeature: Manageable) : DataFilterElementRow(tournamentFeature) + data class ResultMoreThan(var value:Double) : FilterElementRow() + data class ResultLessThan(var value:Double) : FilterElementRow() lateinit var filterSectionRow: FilterSectionRow - val filterName : String = this.filterType.name + val filterName : String = this.queryType.name - private val filterType : FilterType + private val queryType : QueryType get() { return when (this) { - is Cash -> FilterType.CASH - is Tournament -> FilterType.TOURNAMENT -/* is Today -> FilterType. + is Cash -> QueryType.CASH + is Tournament -> QueryType.TOURNAMENT + is Blind -> QueryType.BLINDS + is From -> QueryType.STARTED_FROM_DATE + is To -> QueryType.ENDED_TO_DATE + is Month -> QueryType.MONTH + is Day -> QueryType.DAY_OF_WEEK + is Year -> QueryType.YEAR + is Live -> QueryType.LIVE + is Online -> QueryType.ONLINE + is Weekday -> QueryType.WEEK_DAY + is Weekend-> QueryType.WEEK_END + +/* is Today -> QueryType. is Yesterday -> R.string.yesterday is TodayAndYesterday -> R.string.yesterday_and_today is CurrentWeek -> R.string.current_week is CurrentMonth -> R.string.current_month is CurrentYear -> R.string.current_year - is From -> R.string.from - is To -> R.string.to - is Live -> R.string.live - is Online -> R.string.online - is Weekday -> R.string.week_days - is Weekend-> R.string.weekend - is Year-> R.string.year - is Month-> R.string.month_of_the_year - is Day -> R.string.day_of_the_week is PastDays -> R.string.period_in_days is Limit -> R.string.limit - is TableSize -> R.string.table_size - is Bankroll -> R.string.bankroll - */ - is Game -> FilterType.GAME - /* - is Location -> R.string.location - is TournamentName -> R.string.tournament_name - is TournamentFeature -> R.string.tournament_feature */ - else -> throw FilterValueMapException("no filter type for filter element") //TODO create exception + is TableSize -> QueryType.TABLE_SIZE + is Game -> QueryType.GAME + is Bankroll -> QueryType.BANKROLL + is Location -> QueryType.LOCATION + is TournamentName -> QueryType.TOURNAMENT_NAME + is AnyTournamentFeature -> QueryType.ANY_TOURNAMENT_FEATURES + is AllTournamentFeature -> QueryType.ALL_TOURNAMENT_FEATURES + is ResultMoreThan -> QueryType.MORE_THAN_NET_RESULT + is ResultLessThan -> QueryType.LESS_THAN_NET_RESULT + else -> throw FilterValueMapException("no filter type for $this") //TODO create exception } } - fun contains(filterComponents: List) : Boolean { + fun contains(filterElements: List) : Boolean { return when (this) { - is Game -> filterComponents.any { - it.ids?.contains(this.game.id) ?: false + is DataFilterElementRow -> filterElements.any { + it.ids.contains(this.id) } - is From -> TODO() - is To -> TODO() - is Year -> TODO() - is Month -> TODO() - is Day -> TODO() - is PastDays -> TODO() - is Limit -> TODO() - is TableSize -> TODO() - is Bankroll -> TODO() - is Location -> TODO() - is TournamentName -> TODO() - is TournamentFeature -> TODO() else -> return true } } @@ -122,17 +125,16 @@ sealed class FilterElementRow : RowRepresentable { is PastDays -> R.string.period_in_days is Limit -> R.string.limit is TableSize -> R.string.table_size - is Bankroll -> R.string.bankroll - is Game -> R.string.game - is Location -> R.string.location - is TournamentName -> R.string.tournament_name - is TournamentFeature -> R.string.tournament_feature + is Blind -> TODO() + is ResultMoreThan -> TODO() + is ResultLessThan -> TODO() + else -> null } } override fun getDisplayName(): String { return when (this) { - is Game -> game.getDisplayName() + is DataFilterElementRow -> this.name else -> return super.getDisplayName() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index 1696bdac..084c5676 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -24,6 +24,8 @@ enum class FilterSectionRow(override val resId: Int?): RowRepresentable { BLINDS(net.pokeranalytics.android.R.string.blinds), CASH_RE_BUY_COUNT(net.pokeranalytics.android.R.string.cash_game), TOURNAMENT_TYPE(net.pokeranalytics.android.R.string.tournament_types), + TOURNAMENT_NAME(net.pokeranalytics.android.R.string.tournament_name), + TOURNAMENT_FEATURE(net.pokeranalytics.android.R.string.tournament_feature), COMPLETION_PERCENTAGE(net.pokeranalytics.android.R.string.tournament_completion_percentage_interval), PLACE(net.pokeranalytics.android.R.string.final_position), PLAYERS_COUNT(net.pokeranalytics.android.R.string.players_count), @@ -67,7 +69,8 @@ enum class FilterSectionRow(override val resId: Int?): RowRepresentable { } tableSizes } - + TOURNAMENT_NAME -> arrayListOf() + TOURNAMENT_FEATURE -> arrayListOf() DYNAMIC_DATE -> arrayListOf( Today, Yesterday, @@ -175,7 +178,7 @@ enum class FilterSectionRow(override val resId: Int?): RowRepresentable { val games = realm.copyFromRealm(LiveData.GAME.items(realm) as RealmResults) rows.addAll(games) } - LIMIT_TYPE -> rows.addAll(Limit.values()) + LIMIT_TYPE -> rows.addAll(Limit.numericValues()) TABLE_SIZE -> { val sessions = realm.where().sort("tableSize").distinct("tableSize").findAll() for (session in sessions) {