ProcessorErrors.kt revision c24f4573b0732b6cc0569fc3bbe3867be6f4880c
119b41105359a52aeb80070dec40247241231f05dYigit Boyar/* 219b41105359a52aeb80070dec40247241231f05dYigit Boyar * Copyright (C) 2016 The Android Open Source Project 319b41105359a52aeb80070dec40247241231f05dYigit Boyar * 419b41105359a52aeb80070dec40247241231f05dYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 519b41105359a52aeb80070dec40247241231f05dYigit Boyar * you may not use this file except in compliance with the License. 619b41105359a52aeb80070dec40247241231f05dYigit Boyar * You may obtain a copy of the License at 719b41105359a52aeb80070dec40247241231f05dYigit Boyar * 819b41105359a52aeb80070dec40247241231f05dYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 919b41105359a52aeb80070dec40247241231f05dYigit Boyar * 1019b41105359a52aeb80070dec40247241231f05dYigit Boyar * Unless required by applicable law or agreed to in writing, software 1119b41105359a52aeb80070dec40247241231f05dYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1219b41105359a52aeb80070dec40247241231f05dYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1319b41105359a52aeb80070dec40247241231f05dYigit Boyar * See the License for the specific language governing permissions and 1419b41105359a52aeb80070dec40247241231f05dYigit Boyar * limitations under the License. 1519b41105359a52aeb80070dec40247241231f05dYigit Boyar */ 1619b41105359a52aeb80070dec40247241231f05dYigit Boyar 1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.persistence.room.processor 1864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar 1964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Delete 2064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Insert 2164db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Query 2264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Update 2364db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.RoomTypeNames 2464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.parser.SQLTypeAffinity 2564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.vo.CustomTypeConverter 2664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.vo.Field 2788865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyarimport com.squareup.javapoet.TypeName 2819b41105359a52aeb80070dec40247241231f05dYigit Boyar 2919b41105359a52aeb80070dec40247241231f05dYigit Boyarobject ProcessorErrors { 302c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar private fun String.trim(): String { 31b78956d6a56230a8c2f86b6e749d35e880e4d6efshepshapard return this.trimIndent().replace("\n", " ") 322c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar } 3319b41105359a52aeb80070dec40247241231f05dYigit Boyar val MISSING_QUERY_ANNOTATION = "Query methods must be annotated with ${Query::class.java}" 344f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val MISSING_INSERT_ANNOTATION = "Insertion methods must be annotated with ${Insert::class.java}" 35958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar val MISSING_DELETE_ANNOTATION = "Deletion methods must be annotated with ${Delete::class.java}" 3674b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar val MISSING_UPDATE_ANNOTATION = "Update methods must be annotated with ${Update::class.java}" 37333b4b5e49c48adf7fb928d445b6f7f276b54a02Yigit Boyar val INVALID_ON_CONFLICT_VALUE = "On conflict value must be one of @OnConflictStrategy values." 384f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val INVALID_INSERTION_METHOD_RETURN_TYPE = "Methods annotated with @Insert can return either" + 39dd6aaec8254abfee2dd82a5f2c59282f8eeee9eeYuichi Araki " void, long, Long, long[], Long[] or List<Long>." 4025b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar val TRANSACTION_REFERENCE_DOCS = "https://developer.android.com/reference/android/arch/" + 4125b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar "persistence/room/Transaction.html" 42f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar 436f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun insertionMethodReturnTypeMismatch(definedReturn: TypeName, 446f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas expectedReturnTypes: List<TypeName>): String { 45f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar return "Method returns $definedReturn but it should return one of the following: `" + 46f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar expectedReturnTypes.joinToString(", ") + "`. If you want to return the list of" + 47f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar " row ids from the query, your insertion method can receive only 1 parameter." 48f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar } 49f5f2cf6b9ed63915448e81551e4b7bb72a26030eYigit Boyar 504f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val ABSTRACT_METHOD_IN_DAO_MISSING_ANY_ANNOTATION = "Abstract method in DAO must be annotated" + 514f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar " with ${Query::class.java} AND ${Insert::class.java}" 52c24f4573b0732b6cc0569fc3bbe3867be6f4880cYigit Boyar val INVALID_ANNOTATION_COUNT_IN_DAO_METHOD = "An abstract DAO method must be" + 53c24f4573b0732b6cc0569fc3bbe3867be6f4880cYigit Boyar " annotated with one and only one of the following annotations: " + 54c24f4573b0732b6cc0569fc3bbe3867be6f4880cYigit Boyar DaoProcessor.PROCESSED_ANNOTATIONS.joinToString(",") { 55958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar it.java.simpleName 56958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar } 5719b41105359a52aeb80070dec40247241231f05dYigit Boyar val CANNOT_RESOLVE_RETURN_TYPE = "Cannot resolve return type for %s" 584f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val CANNOT_USE_UNBOUND_GENERICS_IN_QUERY_METHODS = "Cannot use unbound generics in query" + 594f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar " methods. It must be bound to a type through base Dao class." 604f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val CANNOT_USE_UNBOUND_GENERICS_IN_INSERTION_METHODS = "Cannot use unbound generics in" + 614f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar " insertion methods. It must be bound to a type through base Dao class." 62de33ce4068e2678c03fa6fd62f4770be89f79adcYigit Boyar val CANNOT_USE_UNBOUND_GENERICS_IN_ENTITY_FIELDS = "Cannot use unbound fields in entities." 630f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar val CANNOT_USE_UNBOUND_GENERICS_IN_DAO_CLASSES = "Cannot use unbound generics in Dao classes." + 640f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar " If you are trying to create a base DAO, create a normal class, extend it with type" + 650f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar " params then mark the subclass with @Dao." 661600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar val CANNOT_FIND_GETTER_FOR_FIELD = "Cannot find getter for field." 671600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar val CANNOT_FIND_SETTER_FOR_FIELD = "Cannot find setter for field." 68e6325fbeaa2e6759496ea2ca9a4d3d958df690d7Yigit Boyar val MISSING_PRIMARY_KEY = "An entity must have at least 1 field annotated with @PrimaryKey" 692c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar val AUTO_INCREMENTED_PRIMARY_KEY_IS_NOT_INT = "If a primary key is annotated with" + 702c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar " autoGenerate, its type must be int, Integer, long or Long." 714d4bae3f216e55f824d7d7fbfe2f8861906ee3e2Yigit Boyar val AUTO_INCREMENT_EMBEDDED_HAS_MULTIPLE_FIELDS = "When @PrimaryKey annotation is used on a" + 724d4bae3f216e55f824d7d7fbfe2f8861906ee3e2Yigit Boyar " field annotated with @Embedded, the embedded class should have only 1 field." 732c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar 742c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun multiplePrimaryKeyAnnotations(primaryKeys: List<String>): String { 752c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar return """ 762c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar You cannot have multiple primary keys defined in an Entity. If you 772c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar want to declare a composite primary key, you should use @Entity#primaryKeys and 782c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar not use @PrimaryKey. Defined Primary Keys: 792c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar ${primaryKeys.joinToString(", ")}""".trim() 802c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar } 812c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar 822c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun primaryKeyColumnDoesNotExist(columnName: String, allColumns: List<String>): String { 832c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar return "$columnName referenced in the primary key does not exists in the Entity." + 842c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar " Available column names:${allColumns.joinToString(", ")}" 852c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar } 862c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar 870f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar val DAO_MUST_BE_AN_ABSTRACT_CLASS_OR_AN_INTERFACE = "Dao class must be an abstract class or" + 880f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar " an interface" 898bad027c789d3fb3da8e68fa0154f2a24ccc2865Yigit Boyar val DATABASE_MUST_BE_ANNOTATED_WITH_DATABASE = "Database must be annotated with @Database" 908bad027c789d3fb3da8e68fa0154f2a24ccc2865Yigit Boyar val DAO_MUST_BE_ANNOTATED_WITH_DAO = "Dao class must be annotated with @Dao" 9117caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki 9217caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki fun daoMustHaveMatchingConstructor(daoName: String, dbName: String): String { 9317caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki return """ 9417caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki $daoName needs to have either an empty constructor or a constructor that takes 9517caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki $dbName as its only parameter. 9617caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki """.trim() 9717caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki } 9817caba59e1fd850fe1381d7311d23afc4e07cdfbYuichi Araki 998bad027c789d3fb3da8e68fa0154f2a24ccc2865Yigit Boyar val ENTITY_MUST_BE_ANNOTATED_WITH_ENTITY = "Entity class must be annotated with @Entity" 1008bad027c789d3fb3da8e68fa0154f2a24ccc2865Yigit Boyar val DATABASE_ANNOTATION_MUST_HAVE_LIST_OF_ENTITIES = "@Database annotation must specify list" + 1018bad027c789d3fb3da8e68fa0154f2a24ccc2865Yigit Boyar " of entities" 1020fc66ddc60bdc71d5466bb1db1a218e5a3d9c1fcYigit Boyar val COLUMN_NAME_CANNOT_BE_EMPTY = "Column name cannot be blank. If you don't want to set it" + 103275e7088223c097c1a2df718455bede42bc9efedYigit Boyar ", just remove the @ColumnInfo annotation or use @ColumnInfo.INHERIT_FIELD_NAME." 1040fc66ddc60bdc71d5466bb1db1a218e5a3d9c1fcYigit Boyar 1050fc66ddc60bdc71d5466bb1db1a218e5a3d9c1fcYigit Boyar val ENTITY_TABLE_NAME_CANNOT_BE_EMPTY = "Entity table name cannot be blank. If you don't want" + 1060fc66ddc60bdc71d5466bb1db1a218e5a3d9c1fcYigit Boyar " to set it, just remove the tableName property." 1070f77cff2005ccc6263b9902b3ea56fe01161ba51Yigit Boyar 108275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val CANNOT_BIND_QUERY_PARAMETER_INTO_STMT = "Query method parameters should either be a" + 109275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " type that can be converted into a database column or a List / Array that contains" + 110275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " such type. You can consider adding a Type Adapter for this." 111250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar 1124f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val QUERY_PARAMETERS_CANNOT_START_WITH_UNDERSCORE = "Query/Insert method parameters cannot " + 1134f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar "start with underscore (_)." 1148e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar 115efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar val CANNOT_FIND_QUERY_RESULT_ADAPTER = "Not sure how to convert a Cursor to this method's " + 116efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar "return type" 117efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar 1184f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar val INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT = "Method annotated with" + 1194f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar " @Insert but does not have any parameters to insert." 1204f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar 12174b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar val DELETION_MISSING_PARAMS = "Method annotated with" + 122958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar " @Delete but does not have any parameters to delete." 123958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar 12474b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar val UPDATE_MISSING_PARAMS = "Method annotated with" + 12574b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar " @Update but does not have any parameters to update." 12674b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar 127b3c4d9308e4fd66beca3a7824a5db749ce2aace1Yuichi Araki val TRANSACTION_METHOD_MODIFIERS = "Method annotated with @Transaction must not be " + 12825b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar "private, final, or abstract. It can be abstract only if the method is also" + 12925b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar " annotated with @Query." 13025b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar 13125b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar val TRANSACTION_MISSING_ON_RELATION = "The return value includes a Pojo with a @Relation." + 13225b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar " It is usually desired to annotate this method with @Transaction to avoid" + 13325b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar " possibility of inconsistent results between the Pojo and its relations. See " + 13425b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar TRANSACTION_REFERENCE_DOCS + " for details." 135b3c4d9308e4fd66beca3a7824a5db749ce2aace1Yuichi Araki 136958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar val CANNOT_FIND_ENTITY_FOR_SHORTCUT_QUERY_PARAMETER = "Type of the parameter must be a class " + 137958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar "annotated with @Entity or a collection/array of it." 1384f0db7db556b473393dfc31bba5ea67def574877Yigit Boyar 139291985054e698c918df1c735d1042b63b9e97219Yigit Boyar val DB_MUST_EXTEND_ROOM_DB = "Classes annotated with @Database should extend " + 140291985054e698c918df1c735d1042b63b9e97219Yigit Boyar RoomTypeNames.ROOM_DB 141291985054e698c918df1c735d1042b63b9e97219Yigit Boyar 142846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar val LIVE_DATA_QUERY_WITHOUT_SELECT = "LiveData return type can only be used with SELECT" + 143846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar " queries." 144846dfcf52e22de6d912f8ece05ff939c2c9bd154Yigit Boyar 1458df194b42f73f85f29760e8abe11d879ec49b286Yigit Boyar val OBSERVABLE_QUERY_NOTHING_TO_OBSERVE = "Observable query return type (LiveData, Flowable" + 1468df194b42f73f85f29760e8abe11d879ec49b286Yigit Boyar " etc) can only be used with SELECT queries that directly or indirectly (via" + 1478df194b42f73f85f29760e8abe11d879ec49b286Yigit Boyar " @Relation, for example) access at least one table." 1482c56b466fc39da8bc5cb82dc494e534768e65eabshepshapard 1491a74519922de68e007027d56aae9370ee21f31f9shepshapard val RECURSIVE_REFERENCE_DETECTED = "Recursive referencing through @Embedded and/or @Relation " + 1501a74519922de68e007027d56aae9370ee21f31f9shepshapard "detected: %s" 1511a74519922de68e007027d56aae9370ee21f31f9shepshapard 152250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar private val TOO_MANY_MATCHING_GETTERS = "Ambiguous getter for %s. All of the following " + 153250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar "match: %s. You can @Ignore the ones that you don't want to match." 154efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar 155efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar fun tooManyMatchingGetters(field: Field, methodNames: List<String>): String { 1561600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar return TOO_MANY_MATCHING_GETTERS.format(field, methodNames.joinToString(", ")) 1571600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar } 1581600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar 159250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar private val TOO_MANY_MATCHING_SETTERS = "Ambiguous setter for %s. All of the following " + 160250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar "match: %s. You can @Ignore the ones that you don't want to match." 161efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar 162efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar fun tooManyMatchingSetter(field: Field, methodNames: List<String>): String { 1631600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar return TOO_MANY_MATCHING_SETTERS.format(field, methodNames.joinToString(", ")) 1641600cc11df868b62b6ae3995d94a3ec0b86559adYigit Boyar } 165250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar 166275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val CANNOT_FIND_COLUMN_TYPE_ADAPTER = "Cannot figure out how to save this field into" + 167275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " database. You can consider adding a type converter for it." 168275e7088223c097c1a2df718455bede42bc9efedYigit Boyar 169275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val CANNOT_FIND_STMT_BINDER = "Cannot figure out how to bind this field into a statement." 170275e7088223c097c1a2df718455bede42bc9efedYigit Boyar 171275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val CANNOT_FIND_CURSOR_READER = "Cannot figure out how to read this field from a cursor." 172275e7088223c097c1a2df718455bede42bc9efedYigit Boyar 173250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar private val MISSING_PARAMETER_FOR_BIND = "Each bind variable in the query must have a" + 174250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar " matching method parameter. Cannot find method parameters for %s." 175efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar 176250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar fun missingParameterForBindVariable(bindVarName: List<String>): String { 177250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar return MISSING_PARAMETER_FOR_BIND.format(bindVarName.joinToString(", ")) 178250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar } 179250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar 180250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar private val UNUSED_QUERY_METHOD_PARAMETER = "Unused parameter%s: %s" 181250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar fun unusedQueryMethodParameter(unusedParams: List<String>): String { 182250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar return UNUSED_QUERY_METHOD_PARAMETER.format( 183250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar if (unusedParams.size > 1) "s" else "", 184250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar unusedParams.joinToString(",")) 185250a3e6dc5d50c533575b7d276730b89eecc7c19Yigit Boyar } 186af2292b2f53204a3004f53201f51908d70d8090eYigit Boyar 187af2292b2f53204a3004f53201f51908d70d8090eYigit Boyar private val DUPLICATE_TABLES = "Table name \"%s\" is used by multiple entities: %s" 18813a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar fun duplicateTableNames(tableName: String, entityNames: List<String>): String { 189af2292b2f53204a3004f53201f51908d70d8090eYigit Boyar return DUPLICATE_TABLES.format(tableName, entityNames.joinToString(", ")) 190af2292b2f53204a3004f53201f51908d70d8090eYigit Boyar } 191958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar 192958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar val DELETION_METHODS_MUST_RETURN_VOID_OR_INT = "Deletion methods must either return void or" + 193958df7dd95c2cecf93cacef6998a4d7e8d39b7efYigit Boyar " return int (the number of deleted rows)." 19488865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar 19574b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar val UPDATE_METHODS_MUST_RETURN_VOID_OR_INT = "Update methods must either return void or" + 19674b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar " return int (the number of updated rows)." 19774b28faea4bcc4b7fab113a61a066d22dfae7258Yigit Boyar 19888865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar val DAO_METHOD_CONFLICTS_WITH_OTHERS = "Dao method has conflicts." 19988865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar 20013a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar fun duplicateDao(dao: TypeName, methodNames: List<String>): String { 20188865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar return """ 202275e7088223c097c1a2df718455bede42bc9efedYigit Boyar All of these functions [${methodNames.joinToString(", ")}] return the same DAO 203275e7088223c097c1a2df718455bede42bc9efedYigit Boyar class [$dao]. 20413a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar A database can use a DAO only once so you should remove ${methodNames.size - 1} of 20513a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar these conflicting DAO methods. If you are implementing any of these to fulfill an 20613a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar interface, don't make it abstract, instead, implement the code that calls the 20713a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar other one. 2082c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """.trim() 20913a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar } 210afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar 211afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar fun pojoMissingNonNull(pojoTypeName: TypeName, missingPojoFields: List<String>, 2126f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas allQueryColumns: List<String>): String { 213afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar return """ 214afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar The columns returned by the query does not have the fields 215afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar [${missingPojoFields.joinToString(",")}] in $pojoTypeName even though they are 216afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar annotated as non-null or primitive. 217afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar Columns returned by the query: [${allQueryColumns.joinToString(",")}] 218afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar """.trim() 219afbbe0af09599e93010b776bf91f54e82f23e7a3Yigit Boyar } 22013a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar 22113a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar fun cursorPojoMismatch(pojoTypeName: TypeName, 22213a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar unusedColumns: List<String>, allColumns: List<String>, 22313a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar unusedFields: List<Field>, allFields: List<Field>): String { 2242c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar val unusedColumnsWarning = if (unusedColumns.isNotEmpty()) { 2252c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """ 226275e7088223c097c1a2df718455bede42bc9efedYigit Boyar The query returns some columns [${unusedColumns.joinToString(", ")}] which are not 227275e7088223c097c1a2df718455bede42bc9efedYigit Boyar use by $pojoTypeName. You can use @ColumnInfo annotation on the fields to specify 22813a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar the mapping. 2292c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """.trim() 23013a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar } else { 23113a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar "" 23213a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar } 2332c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar val unusedFieldsWarning = if (unusedFields.isNotEmpty()) { 2342c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """ 23513a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar $pojoTypeName has some fields 236275e7088223c097c1a2df718455bede42bc9efedYigit Boyar [${unusedFields.joinToString(", ") { it.columnName }}] which are not returned by the 23713a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar query. If they are not supposed to be read from the result, you can mark them with 23813a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar @Ignore annotation. 2392c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """.trim() 24013a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar } else { 24113a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar "" 24213a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar } 24313a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar return """ 24413a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar $unusedColumnsWarning 24513a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar $unusedFieldsWarning 24613a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar You can suppress this warning by annotating the method with 24713a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). 24813a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar Columns returned by the query: ${allColumns.joinToString(", ")}. 24913a2048db98b1cc2dbd1692b73b794527975a446Yigit Boyar Fields in $pojoTypeName: ${allFields.joinToString(", ") { it.columnName }}. 2502c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar """.trim() 25188865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar } 25288865f77c35657a2bc545a718ca16a648fc8b62eYigit Boyar 253275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_UNBOUND_GENERIC = "Cannot use unbound generics in Type Converters." 254275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_BAD_RETURN_TYPE = "Invalid return type for a type converter." 255275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_MUST_RECEIVE_1_PARAM = "Type converters must receive 1 parameter." 256275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_EMPTY_CLASS = "Class is referenced as a converter but it does not have any" + 257275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " converter methods." 258275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_MISSING_NOARG_CONSTRUCTOR = "Classes that are used as TypeConverters must" + 259275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " have no-argument public constructors." 260275e7088223c097c1a2df718455bede42bc9efedYigit Boyar val TYPE_CONVERTER_MUST_BE_PUBLIC = "Type converters must be public." 261275e7088223c097c1a2df718455bede42bc9efedYigit Boyar 2622c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun duplicateTypeConverters(converters: List<CustomTypeConverter>): String { 263275e7088223c097c1a2df718455bede42bc9efedYigit Boyar return "Multiple methods define the same conversion. Conflicts with these:" + 264275e7088223c097c1a2df718455bede42bc9efedYigit Boyar " ${converters.joinToString(", ") { it.toString() }}" 265275e7088223c097c1a2df718455bede42bc9efedYigit Boyar } 26696cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar 26796cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar // TODO must print field paths. 26896cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar val POJO_FIELD_HAS_DUPLICATE_COLUMN_NAME = "Field has non-unique column name." 26996cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar 2702c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun pojoDuplicateFieldNames(columnName: String, fieldPaths: List<String>): String { 27196cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar return "Multiple fields have the same columnName: $columnName." + 27296cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar " Field names: ${fieldPaths.joinToString(", ")}." 27396cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar } 27496cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar 2754d4bae3f216e55f824d7d7fbfe2f8861906ee3e2Yigit Boyar fun embeddedPrimaryKeyIsDropped(entityQName: String, fieldName: String): String { 27696cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar return "Primary key constraint on $fieldName is ignored when being merged into " + 27796cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar entityQName 27896cc740203eaa752fc85ca7ca722a8de550ae88cYigit Boyar } 279dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 280dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar val INDEX_COLUMNS_CANNOT_BE_EMPTY = "List of columns in an index cannot be empty" 281dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 2822c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun indexColumnDoesNotExist(columnName: String, allColumns: List<String>): String { 283dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "$columnName referenced in the index does not exists in the Entity." + 284dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " Available column names:${allColumns.joinToString(", ")}" 285dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 286dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 2872c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun duplicateIndexInEntity(indexName: String): String { 288dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "There are multiple indices with name $indexName. This happen if you've declared" + 289dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " the same index multiple times or different indices have the same name. See" + 290dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " @Index documentation for details." 291dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 292dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 2932c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun duplicateIndexInDatabase(indexName: String, indexPaths: List<String>): String { 294dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "There are multiple indices with name $indexName. You should rename " + 295dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar "${indexPaths.size - 1} of these to avoid the conflict:" + 296dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar "${indexPaths.joinToString(", ")}." 297dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 298dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 2994d4bae3f216e55f824d7d7fbfe2f8861906ee3e2Yigit Boyar fun droppedEmbeddedFieldIndex(fieldPath: String, grandParent: String): String { 300dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "The index will be dropped when being merged into $grandParent" + 301dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar "($fieldPath). You must re-declare it in $grandParent if you want to index this" + 302dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " field in $grandParent." 303dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 304dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 3056f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun droppedEmbeddedIndex(entityName: String, fieldPath: String, grandParent: String): String { 306dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "Indices defined in $entityName will be dropped when it is merged into" + 307dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " $grandParent ($fieldPath). You can re-declare them in $grandParent." 308dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 309dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 3102c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun droppedSuperClassIndex(childEntity: String, superEntity: String): String { 311dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "Indices defined in $superEntity will NOT be re-used in $childEntity. If you want" + 312dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " to inherit them, you must re-declare them in $childEntity." + 313dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " Alternatively, you can set inheritSuperIndices to true in the @Entity annotation." 314dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 315dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar 3162c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar fun droppedSuperClassFieldIndex(fieldName: String, childEntity: String, 3172c6462f129bf43965ed8b054b026f6a28fe6fd8fYigit Boyar superEntity: String): String { 318dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar return "Index defined on field `$fieldName` in $superEntity will NOT be re-used in" + 319dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " $childEntity. " + 320dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar "If you want to inherit it, you must re-declare it in $childEntity." + 321dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar " Alternatively, you can set inheritSuperIndices to true in the @Entity annotation." 322dc18ce63fe07921b1080e48d3e597e2b5240d17aYigit Boyar } 323092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 324092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar val RELATION_NOT_COLLECTION = "Fields annotated with @Relation must be a List or Set." 325092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 3266f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun relationCannotFindEntityField(entityName: String, columnName: String, 3276f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas availableColumns: List<String>): String { 328f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar return "Cannot find the child entity column `$columnName` in $entityName." + 329f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar " Options: ${availableColumns.joinToString(", ")}" 330092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar } 331092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 3326f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun relationCannotFindParentEntityField(entityName: String, columnName: String, 3336f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas availableColumns: List<String>): String { 334f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar return "Cannot find the parent entity column `$columnName` in $entityName." + 335f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar " Options: ${availableColumns.joinToString(", ")}" 336092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar } 337092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 338092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar val RELATION_IN_ENTITY = "Entities cannot have relations." 339092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 340092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar val CANNOT_FIND_TYPE = "Cannot find type." 341092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 342f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar fun relationAffinityMismatch(parentColumn: String, childColumn: String, 3436f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas parentAffinity: SQLTypeAffinity?, 3446f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas childAffinity: SQLTypeAffinity?): String { 345092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar return """ 346f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar The affinity of parent column ($parentColumn : $parentAffinity) does not match the type 347f385ca501bbfd3ccaf6b412f8f09c64d9ee742f2Yigit Boyar affinity of the child column ($childColumn : $childAffinity). 348092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar """.trim() 349092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar } 350092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 351092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar val CANNOT_USE_MORE_THAN_ONE_POJO_FIELD_ANNOTATION = "A field can be annotated with only" + 352092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar " one of the following:" + PojoProcessor.PROCESSED_ANNOTATIONS.joinToString(",") { 353092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar it.java.simpleName 354092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar } 355092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar 3566f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun relationBadProject(entityQName: String, missingColumnNames: List<String>, 3576f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas availableColumnNames: List<String>): String { 358092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar return """ 359092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar $entityQName does not have the following columns: ${missingColumnNames.joinToString(",")}. 360092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar Available columns are: ${availableColumnNames.joinToString(",")} 361092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar """.trim() 362092164e5501d0a254001225acd9dca42e5fa57e9Yigit Boyar } 363a64756a18111a7312b3fa03b76d13381a8907176Yigit Boyar 364a64756a18111a7312b3fa03b76d13381a8907176Yigit Boyar val MISSING_SCHEMA_EXPORT_DIRECTORY = "Schema export directory is not provided to the" + 365a64756a18111a7312b3fa03b76d13381a8907176Yigit Boyar " annotation processor so we cannot export the schema. You can either provide" + 366a64756a18111a7312b3fa03b76d13381a8907176Yigit Boyar " `room.schemaLocation` annotation processor argument OR set exportSchema to false." 367875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 368875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar val INVALID_FOREIGN_KEY_ACTION = "Invalid foreign key action. It must be one of the constants" + 369875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar " defined in ForeignKey.Action" 370875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 3716f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyNotAnEntity(className: String): String { 372875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 373875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar Classes referenced in Foreign Key annotations must be @Entity classes. $className is not 374875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar an entity 375875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar """.trim() 376875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 377875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 378875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar val FOREIGN_KEY_CANNOT_FIND_PARENT = "Cannot find parent entity class." 379875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 380875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar fun foreignKeyChildColumnDoesNotExist(columnName: String, allColumns: List<String>): String { 381875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return "($columnName) referenced in the foreign key does not exists in the Entity." + 382875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar " Available column names:${allColumns.joinToString(", ")}" 383875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 384875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 3856f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyParentColumnDoesNotExist(parentEntity: String, 386875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar missingColumn: String, 3876f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas allColumns: List<String>): String { 388875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return "($missingColumn) does not exist in $parentEntity. Available columns are" + 389875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar " ${allColumns.joinToString(",")}" 390875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 391875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 392875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar val FOREIGN_KEY_EMPTY_CHILD_COLUMN_LIST = "Must specify at least 1 column name for the child" 393875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 394875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar val FOREIGN_KEY_EMPTY_PARENT_COLUMN_LIST = "Must specify at least 1 column name for the parent" 395875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 3966f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyColumnNumberMismatch( 3976f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas childColumns: List<String>, parentColumns: List<String>): String { 398875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 399875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar Number of child columns in foreign key must match number of parent columns. 400875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar Child reference has ${childColumns.joinToString(",")} and parent reference has 401875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar ${parentColumns.joinToString(",")} 402875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar """.trim() 403875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 404875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 4056f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyMissingParentEntityInDatabase(parentTable: String, childEntity: String): String { 406875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 407875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar $parentTable table referenced in the foreign keys of $childEntity does not exist in 408875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar the database. Maybe you forgot to add the referenced entity in the entities list of 409875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar the @Database annotation?""".trim() 410875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 411875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 4126f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyMissingIndexInParent(parentEntity: String, parentColumns: List<String>, 4136f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas childEntity: String, childColumns: List<String>): String { 414875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 415875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar $childEntity has a foreign key (${childColumns.joinToString(",")}) that references 416875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar $parentEntity (${parentColumns.joinToString(",")}) but $parentEntity does not have 417875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar a unique index on those columns nor the columns are its primary key. 418875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar SQLite requires having a unique constraint on referenced parent columns so you must 419875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar add a unique index to $parentEntity that has 420875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar (${parentColumns.joinToString(",")}) column(s). 421875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar """.trim() 422875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 423875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 4246f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyMissingIndexInChildColumns(childColumns: List<String>): String { 425875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 426875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar (${childColumns.joinToString(",")}) column(s) reference a foreign key but 427875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar they are not part of an index. This may trigger full table scans whenever parent 428875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar table is modified so you are highly advised to create an index that covers these 429875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar columns. 430875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar """.trim() 431875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 432875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar 4336f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun foreignKeyMissingIndexInChildColumn(childColumn: String): String { 434875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar return """ 435875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar $childColumn column references a foreign key but it is not part of an index. This 436875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar may trigger full table scans whenever parent table is modified so you are highly 437875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar advised to create an index that covers this column. 438875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar """.trim() 439875203d39f95be2367dec3ee70be4e2169b4e0f0Yigit Boyar } 44008ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar 4416f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun shortcutEntityIsNotInDatabase(database: String, dao: String, entity: String): String { 44208ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar return """ 44308ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar $dao is part of $database but this entity is not in the database. Maybe you forgot 44408ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar to add $entity to the entities section of the @Database? 44508ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar """.trim() 44608ddf77b7cc743f85b23e83de8b22b69fe4bf6d2Yigit Boyar } 4473c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar val MISSING_ROOM_RXJAVA2_ARTIFACT = "To use RxJava2 features, you must add `rxjava2`" + 44864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar " artifact from Room as a dependency. android.arch.persistence.room:rxjava2:<version>" 449f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar 4506f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun ambigiousConstructor( 4516f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas pojo: String, paramName: String, matchingFields: List<String>): String { 452f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar return """ 453f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar Ambiguous constructor. The parameter ($paramName) in $pojo matches multiple fields: 454f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar [${matchingFields.joinToString(",")}]. If you don't want to use this constructor, 455f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar you can annotate it with @Ignore. If you want Room to use this constructor, you can 456f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar rename the parameters to exactly match the field name to fix the ambiguity. 457f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar """.trim() 458f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar } 459f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar 460f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar val MISSING_POJO_CONSTRUCTOR = """ 461f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar Entities and Pojos must have a usable public constructor. You can have an empty 462f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar constructor or a constructor whose parameters match the fields (by name and type). 463f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar """.trim() 464f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar 465f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar val TOO_MANY_POJO_CONSTRUCTORS = """ 466f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar Room cannot pick a constructor since multiple constructors are suitable. Try to annotate 467f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar unwanted constructors with @Ignore. 468f8c3624579d5761a2d34a7199932492d267f5f85Yigit Boyar """.trim() 469abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar 470b9ea73472fb85e1a7074734824ad11c3f64cad83Yigit Boyar val TOO_MANY_POJO_CONSTRUCTORS_CHOOSING_NO_ARG = """ 471b9ea73472fb85e1a7074734824ad11c3f64cad83Yigit Boyar There are multiple good constructors and Room will pick the no-arg constructor. 472b9ea73472fb85e1a7074734824ad11c3f64cad83Yigit Boyar You can use the @Ignore annotation to eliminate unwanted constructors. 473b9ea73472fb85e1a7074734824ad11c3f64cad83Yigit Boyar """.trim() 474b9ea73472fb85e1a7074734824ad11c3f64cad83Yigit Boyar 475abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar val PAGING_SPECIFY_DATA_SOURCE_TYPE = "For now, Room only supports TiledDataSource class." 476540e3498175652abe452d8e0ed1c252e718ddf5aFlorina Muntenescu 4776f1f5567abe765d30fda9c8fedce5617ecdeda9cAurimas Liutikas fun primaryKeyNull(field: String): String { 4784c22afcd70f11a45e350b5729e67dc9f27deb319Florina Muntenescu return "You must annotate primary keys with @NonNull. \"$field\" is nullable. SQLite " + 4794c22afcd70f11a45e350b5729e67dc9f27deb319Florina Muntenescu "considers this a " + 4804c22afcd70f11a45e350b5729e67dc9f27deb319Florina Muntenescu "bug and Room does not allow it. See SQLite docs for details: " + 4814c22afcd70f11a45e350b5729e67dc9f27deb319Florina Muntenescu "https://www.sqlite.org/lang_createtable.html" 4824c22afcd70f11a45e350b5729e67dc9f27deb319Florina Muntenescu } 483f3b01d87d24552e0d716aa6b002fcd54e2522adfYigit Boyar 484f3b01d87d24552e0d716aa6b002fcd54e2522adfYigit Boyar val INVALID_COLUMN_NAME = "Invalid column name. Room does not allow using ` or \" in column" + 485f3b01d87d24552e0d716aa6b002fcd54e2522adfYigit Boyar " names" 486f3b01d87d24552e0d716aa6b002fcd54e2522adfYigit Boyar 487f3b01d87d24552e0d716aa6b002fcd54e2522adfYigit Boyar val INVALID_TABLE_NAME = "Invalid table name. Room does not allow using ` or \" in table names" 48819b41105359a52aeb80070dec40247241231f05dYigit Boyar} 489