| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * 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 |
| * |
| * http://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 androidx.room.solver.query.result |
| |
| import androidx.room.ext.AndroidTypeNames |
| import androidx.room.ext.CommonTypeNames |
| import androidx.room.ext.L |
| import androidx.room.ext.N |
| import androidx.room.ext.RoomTypeNames |
| import androidx.room.solver.CodeGenScope |
| import com.squareup.javapoet.FieldSpec |
| import com.squareup.javapoet.MethodSpec |
| import com.squareup.javapoet.ParameterSpec |
| import com.squareup.javapoet.ParameterizedTypeName |
| import com.squareup.javapoet.TypeName |
| import com.squareup.javapoet.TypeSpec |
| import javax.lang.model.element.Modifier |
| |
| class PositionalDataSourceQueryResultBinder( |
| val listAdapter: ListQueryResultAdapter?, |
| val tableNames: Set<String> |
| ) : QueryResultBinder(listAdapter) { |
| val itemTypeName: TypeName = listAdapter?.rowAdapter?.out?.typeName ?: TypeName.OBJECT |
| val typeName: ParameterizedTypeName = ParameterizedTypeName.get( |
| RoomTypeNames.LIMIT_OFFSET_DATA_SOURCE, itemTypeName) |
| override fun convertAndReturn( |
| roomSQLiteQueryVar: String, |
| canReleaseQuery: Boolean, |
| dbField: FieldSpec, |
| inTransaction: Boolean, |
| scope: CodeGenScope |
| ) { |
| // first comma for table names comes from the string since it might be empty in which case |
| // we don't need a comma. If list is empty, this prevents generating bad code (it is still |
| // an error to have empty list but that is already reported while item is processed) |
| val tableNamesList = tableNames.joinToString("") { ", \"$it\"" } |
| val spec = TypeSpec.anonymousClassBuilder("$N, $L, $L $L", |
| dbField, roomSQLiteQueryVar, inTransaction, tableNamesList).apply { |
| superclass(typeName) |
| addMethod(createConvertRowsMethod(scope)) |
| }.build() |
| scope.builder().apply { |
| addStatement("return $L", spec) |
| } |
| } |
| |
| private fun createConvertRowsMethod(scope: CodeGenScope): MethodSpec = |
| MethodSpec.methodBuilder("convertRows").apply { |
| addAnnotation(Override::class.java) |
| addModifiers(Modifier.PROTECTED) |
| returns(ParameterizedTypeName.get(CommonTypeNames.LIST, itemTypeName)) |
| val cursorParam = ParameterSpec.builder(AndroidTypeNames.CURSOR, "cursor") |
| .build() |
| addParameter(cursorParam) |
| val resultVar = scope.getTmpVar("_res") |
| val rowsScope = scope.fork() |
| listAdapter?.convert(resultVar, cursorParam.name, rowsScope) |
| addCode(rowsScope.builder().build()) |
| addStatement("return $L", resultVar) |
| }.build() |
| } |