Merge "Migrate DaoWriter raw query codegen to XPoet" into androidx-main
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
index 4b78ec0..a88bb07 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/javapoet_ext.kt
@@ -22,6 +22,8 @@
import androidx.room.compiler.codegen.XCodeBlock
import androidx.room.compiler.codegen.XFunSpec
import androidx.room.compiler.codegen.XFunSpec.Builder.Companion.apply
+import androidx.room.compiler.codegen.XMemberName.Companion.companionMember
+import androidx.room.compiler.codegen.XMemberName.Companion.packageMember
import androidx.room.compiler.codegen.XTypeName
import androidx.room.compiler.codegen.XTypeSpec
import androidx.room.compiler.codegen.asClassName
@@ -57,8 +59,7 @@
ClassName.get("$SQLITE_PACKAGE.db", "SupportSQLiteOpenHelper.Callback")
val SQLITE_OPEN_HELPER_CONFIG: ClassName =
ClassName.get("$SQLITE_PACKAGE.db", "SupportSQLiteOpenHelper.Configuration")
- val QUERY: ClassName =
- ClassName.get("$SQLITE_PACKAGE.db", "SupportSQLiteQuery")
+ val QUERY = XClassName.get("$SQLITE_PACKAGE.db", "SupportSQLiteQuery")
}
object RoomTypeNames {
@@ -254,6 +255,13 @@
val FLOW = ClassName.get("kotlinx.coroutines.flow", "Flow")
}
+object RoomMemberNames {
+ val CURSOR_UTIL_GET_COLUMN_INDEX =
+ RoomTypeNames.CURSOR_UTIL.packageMember("getColumnIndex")
+ val ROOM_SQL_QUERY_ACQUIRE =
+ RoomTypeNames.ROOM_SQL_QUERY.companionMember("acquire", isJvmStatic = true)
+}
+
val DEFERRED_TYPES = listOf(
LifecyclesTypeNames.LIVE_DATA,
LifecyclesTypeNames.COMPUTABLE_LIVE_DATA,
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
index 5e293f9..9cc2640 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/ProcessorErrors.kt
@@ -723,7 +723,7 @@
}
val RAW_QUERY_STRING_PARAMETER_REMOVED = "RawQuery does not allow passing a string anymore." +
- " Please use ${SupportDbTypeNames.QUERY}."
+ " Please use ${SupportDbTypeNames.QUERY.canonicalName}."
val MISSING_COPY_ANNOTATIONS = "Annotated property getter is missing " +
"@AutoValue.CopyAnnotations."
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/RawQueryMethodProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/RawQueryMethodProcessor.kt
index 7e59ed5..ec08a3d 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/RawQueryMethodProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/RawQueryMethodProcessor.kt
@@ -18,13 +18,13 @@
import androidx.room.RawQuery
import androidx.room.Transaction
-import androidx.room.ext.SupportDbTypeNames
-import androidx.room.ext.isEntityElement
-import androidx.room.parser.SqlParser
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XNullability
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XVariableElement
+import androidx.room.ext.SupportDbTypeNames
+import androidx.room.ext.isEntityElement
+import androidx.room.parser.SqlParser
import androidx.room.processor.ProcessorErrors.RAW_QUERY_STRING_PARAMETER_REMOVED
import androidx.room.vo.MapInfo
import androidx.room.vo.RawQueryMethod
@@ -155,7 +155,7 @@
if (isSupportSql) {
return RawQueryMethod.RuntimeQueryParameter(
paramName = extractParams[0].name,
- type = supportQueryType.typeName
+ typeName = supportQueryType.asTypeName()
)
}
val stringType = processingEnv.requireType("java.lang.String")
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/RawQueryMethod.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/RawQueryMethod.kt
index 95948ef..3aafee5 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/RawQueryMethod.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/RawQueryMethod.kt
@@ -16,14 +16,14 @@
package androidx.room.vo
-import androidx.room.ext.CommonTypeNames
-import androidx.room.ext.SupportDbTypeNames
+import androidx.room.compiler.codegen.XTypeName
+import androidx.room.compiler.codegen.asClassName
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.isKotlinUnit
+import androidx.room.ext.SupportDbTypeNames
import androidx.room.ext.isNotVoid
import androidx.room.solver.query.result.QueryResultBinder
-import com.squareup.javapoet.TypeName
/**
* A class that holds information about a method annotated with RawQuery.
@@ -44,9 +44,9 @@
data class RuntimeQueryParameter(
val paramName: String,
- val type: TypeName
+ val typeName: XTypeName
) {
- fun isString() = CommonTypeNames.STRING == type
- fun isSupportQuery() = SupportDbTypeNames.QUERY == type
+ fun isString() = String::class.asClassName() == typeName
+ fun isSupportQuery() = SupportDbTypeNames.QUERY == typeName
}
}
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt b/room/room-compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
index 392f5a3..fd6511f 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
@@ -35,11 +35,11 @@
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.isVoid
import androidx.room.ext.L
-import androidx.room.ext.N
+import androidx.room.ext.RoomMemberNames
+import androidx.room.ext.RoomTypeNames
import androidx.room.ext.RoomTypeNames.DELETE_OR_UPDATE_ADAPTER
import androidx.room.ext.RoomTypeNames.INSERTION_ADAPTER
import androidx.room.ext.RoomTypeNames.ROOM_DB
-import androidx.room.ext.RoomTypeNames.ROOM_SQL_QUERY
import androidx.room.ext.RoomTypeNames.SHARED_SQLITE_STMT
import androidx.room.ext.RoomTypeNames.UPSERTION_ADAPTER
import androidx.room.ext.SupportDbTypeNames
@@ -355,42 +355,36 @@
val roomSQLiteQueryVar: String
val queryParam = method.runtimeQueryParam
val shouldReleaseQuery: Boolean
- when {
- queryParam?.isString() == true -> {
- roomSQLiteQueryVar = scope.getTmpVar("_statement")
- shouldReleaseQuery = true
- addStatement(
- "$T $L = $T.acquire($L, 0)",
- ROOM_SQL_QUERY.toJavaPoet(),
- roomSQLiteQueryVar,
- ROOM_SQL_QUERY.toJavaPoet(),
+ if (queryParam?.isSupportQuery() == true) {
+ roomSQLiteQueryVar = queryParam.paramName
+ shouldReleaseQuery = false
+ } else if (queryParam?.isString() == true) {
+ roomSQLiteQueryVar = scope.getTmpVar("_statement")
+ shouldReleaseQuery = true
+ addLocalVariable(
+ name = roomSQLiteQueryVar,
+ typeName = RoomTypeNames.ROOM_SQL_QUERY,
+ assignExpr = XCodeBlock.of(
+ codeLanguage,
+ "%M(%L, 0)",
+ RoomMemberNames.ROOM_SQL_QUERY_ACQUIRE,
queryParam.paramName
- )
- }
- queryParam?.isSupportQuery() == true -> {
- shouldReleaseQuery = false
- roomSQLiteQueryVar = scope.getTmpVar("_internalQuery")
- // move it to a final variable so that the generated code can use it inside
- // callback blocks in java 7
- addStatement(
- "final $T $L = $N",
- queryParam.type,
- roomSQLiteQueryVar,
- queryParam.paramName
- )
- }
- else -> {
- // try to generate compiling code. we would've already reported this error
- roomSQLiteQueryVar = scope.getTmpVar("_statement")
- shouldReleaseQuery = false
- addStatement(
- "$T $L = $T.acquire($L, 0)",
- ROOM_SQL_QUERY.toJavaPoet(),
- roomSQLiteQueryVar,
- ROOM_SQL_QUERY.toJavaPoet(),
+ ),
+ )
+ } else {
+ // try to generate compiling code. we would've already reported this error
+ roomSQLiteQueryVar = scope.getTmpVar("_statement")
+ shouldReleaseQuery = false
+ addLocalVariable(
+ name = roomSQLiteQueryVar,
+ typeName = RoomTypeNames.ROOM_SQL_QUERY,
+ assignExpr = XCodeBlock.of(
+ codeLanguage,
+ "%M(%S, 0)",
+ RoomMemberNames.ROOM_SQL_QUERY_ACQUIRE,
"missing query parameter"
- )
- }
+ ),
+ )
}
if (method.returnsValue) {
// don't generate code because it will create 1 more error. The original error is
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt b/room/room-compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
index 941e011..399a208 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
@@ -21,7 +21,7 @@
import androidx.room.compiler.codegen.XTypeName
import androidx.room.compiler.codegen.toJavaPoet
import androidx.room.ext.AndroidTypeNames.CURSOR
-import androidx.room.ext.RoomTypeNames.CURSOR_UTIL
+import androidx.room.ext.RoomMemberNames
import androidx.room.ext.capitalize
import androidx.room.ext.stripNonJava
import androidx.room.solver.CodeGenScope
@@ -62,8 +62,8 @@
typeName = XTypeName.PRIMITIVE_INT,
assignExpr = XCodeBlock.of(
language,
- "%T.getColumnIndex(%N, %S)",
- CURSOR_UTIL,
+ "%M(%N, %S)",
+ RoomMemberNames.CURSOR_UTIL_GET_COLUMN_INDEX,
cursorParamName,
it.columnName
)
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/writer/QueryWriter.kt b/room/room-compiler/src/main/kotlin/androidx/room/writer/QueryWriter.kt
index c2a8745..ec8031f 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/writer/QueryWriter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/writer/QueryWriter.kt
@@ -18,10 +18,10 @@
import androidx.room.compiler.codegen.XCodeBlock
import androidx.room.compiler.codegen.XCodeBlock.Builder.Companion.addLocalVal
-import androidx.room.compiler.codegen.XMemberName.Companion.companionMember
import androidx.room.compiler.codegen.XMemberName.Companion.packageMember
import androidx.room.compiler.codegen.XTypeName
import androidx.room.compiler.codegen.asClassName
+import androidx.room.ext.RoomMemberNames
import androidx.room.ext.RoomTypeNames
import androidx.room.parser.ParsedQuery
import androidx.room.parser.Section
@@ -131,8 +131,7 @@
assignExpr = XCodeBlock.of(
language,
"%M(%L, %L)",
- RoomTypeNames.ROOM_SQL_QUERY
- .companionMember("acquire", isJvmStatic = true),
+ RoomMemberNames.ROOM_SQL_QUERY_ACQUIRE,
outSqlQueryName,
argCount
)
@@ -152,8 +151,7 @@
assignExpr = XCodeBlock.of(
language,
"%M(%L, %L)",
- RoomTypeNames.ROOM_SQL_QUERY
- .companionMember("acquire", isJvmStatic = true),
+ RoomMemberNames.ROOM_SQL_QUERY_ACQUIRE,
outSqlQueryName,
knownQueryArgsCount
)
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
index 78d8ba7..7942588 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
@@ -57,7 +57,7 @@
`is`(
RawQueryMethod.RuntimeQueryParameter(
paramName = "query",
- type = SupportDbTypeNames.QUERY
+ typeName = SupportDbTypeNames.QUERY
)
)
)
@@ -96,7 +96,7 @@
`is`(
RawQueryMethod.RuntimeQueryParameter(
paramName = "query",
- type = SupportDbTypeNames.QUERY
+ typeName = SupportDbTypeNames.QUERY
)
)
)
@@ -119,7 +119,7 @@
`is`(
RawQueryMethod.RuntimeQueryParameter(
paramName = "query",
- type = SupportDbTypeNames.QUERY
+ typeName = SupportDbTypeNames.QUERY
)
)
)
@@ -197,7 +197,7 @@
`is`(
RawQueryMethod.RuntimeQueryParameter(
paramName = "query",
- type = SupportDbTypeNames.QUERY
+ typeName = SupportDbTypeNames.QUERY
)
)
)
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/KotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/KotlinCodeGenTest.kt
index ac68dd6..a17ced3 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/KotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/KotlinCodeGenTest.kt
@@ -649,6 +649,34 @@
)
}
+ @Test
+ fun rawQuery() {
+ val testName = object {}.javaClass.enclosingMethod!!.name
+ val src = Source.kotlin(
+ "MyDao.kt",
+ """
+ import androidx.room.*
+ import androidx.sqlite.db.SupportSQLiteQuery
+
+ @Dao
+ interface MyDao {
+ @RawQuery(observedEntities = [MyEntity::class])
+ fun getEntity(sql: SupportSQLiteQuery): MyEntity
+ }
+
+ @Entity
+ data class MyEntity(
+ @PrimaryKey
+ val pk: Long,
+ )
+ """.trimIndent()
+ )
+ runTest(
+ sources = listOf(src, databaseSrc),
+ expectedFilePath = getTestGoldenPath(testName)
+ )
+ }
+
private fun getTestGoldenPath(testName: String): String {
return "kotlinCodeGen/$testName.kt"
}
diff --git a/room/room-compiler/src/test/test-data/daoWriter/output/javac/ComplexDao.java b/room/room-compiler/src/test/test-data/daoWriter/output/javac/ComplexDao.java
index 9868e0a..7b158a9 100644
--- a/room/room-compiler/src/test/test-data/daoWriter/output/javac/ComplexDao.java
+++ b/room/room-compiler/src/test/test-data/daoWriter/output/javac/ComplexDao.java
@@ -665,9 +665,8 @@
@Override
public User getUserViaRawQuery(final SupportSQLiteQuery rawQuery) {
- final SupportSQLiteQuery _internalQuery = rawQuery;
__db.assertNotSuspendingTransaction();
- final Cursor _cursor = DBUtil.query(__db, _internalQuery, false, null);
+ final Cursor _cursor = DBUtil.query(__db, rawQuery, false, null);
try {
final User _result;
if (_cursor.moveToFirst()) {
diff --git a/room/room-compiler/src/test/test-data/daoWriter/output/ksp/ComplexDao.java b/room/room-compiler/src/test/test-data/daoWriter/output/ksp/ComplexDao.java
index 74d05fa..8a7f450 100644
--- a/room/room-compiler/src/test/test-data/daoWriter/output/ksp/ComplexDao.java
+++ b/room/room-compiler/src/test/test-data/daoWriter/output/ksp/ComplexDao.java
@@ -585,9 +585,8 @@
@Override
public User getUserViaRawQuery(final SupportSQLiteQuery rawQuery) {
- final SupportSQLiteQuery _internalQuery = rawQuery;
__db.assertNotSuspendingTransaction();
- final Cursor _cursor = DBUtil.query(__db, _internalQuery, false, null);
+ final Cursor _cursor = DBUtil.query(__db, rawQuery, false, null);
try {
final User _result;
if (_cursor.moveToFirst()) {
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/rawQuery.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/rawQuery.kt
new file mode 100644
index 0000000..688d74c
--- /dev/null
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/rawQuery.kt
@@ -0,0 +1,56 @@
+import android.database.Cursor
+import androidx.room.RoomDatabase
+import androidx.room.util.getColumnIndex
+import androidx.room.util.query
+import androidx.sqlite.db.SupportSQLiteQuery
+import java.lang.Class
+import javax.`annotation`.processing.Generated
+import kotlin.Int
+import kotlin.Long
+import kotlin.Suppress
+import kotlin.collections.List
+import kotlin.jvm.JvmStatic
+
+@Generated(value = ["androidx.room.RoomProcessor"])
+@Suppress(names = ["unchecked", "deprecation"])
+public class MyDao_Impl : MyDao {
+ private val __db: RoomDatabase
+
+ public constructor(__db: RoomDatabase) {
+ this.__db = __db
+ }
+
+ public override fun getEntity(sql: SupportSQLiteQuery): MyEntity {
+ __db.assertNotSuspendingTransaction()
+ val _cursor: Cursor = query(__db, sql, false, null)
+ try {
+ val _result: MyEntity
+ if (_cursor.moveToFirst()) {
+ _result = __entityCursorConverter_MyEntity(_cursor)
+ } else {
+ error("Cursor was empty, but expected a single item.")
+ }
+ return _result
+ } finally {
+ _cursor.close()
+ }
+ }
+
+ private fun __entityCursorConverter_MyEntity(cursor: Cursor): MyEntity {
+ val _entity: MyEntity
+ val _cursorIndexOfPk: Int = getColumnIndex(cursor, "pk")
+ val _tmpPk: Long
+ if (_cursorIndexOfPk == -1) {
+ _tmpPk = 0
+ } else {
+ _tmpPk = cursor.getLong(_cursorIndexOfPk)
+ }
+ _entity = MyEntity(_tmpPk)
+ return _entity
+ }
+
+ public companion object {
+ @JvmStatic
+ public fun getRequiredConverters(): List<Class<*>> = emptyList()
+ }
+}
\ No newline at end of file