1 /*
2  * 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.migration.bundle
18 
19 import androidx.annotation.RestrictTo
20 import androidx.room.Index
21 import kotlinx.serialization.SerialName
22 import kotlinx.serialization.Serializable
23 
24 /** Data class that holds the schema information about a table [androidx.room.Index] */
25 @Serializable
26 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
27 class IndexBundle(
28     @SerialName("name") val name: String,
29     @SerialName("unique") val isUnique: Boolean,
30     @SerialName("columnNames") val columnNames: List<String>? = null,
31     @SerialName("orders") val orders: List<String>? = null,
32     @SerialName("createSql") val createSql: String
33 ) : SchemaEquality<IndexBundle> {
34     companion object {
35         // should match Index.kt
36         const val DEFAULT_PREFIX: String = "index_"
37     }
38 
createnull39     fun create(tableName: String): String {
40         return replaceTableName(createSql, tableName)
41     }
42 
43     /** Gets the CREATE INDEX SQL query that uses the given table name. */
getCreateSqlnull44     fun getCreateSql(tableName: String): String {
45         return replaceTableName(createSql, tableName)
46     }
47 
isSchemaEqualnull48     override fun isSchemaEqual(other: IndexBundle): Boolean {
49         if (isUnique != other.isUnique) return false
50         if (name.startsWith(DEFAULT_PREFIX)) {
51             if (!other.name.startsWith(DEFAULT_PREFIX)) {
52                 return false
53             }
54         } else if (other.name.startsWith(DEFAULT_PREFIX)) {
55             return false
56         } else if (name != other.name) {
57             return false
58         }
59 
60         // order matters
61         if (columnNames?.let { columnNames != other.columnNames } ?: (other.columnNames != null)) {
62             return false
63         }
64 
65         // order matters and null orders is considered equal to all ASC orders, to be backward
66         // compatible with schemas where orders are not present in the schema file
67         val columnsSize = columnNames?.size ?: 0
68         val orders =
69             if (orders.isNullOrEmpty()) {
70                 List(columnsSize) { Index.Order.ASC.name }
71             } else {
72                 orders
73             }
74         val otherOrders =
75             if (other.orders.isNullOrEmpty()) {
76                 List(columnsSize) { Index.Order.ASC.name }
77             } else {
78                 other.orders
79             }
80 
81         if (orders != otherOrders) return false
82         return true
83     }
84 }
85