diff --git a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/SQLiteDatabase.kt b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/SQLiteDatabase.kt index 0447b25b53..03ed4b52e9 100644 --- a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/SQLiteDatabase.kt +++ b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/SQLiteDatabase.kt @@ -29,6 +29,7 @@ import com.bloomberg.selekt.SQLiteAutoVacuumMode import com.bloomberg.selekt.SQLiteJournalMode import com.bloomberg.selekt.SQLiteTraceEventMode import com.bloomberg.selekt.SQLiteTransactionMode +import com.bloomberg.selekt.annotations.DelicateApi import com.bloomberg.selekt.pools.Priority import org.intellij.lang.annotations.Language import java.io.Closeable @@ -180,9 +181,11 @@ class SQLiteDatabase private constructor( * * @see SQLite's transaction */ - internal fun beginExclusiveTransaction() = database.beginExclusiveTransaction() + @DelicateApi + fun beginExclusiveTransaction() = database.beginExclusiveTransaction() - internal fun beginExclusiveTransactionWithListener(listener: SQLTransactionListener) = + @DelicateApi + fun beginExclusiveTransactionWithListener(listener: SQLTransactionListener) = database.beginExclusiveTransactionWithListener(listener) /** @@ -196,9 +199,11 @@ class SQLiteDatabase private constructor( * * @see SQLite's transaction */ - internal fun beginImmediateTransaction() = database.beginImmediateTransaction() + @DelicateApi + fun beginImmediateTransaction() = database.beginImmediateTransaction() - internal fun beginImmediateTransactionWithListener(listener: SQLTransactionListener) = + @DelicateApi + fun beginImmediateTransactionWithListener(listener: SQLTransactionListener) = database.beginImmediateTransactionWithListener(listener) fun compileStatement(@Language("RoomSql") sql: String) = database.compileStatement(sql) @@ -209,7 +214,8 @@ class SQLiteDatabase private constructor( whereClause.orEmpty(), whereArgs.orEmpty()) - internal fun endTransaction() = database.endTransaction() + @DelicateApi + fun endTransaction() = database.endTransaction() fun exec(@Language("RoomSql") sql: String) = database.exec(sql) @@ -333,7 +339,8 @@ class SQLiteDatabase private constructor( database.pragma(PAGE_SIZE, 1 shl value) } - internal fun setTransactionSuccessful() = database.setTransactionSuccessful() + @DelicateApi + fun setTransactionSuccessful() = database.setTransactionSuccessful() /** * @since 0.7.4 diff --git a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabase.kt b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabase.kt index 091b86cc0c..139067a2ce 100644 --- a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabase.kt +++ b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabase.kt @@ -26,9 +26,11 @@ import androidx.sqlite.db.SupportSQLiteQuery import com.bloomberg.selekt.SQLTransactionListener import com.bloomberg.selekt.SQLiteJournalMode import com.bloomberg.selekt.android.SQLiteDatabase +import com.bloomberg.selekt.annotations.DelicateApi import org.intellij.lang.annotations.Language import java.util.Locale +@DelicateApi internal fun SQLiteDatabase.asSupportSQLiteDatabase(): SupportSQLiteDatabase = SupportSQLiteDatabase(this) @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @@ -50,6 +52,7 @@ private class WrappedSQLiteTransactionListener( override fun hashCode() = listener.hashCode() } +@DelicateApi private class SupportSQLiteDatabase constructor( private val database: SQLiteDatabase ) : SupportSQLiteDatabase { diff --git a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteOpenHelper.kt b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteOpenHelper.kt index a7024200e3..7994e77704 100644 --- a/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteOpenHelper.kt +++ b/AndroidLib/src/main/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteOpenHelper.kt @@ -23,6 +23,7 @@ import com.bloomberg.selekt.android.ISQLiteOpenHelper import com.bloomberg.selekt.android.SQLiteDatabase import com.bloomberg.selekt.android.SQLiteOpenHelper import com.bloomberg.selekt.android.SQLiteOpenParams +import com.bloomberg.selekt.annotations.DelicateApi fun createSupportSQLiteOpenHelperFactory( journalMode: SQLiteJournalMode, @@ -41,7 +42,7 @@ private class SupportSQLiteOpenHelperFactory( ).asSupportSQLiteOpenHelper() } -internal fun ISQLiteOpenHelper.asSupportSQLiteOpenHelper() = object : SupportSQLiteOpenHelper { +internal fun ISQLiteOpenHelper.asSupportSQLiteOpenHelper() = @DelicateApi object : SupportSQLiteOpenHelper { private val database: SupportSQLiteDatabase by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { this@asSupportSQLiteOpenHelper.writableDatabase.asSupportSQLiteDatabase() } @@ -73,7 +74,7 @@ internal fun SupportSQLiteOpenHelper.Configuration.asSelektConfiguration( name = requireNotNull(name) { "Encryption of in-memory SupportDatabases is not supported." } ) -internal fun SupportSQLiteOpenHelper.Callback.asSelektCallback() = object : ISQLiteOpenHelper.Callback { +internal fun SupportSQLiteOpenHelper.Callback.asSelektCallback() = @DelicateApi object : ISQLiteOpenHelper.Callback { override fun onConfigure(database: SQLiteDatabase) = this@asSelektCallback.onConfigure( database.asSupportSQLiteDatabase()) diff --git a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseTransactionTest.kt b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseTransactionTest.kt index c9dc5b3e3a..f29b10ffef 100644 --- a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseTransactionTest.kt +++ b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseTransactionTest.kt @@ -22,6 +22,7 @@ import com.bloomberg.selekt.SQLTransactionListener import com.bloomberg.selekt.commons.deleteDatabase import com.bloomberg.selekt.SQLiteJournalMode import com.bloomberg.selekt.SQLiteTransactionMode +import com.bloomberg.selekt.annotations.DelicateApi import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.doThrow @@ -71,6 +72,7 @@ internal data class TransactionTestInputs( } @RunWith(Parameterized::class) +@DelicateApi internal class SQLiteDatabaseTransactionTest(inputs: TransactionTestInputs) { @get:Rule val timeoutRule = DisableOnDebug(Timeout(10L, TimeUnit.SECONDS)) diff --git a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseWALTest.kt b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseWALTest.kt index 6ec0844f1e..11f4f02245 100644 --- a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseWALTest.kt +++ b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/SQLiteDatabaseWALTest.kt @@ -23,7 +23,7 @@ import com.bloomberg.selekt.Experimental import com.bloomberg.selekt.SQLTransactionListener import com.bloomberg.selekt.SQLiteAutoVacuumMode import com.bloomberg.selekt.SQLiteJournalMode -import com.bloomberg.selekt.commons.deleteDatabase +import com.bloomberg.selekt.annotations.DelicateApi import org.mockito.kotlin.doThrow import org.mockito.kotlin.mock import org.mockito.kotlin.times @@ -42,6 +42,7 @@ import kotlin.test.assertSame import kotlin.test.assertTrue @RunWith(RobolectricTestRunner::class) +@DelicateApi internal class SQLiteDatabaseWALTest { private val file = File.createTempFile("test-sql-database-wal", ".db").also { it.deleteOnExit() } diff --git a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabaseTest.kt b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabaseTest.kt index 321c156011..5da360fafb 100644 --- a/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabaseTest.kt +++ b/AndroidLib/src/test/kotlin/com/bloomberg/selekt/android/support/SupportSQLiteDatabaseTest.kt @@ -24,6 +24,7 @@ import androidx.sqlite.db.SupportSQLiteQuery import com.bloomberg.selekt.SQLiteJournalMode import com.bloomberg.selekt.android.ConflictAlgorithm import com.bloomberg.selekt.android.SQLiteDatabase +import com.bloomberg.selekt.annotations.DelicateApi import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn @@ -56,11 +57,12 @@ import kotlin.test.assertTrue private const val CONFLICT_REPLACE = 5 @RunWith(RobolectricTestRunner::class) +@DelicateApi internal class SupportSQLiteDatabaseTest { @get:Rule val timeoutRule = DisableOnDebug(Timeout(10L, TimeUnit.SECONDS)) - @Mock lateinit var database: com.bloomberg.selekt.android.SQLiteDatabase + @Mock lateinit var database: SQLiteDatabase private lateinit var supportDatabase: SupportSQLiteDatabase @Before diff --git a/ApiLib/src/main/kotlin/com/bloomberg/selekt/annotations/DelicateApi.kt b/ApiLib/src/main/kotlin/com/bloomberg/selekt/annotations/DelicateApi.kt new file mode 100644 index 0000000000..d4a0638e6d --- /dev/null +++ b/ApiLib/src/main/kotlin/com/bloomberg/selekt/annotations/DelicateApi.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2021 Bloomberg Finance L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bloomberg.selekt.annotations + +/** + * Marks Selekt methods that are to be used with caution. Their use must be subject to careful review. Misuse may result + * in leaks or hard to diagnose bugs. + */ +@MustBeDocumented +@Retention(value = AnnotationRetention.BINARY) +@RequiresOptIn( + level = RequiresOptIn.Level.WARNING, + message = "This is a delicate API whose use requires care." +) +annotation class DelicateApi