From cfde324f58ceccee14a18650df95e6c9a7d12f7f Mon Sep 17 00:00:00 2001 From: JaniruTEC <52893617+JaniruTEC@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:57:39 +0200 Subject: [PATCH] Enforced single call convention for parts of "MappingSupportSQLiteQuery" Also added workaround for tests *This commit is related to issue #529 [1]* [1] https://github.com/cryptomator/android/issues/529 --- .../MappingSupportSQLiteDatabase.kt | 5 ++--- .../MappingSupportSQLiteDatabaseTest.kt | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/data/src/main/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabase.kt b/data/src/main/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabase.kt index 64e761149..cc6e46a8a 100644 --- a/data/src/main/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabase.kt +++ b/data/src/main/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabase.kt @@ -10,7 +10,6 @@ import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.SupportSQLiteProgram import androidx.sqlite.db.SupportSQLiteQuery import androidx.sqlite.db.SupportSQLiteStatement -import timber.log.Timber internal class MappingSupportSQLiteDatabase( private val delegate: SupportSQLiteDatabase, @@ -166,8 +165,8 @@ internal class MappingSupportSQLiteDatabase( ) : SupportSQLiteQuery by delegateQuery { private val _sql = map(delegateQuery.sql) - private val sqlDelegate = OneOffDelegate { Timber.tag("MappingSupportSQLiteQuery").e("SQL queried twice") } - private val bindToDelegate = OneOffDelegate { Timber.tag("MappingSupportSQLiteQuery").e("bindTo called twice") } + private val sqlDelegate = OneOffDelegate { throw IllegalStateException("SQL queried twice") } + private val bindToDelegate = OneOffDelegate { throw IllegalStateException("bindTo called twice") } override val sql: String get() = sqlDelegate.call { _sql } diff --git a/data/src/test/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabaseTest.kt b/data/src/test/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabaseTest.kt index e963ce72e..3c4548729 100644 --- a/data/src/test/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabaseTest.kt +++ b/data/src/test/java/org/cryptomator/data/db/sqlmapping/MappingSupportSQLiteDatabaseTest.kt @@ -118,6 +118,7 @@ class MappingSupportSQLiteDatabaseTest { identityMapping.query(SimpleSQLiteQuery("SELECT `col` FROM `id_test`")) commentMapping.query(SimpleSQLiteQuery("SELECT `col` FROM `comment_test`")) + val supportSQLiteQueryProperties = newCachedSupportSQLiteQueryProperties() verify(delegateMock).query( anyPseudoEquals(SimpleSQLiteQuery("SELECT `col` FROM `id_test`"), supportSQLiteQueryProperties) ) @@ -134,6 +135,7 @@ class MappingSupportSQLiteDatabaseTest { identityMapping.query(SimpleSQLiteQuery("SELECT `col` FROM `id_test` WHERE `col` = ?", arrayOf("test1"))) commentMapping.query(SimpleSQLiteQuery("SELECT `col` FROM `comment_test` WHERE `col` = ?", arrayOf("test2"))) + val supportSQLiteQueryProperties = newCachedSupportSQLiteQueryProperties() verify(delegateMock).query( anyPseudoEquals(SimpleSQLiteQuery("SELECT `col` FROM `id_test` WHERE `col` = ?", arrayOf("test1")), supportSQLiteQueryProperties) ) @@ -151,6 +153,7 @@ class MappingSupportSQLiteDatabaseTest { identityMapping.query(queries.idCall, signals.idCall) commentMapping.query(queries.commentCall, signals.commentCall) + val supportSQLiteQueryProperties = newCachedSupportSQLiteQueryProperties() verify(delegateMock).query( anyPseudoEquals(queries.idExpected, supportSQLiteQueryProperties), anyPseudoEqualsUnlessNull(signals.idExpected, setOf>(CancellationSignal::isCanceled)) @@ -352,6 +355,15 @@ private class PseudoEqualsMatcher( private typealias ValueExtractor = (T) -> Any? +private data class CacheEntry(val value: Any?) //Allows correct handling of nulls + +private fun ValueExtractor.asCached(): ValueExtractor { + val cache = mutableMapOf() + return { + cache.computeIfAbsent(it) { key -> CacheEntry(this@asCached(key)) }.value + } +} + private inline fun OngoingStubbing.thenDo(crossinline action: (invocation: InvocationOnMock) -> Unit): OngoingStubbing = thenAnswer { action(it) } private class NullHandlingMatcher( @@ -367,10 +379,13 @@ private class NullHandlingMatcher( } } -private val supportSQLiteQueryProperties: Set> - get() = setOf(SupportSQLiteQuery::sql, SupportSQLiteQuery::argCount, { query: SupportSQLiteQuery -> +private fun newCachedSupportSQLiteQueryProperties(): Set> = setOf( + SupportSQLiteQuery::sql.asCached(), + SupportSQLiteQuery::argCount, + { query: SupportSQLiteQuery -> CachingSupportSQLiteProgram().also { query.bindTo(it) }.bindings - }) + }.asCached() +) private class CachingSupportSQLiteProgram : SupportSQLiteProgram {