1846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar/* 2846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * Copyright (C) 2017 The Android Open Source Project 3846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * 4846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * you may not use this file except in compliance with the License. 6846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * You may obtain a copy of the License at 7846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * 8846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * 10846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * See the License for the specific language governing permissions and 14846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * limitations under the License. 15846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar */ 16846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 17bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room.solver.query.result 18846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 19bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.annotation.NonNull 20bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.L 21bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.LifecyclesTypeNames 22bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.N 23bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.RoomTypeNames 24bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.RoomTypeNames.INVALIDATION_OBSERVER 25bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.typeName 26bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.solver.CodeGenScope 27846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport com.squareup.javapoet.FieldSpec 28846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport com.squareup.javapoet.MethodSpec 292ec1285ef79d4849069efe95cfbac2307d291a47Yuichi Arakiimport com.squareup.javapoet.ParameterSpec 30846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport com.squareup.javapoet.ParameterizedTypeName 31846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport com.squareup.javapoet.TypeName 32846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport com.squareup.javapoet.TypeSpec 33846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport javax.lang.model.element.Modifier 34846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyarimport javax.lang.model.type.TypeMirror 35846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 36846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar/** 37846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar * Converts the query into a LiveData and returns it. No query is run until necessary. 38846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar */ 392c56b466fc39da8bc5cb82dc494e534768e65eabshepshapardclass LiveDataQueryResultBinder(val typeArg: TypeMirror, val tableNames: Set<String>, 40846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar adapter: QueryResultAdapter?) 413c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar : BaseObservableQueryResultBinder(adapter) { 42092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar @Suppress("JoinDeclarationAndAssignment") 436f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas override fun convertAndReturn( 446f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas roomSQLiteQueryVar: String, 45de23b91b2c982ef5c93349b16415654ae3fe5ac9Yigit Boyar canReleaseQuery: Boolean, 466f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas dbField: FieldSpec, 476f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas inTransaction: Boolean, 486f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas scope: CodeGenScope 496f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas ) { 50846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar val typeName = typeArg.typeName() 51846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 52846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar val liveDataImpl = TypeSpec.anonymousClassBuilder("").apply { 53846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar superclass(ParameterizedTypeName.get(LifecyclesTypeNames.COMPUTABLE_LIVE_DATA, 54846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar typeName)) 55b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar val observerField = FieldSpec.builder(RoomTypeNames.INVALIDATION_OBSERVER, 56b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar scope.getTmpVar("_observer"), Modifier.PRIVATE).build() 57b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar addField(observerField) 58846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addMethod(createComputeMethod( 59b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar observerField = observerField, 60846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar typeName = typeName, 61b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar roomSQLiteQueryVar = roomSQLiteQueryVar, 62846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar dbField = dbField, 6325b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar inTransaction = inTransaction, 64846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar scope = scope 65846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar )) 66de23b91b2c982ef5c93349b16415654ae3fe5ac9Yigit Boyar if (canReleaseQuery) { 67de23b91b2c982ef5c93349b16415654ae3fe5ac9Yigit Boyar addMethod(createFinalizeMethod(roomSQLiteQueryVar)) 68de23b91b2c982ef5c93349b16415654ae3fe5ac9Yigit Boyar } 69846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar }.build() 70846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar scope.builder().apply { 71f59164365fb6de9f148b597af5a6e19b3b7c8c2eYigit Boyar addStatement("return $L.getLiveData()", liveDataImpl) 72846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar } 73846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar } 74846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 756f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas private fun createComputeMethod( 766f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas roomSQLiteQueryVar: String, 776f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas typeName: TypeName, 786f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas observerField: FieldSpec, 796f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas dbField: FieldSpec, 806f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas inTransaction: Boolean, 816f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas scope: CodeGenScope 826f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas ): MethodSpec { 83846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar return MethodSpec.methodBuilder("compute").apply { 84846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addAnnotation(Override::class.java) 85846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addModifiers(Modifier.PROTECTED) 86846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar returns(typeName) 87846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 88b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar beginControlFlow("if ($N == null)", observerField).apply { 89b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar addStatement("$N = $L", observerField, createAnonymousObserver()) 90b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar addStatement("$N.getInvalidationTracker().addWeakObserver($N)", 91b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar dbField, observerField) 92846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar } 93846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar endControlFlow() 94846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 9525b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar createRunQueryAndReturnStatements(builder = this, 9625b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar roomSQLiteQueryVar = roomSQLiteQueryVar, 9725b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar dbField = dbField, 9825b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar inTransaction = inTransaction, 9925b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar scope = scope) 100846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar }.build() 101846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar } 102846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 103846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar private fun createAnonymousObserver(): TypeSpec { 104092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar val tableNamesList = tableNames.joinToString(",") { "\"$it\"" } 105846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar return TypeSpec.anonymousClassBuilder(tableNamesList).apply { 106846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar superclass(INVALIDATION_OBSERVER) 107846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addMethod(MethodSpec.methodBuilder("onInvalidated").apply { 108846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar returns(TypeName.VOID) 109846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addAnnotation(Override::class.java) 1102ec1285ef79d4849069efe95cfbac2307d291a47Yuichi Araki addParameter(ParameterSpec.builder( 1112ec1285ef79d4849069efe95cfbac2307d291a47Yuichi Araki ParameterizedTypeName.get(Set::class.java, String::class.java), "tables") 1122ec1285ef79d4849069efe95cfbac2307d291a47Yuichi Araki .addAnnotation(NonNull::class.java) 1132ec1285ef79d4849069efe95cfbac2307d291a47Yuichi Araki .build()) 114846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addModifiers(Modifier.PUBLIC) 115846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar addStatement("invalidate()") 116846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar }.build()) 117846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar }.build() 118846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar } 119846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar} 120