1 /* <lambda>null2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.room.writer 18 19 import androidx.room.ext.L 20 import androidx.room.ext.RoomTypeNames 21 import androidx.room.ext.S 22 import androidx.room.ext.SupportDbTypeNames 23 import androidx.room.solver.CodeGenScope 24 import androidx.room.vo.Entity 25 import androidx.room.vo.FieldWithIndex 26 import com.squareup.javapoet.ClassName 27 import com.squareup.javapoet.MethodSpec 28 import com.squareup.javapoet.ParameterSpec 29 import com.squareup.javapoet.ParameterizedTypeName 30 import com.squareup.javapoet.TypeName 31 import com.squareup.javapoet.TypeSpec 32 import javax.lang.model.element.Modifier.PUBLIC 33 34 class EntityUpdateAdapterWriter(val entity: Entity, val onConflict: String) { 35 fun createAnonymous(classWriter: ClassWriter, dbParam: String): TypeSpec { 36 @Suppress("RemoveSingleExpressionStringTemplate") 37 return TypeSpec.anonymousClassBuilder("$L", dbParam).apply { 38 superclass(ParameterizedTypeName.get(RoomTypeNames.DELETE_OR_UPDATE_ADAPTER, 39 entity.typeName) 40 ) 41 addMethod(MethodSpec.methodBuilder("createQuery").apply { 42 addAnnotation(Override::class.java) 43 returns(ClassName.get("java.lang", "String")) 44 addModifiers(PUBLIC) 45 val query = "UPDATE OR $onConflict `${entity.tableName}` SET " + 46 entity.fields.joinToString(",") { field -> 47 "`${field.columnName}` = ?" 48 } + " WHERE " + entity.primaryKey.fields.joinToString(" AND ") { 49 "`${it.columnName}` = ?" 50 } 51 addStatement("return $S", query) 52 }.build()) 53 addMethod(MethodSpec.methodBuilder("bind").apply { 54 val bindScope = CodeGenScope(classWriter) 55 addAnnotation(Override::class.java) 56 val stmtParam = "stmt" 57 addParameter(ParameterSpec.builder(SupportDbTypeNames.SQLITE_STMT, 58 stmtParam).build()) 59 val valueParam = "value" 60 addParameter(ParameterSpec.builder(entity.typeName, valueParam).build()) 61 returns(TypeName.VOID) 62 addModifiers(PUBLIC) 63 val mappedField = FieldWithIndex.byOrder(entity.fields) 64 FieldReadWriteWriter.bindToStatement( 65 ownerVar = valueParam, 66 stmtParamVar = stmtParam, 67 fieldsWithIndices = mappedField, 68 scope = bindScope 69 ) 70 val pkeyStart = entity.fields.size 71 val mappedPrimaryKeys = entity.primaryKey.fields.mapIndexed { index, field -> 72 FieldWithIndex(field = field, 73 indexVar = "${pkeyStart + index + 1}", 74 alwaysExists = true) 75 } 76 FieldReadWriteWriter.bindToStatement( 77 ownerVar = valueParam, 78 stmtParamVar = stmtParam, 79 fieldsWithIndices = mappedPrimaryKeys, 80 scope = bindScope 81 ) 82 addCode(bindScope.builder().build()) 83 }.build()) 84 }.build() 85 } 86 } 87