From ea8cd44f98fbb29a11bd79ad83c6a5a5c89baf36 Mon Sep 17 00:00:00 2001 From: Rick Busarow Date: Tue, 2 Jun 2020 16:18:02 -0500 Subject: [PATCH] add incremental support --- .../matrix/roomigrant/compiler/Migration.kt | 53 +++++++--- .../matrix/roomigrant/compiler/Processor.kt | 55 ++++++----- .../matrix/roomigrant/compiler/data/Scheme.kt | 5 +- .../matrix/roomigrant/compiler/data/View.kt | 20 ++++ .../roomigrant/compiler/diff/FieldDiff.kt | 14 +-- .../roomigrant/compiler/diff/FieldsDiff.kt | 14 +-- .../roomigrant/compiler/diff/IndicesDiff.kt | 12 +-- .../roomigrant/compiler/diff/SchemeDiff.kt | 57 ++++++++--- .../roomigrant/compiler/diff/TableDiff.kt | 11 ++- .../roomigrant/compiler/diff/ViewDiff.kt | 12 +++ .../10.json | 98 +++++++++++++++++++ .../11.json | 98 +++++++++++++++++++ .../12.json | 98 +++++++++++++++++++ .../7.json | 6 +- .../8.json | 93 ++++++++++++++++++ .../9.json | 93 ++++++++++++++++++ .../matrix/roomigrant/test/DatabaseTest.kt | 2 +- .../dev/matrix/roomigrant/test/Database.kt | 6 +- .../dev/matrix/roomigrant/test/Object1Dbo.kt | 1 + .../dev/matrix/roomigrant/test/Object2Dbo.kt | 4 +- .../matrix/roomigrant/test/ObjectDboView.kt | 9 ++ 21 files changed, 673 insertions(+), 88 deletions(-) create mode 100644 RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/View.kt create mode 100644 RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/ViewDiff.kt create mode 100644 RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/10.json create mode 100644 RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/11.json create mode 100644 RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/12.json create mode 100644 RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/8.json create mode 100644 RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/9.json create mode 100644 RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/ObjectDboView.kt diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt index 745bac1..30e560a 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt @@ -1,10 +1,7 @@ package dev.matrix.roomigrant.compiler import com.squareup.kotlinpoet.* -import dev.matrix.roomigrant.compiler.data.Field -import dev.matrix.roomigrant.compiler.data.Index -import dev.matrix.roomigrant.compiler.data.Scheme -import dev.matrix.roomigrant.compiler.data.Table +import dev.matrix.roomigrant.compiler.data.* import dev.matrix.roomigrant.compiler.diff.SchemeDiff import dev.matrix.roomigrant.compiler.rules.FieldRule import java.util.* @@ -65,14 +62,14 @@ class Migration( var variableIndex = 0 val diff = SchemeDiff(scheme1, scheme2) - for (tableDiff in diff.added) { - createTable(tableDiff.table2) - createTableIndices(tableDiff.table2) + for (tableDiff in diff.addedTables) { + createTable(tableDiff.new) + createTableIndices(tableDiff.new) } - for (tableDiff in diff.changed) { - val table1 = tableDiff.table1 - val table2 = tableDiff.table2 + for (tableDiff in diff.changedTables) { + val table1 = tableDiff.old + val table2 = tableDiff.new if (!tableDiff.primaryKeyChanged && tableDiff.fieldsDiff.onlyAdded) { val sb = StringBuilder() @@ -103,16 +100,16 @@ class Migration( val fields = LinkedHashMap() for (it in tableDiff.fieldsDiff.same) { - fields[it.field2.name] = toSql(getFieldRule(table2, it.field2), it.copySql) + fields[it.newField.name] = toSql(getFieldRule(table2, it.newField), it.copySql) } for (it in tableDiff.fieldsDiff.added) { fields[it.name] = toSql(getFieldRule(table2, it), it.defaultSqlValue) } for (it in tableDiff.fieldsDiff.affinityChanged) { - fields[it.field2.name] = toSql(getFieldRule(table2, it.field2), it.castSql) + fields[it.newField.name] = toSql(getFieldRule(table2, it.newField), it.castSql) } for (it in tableDiff.fieldsDiff.nullabilityChanged) { - fields[it.field2.name] = toSql(getFieldRule(table2, it.field2), it.toNotNullableSql) + fields[it.newField.name] = toSql(getFieldRule(table2, it.newField), it.toNotNullableSql) } val sb = StringBuilder() @@ -139,9 +136,25 @@ class Migration( } } - for (table in diff.removed) { + for (table in diff.removedTables) { dropTable(table.name) } + + for (viewDiff in diff.addedViews) { + createView(viewDiff.new) + } + + for (viewDiff in diff.changedViews) { + val old = viewDiff.old + val new = viewDiff.new + + old?.name?.let { dropView(it)} + createView(new) + } + + for (view in diff.removedViews) { + dropView(view.name) + } } private fun getFieldRule(table: Table, field: Field): FieldRule? { @@ -164,6 +177,18 @@ class Migration( execSql(table.createSql(table.name)) } + private fun dropView(viewName: String) { + execSql("DROP VIEW IF EXISTS `$viewName`") + } + + private fun renameView(viewName1: String, viewName2: String) { + execSql("ALTER VIEW `$viewName1` RENAME TO `$viewName2`") + } + + private fun createView(view: View) { + execSql(view.createSql(view.name)) + } + private fun dropTableIndex(index: Index) { execSql("DROP INDEX IF EXISTS ${index.name}") } diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Processor.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Processor.kt index c1c7135..351fc8f 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Processor.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Processor.kt @@ -7,6 +7,7 @@ import dev.matrix.roomigrant.GenerateRoomMigrations import dev.matrix.roomigrant.compiler.data.Root import net.ltgt.gradle.incap.IncrementalAnnotationProcessor import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING +import dev.matrix.roomigrant.compiler.data.Scheme import java.io.File import java.io.InputStreamReader import javax.annotation.processing.AbstractProcessor @@ -25,38 +26,38 @@ import androidx.room.Database as DatabaseAnnotation @SupportedSourceVersion(SourceVersion.RELEASE_7) class Processor : AbstractProcessor() { - override fun getSupportedSourceVersion() = SourceVersion.latestSupported()!! - override fun getSupportedAnnotationTypes() = mutableSetOf(GenerateRoomMigrations::class.java.name) + override fun getSupportedSourceVersion() = SourceVersion.latestSupported()!! + override fun getSupportedAnnotationTypes() = mutableSetOf(GenerateRoomMigrations::class.java.name) - private val moshi = Moshi.Builder().build() + private val moshi = Moshi.Builder().build() - override fun process(annotations: MutableSet, roundEnvironment: RoundEnvironment): Boolean { - val schemaLocation = processingEnv.options["room.schemaLocation"] ?: return true - val elements = roundEnvironment.getElementsAnnotatedWith(GenerateRoomMigrations::class.java) - .filterIsInstance() + override fun process(annotations: MutableSet, roundEnvironment: RoundEnvironment): Boolean { + val schemaLocation = processingEnv.options["room.schemaLocation"] ?: return true + val elements = roundEnvironment.getElementsAnnotatedWith(GenerateRoomMigrations::class.java) + .filterIsInstance() - for (element in elements) { - if (element.getAnnotation(DatabaseAnnotation::class.java) == null) { - throw Exception("$element is not annotated with ${DatabaseAnnotation::class.simpleName}") - } - processDatabase(schemaLocation, element) - } - return true - } + for (element in elements) { + if (element.getAnnotation(DatabaseAnnotation::class.java) == null) { + throw Exception("$element is not annotated with ${DatabaseAnnotation::class.simpleName}") + } + processDatabase(schemaLocation, element) + } + return true + } - private fun processDatabase(schemaLocation: String, element: TypeElement) { - val folder = File(schemaLocation, element.asClassName().toString()) - val schemes = folder.listFiles().mapNotNull { readScheme(it) }.sortedBy { it.version } + private fun processDatabase(schemaLocation: String, element: TypeElement) { + val folder = File(schemaLocation, element.asClassName().toString()) + val schemes = folder.listFiles().mapNotNull { readScheme(it) }.sortedBy { it.version } - val database = Database(processingEnv, element) - for (scheme in schemes) { - database.addScheme(scheme) - } - for (index in 1 until schemes.size) { - database.addMigration(schemes[index - 1], schemes[index]).generate() - } - database.generate() - } + val database = Database(processingEnv, element) + for (scheme in schemes) { + database.addScheme(scheme) + } + for (index in 1 until schemes.size) { + database.addMigration(schemes[index - 1], schemes[index]).generate() + } + database.generate() + } private fun readScheme(file: File) = try { InputStreamReader(file.inputStream()).use { diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/Scheme.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/Scheme.kt index 200186d..8c4d5a7 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/Scheme.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/Scheme.kt @@ -12,4 +12,7 @@ data class Scheme( val version: Int, @Json(name = "entities") - val tables: List) + val tables: List
, + + @Json(name ="views") + val views: List = emptyList()) diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/View.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/View.kt new file mode 100644 index 0000000..7078f87 --- /dev/null +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/data/View.kt @@ -0,0 +1,20 @@ +package dev.matrix.roomigrant.compiler.data + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class View( + @Json(name ="viewName") + val name: String, + + @Json(name ="createSql") + val createSqlTemplate: String) { + + fun createSql(viewName: String = name) = createSqlTemplate.replace("\${VIEW_NAME}", viewName) + + constructor(view: View, name: String) : this( + name = name, + createSqlTemplate = view.createSqlTemplate) + +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldDiff.kt index 0cc70d3..b265966 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldDiff.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldDiff.kt @@ -7,16 +7,16 @@ import dev.matrix.roomigrant.compiler.data.Table * @author matrixdev */ @Suppress("CanBeParameter", "MemberVisibilityCanBePrivate", "unused") -class FieldDiff(val table1: Table, val table2: Table, val field1: Field, val field2: Field) { - val affinityChanged = field1.affinity != field2.affinity - val nullabilityChanged = !field1.notNull && field2.notNull +class FieldDiff(val oldTable: Table, val newTable: Table, val oldField: Field, val newField: Field) { + val affinityChanged = oldField.affinity != newField.affinity + val nullabilityChanged = !oldField.notNull && newField.notNull val copySql: String - get() = "`${table1.name}`.`${field1.name}`" + get() = "`${oldTable.name}`.`${oldField.name}`" val castSql: String - get() = "CAST(`${table1.name}`.`${field1.name}` AS ${field2.affinity})" + get() = "CAST(`${oldTable.name}`.`${oldField.name}` AS ${newField.affinity})" val toNotNullableSql: String - get() = "IFNULL(`${table1.name}`.`${field2.name}`, ${field2.defaultSqlValue})" -} \ No newline at end of file + get() = "IFNULL(`${oldTable.name}`.`${newField.name}`, ${newField.defaultSqlValue})" +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldsDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldsDiff.kt index af33620..4d4a85b 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldsDiff.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/FieldsDiff.kt @@ -7,7 +7,7 @@ import dev.matrix.roomigrant.compiler.data.Table * @author matrixdev */ @Suppress("CanBeParameter", "MemberVisibilityCanBePrivate") -class FieldsDiff(val table1: Table?, val table2: Table) { +class FieldsDiff(val old: Table?, val new: Table) { val same = ArrayList() val added = ArrayList() @@ -26,20 +26,20 @@ class FieldsDiff(val table1: Table?, val table2: Table) { } fun init() { - if (table1 == null) { - added.addAll(table2.fields) + if (old == null) { + added.addAll(new.fields) return } - val fields1Map = table1.fields.associateByTo(HashMap()) { it.name } - for (field2 in table2.fields) { + val fields1Map = old.fields.associateByTo(HashMap()) { it.name } + for (field2 in new.fields) { val field1 = fields1Map.remove(field2.name) if (field1 == null) { added.add(field2) continue } - val diff = FieldDiff(table1, table2, field1, field2) + val diff = FieldDiff(old, new, field1, field2) when { diff.affinityChanged -> affinityChanged.add(diff) diff.nullabilityChanged -> nullabilityChanged.add(diff) @@ -49,4 +49,4 @@ class FieldsDiff(val table1: Table?, val table2: Table) { removed.addAll(fields1Map.values) } -} \ No newline at end of file +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/IndicesDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/IndicesDiff.kt index 1491fbb..a943aeb 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/IndicesDiff.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/IndicesDiff.kt @@ -7,7 +7,7 @@ import dev.matrix.roomigrant.compiler.data.Table * @author matrixdev */ @Suppress("CanBeParameter", "MemberVisibilityCanBePrivate") -class IndicesDiff(val table1: Table?, val table2: Table) { +class IndicesDiff(val old: Table?, val new: Table) { val same = ArrayList() val added = ArrayList() @@ -22,13 +22,13 @@ class IndicesDiff(val table1: Table?, val table2: Table) { } fun init() { - if (table1 == null) { - added.addAll(table2.indices) + if (old == null) { + added.addAll(new.indices) return } - val indexes1Map = table1.indices.associateByTo(HashMap()) { it.name } - for (index2 in table2.indices) { + val indexes1Map = old.indices.associateByTo(HashMap()) { it.name } + for (index2 in new.indices) { val index1 = indexes1Map.remove(index2.name) when (index1) { null -> added.add(index2) @@ -39,4 +39,4 @@ class IndicesDiff(val table1: Table?, val table2: Table) { removed.addAll(indexes1Map.values) } -} \ No newline at end of file +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/SchemeDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/SchemeDiff.kt index d9af6be..ce20667 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/SchemeDiff.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/SchemeDiff.kt @@ -2,6 +2,7 @@ package dev.matrix.roomigrant.compiler.diff import dev.matrix.roomigrant.compiler.data.Scheme import dev.matrix.roomigrant.compiler.data.Table +import dev.matrix.roomigrant.compiler.data.View import java.util.* import kotlin.collections.ArrayList import kotlin.collections.HashMap @@ -10,31 +11,57 @@ import kotlin.collections.HashMap * @author matrixdev */ @Suppress("CanBeParameter", "MemberVisibilityCanBePrivate", "unused") -class SchemeDiff(val scheme1: Scheme, val scheme2: Scheme) { +class SchemeDiff(val old: Scheme, val new: Scheme) { - val same = ArrayList() - val added = ArrayList() - val removed = ArrayList
() - val changed = ArrayList() + val sameTables = ArrayList() + val addedTables = ArrayList() + val removedTables = ArrayList
() + val changedTables = ArrayList() + + val sameViews = ArrayList() + val addedViews = ArrayList() + val removedViews = ArrayList() + val changedViews = ArrayList() val wasChanged: Boolean - get() = added.isEmpty() && removed.isEmpty() && changed.isEmpty() + get() = addedTables.isEmpty() + && removedTables.isEmpty() + && changedTables.isEmpty() + && addedViews.isEmpty() + && removedViews.isEmpty() + && changedViews.isEmpty() init { - val tables1Map = scheme1.tables.associateByTo(HashMap()) { it.name.toLowerCase(Locale.getDefault()) } - for (table2 in scheme2.tables) { - val table1 = tables1Map.remove(table2.name.toLowerCase(Locale.getDefault())) - if (table1 == null) { - added.add(TableDiff(null, table2)) + val oldTableMap = old.tables.associateByTo(HashMap()) { it.name.toLowerCase(Locale.getDefault()) } + for (newTable in new.tables) { + val oldTable = oldTableMap.remove(newTable.name.toLowerCase(Locale.getDefault())) + if (oldTable == null) { + addedTables.add(TableDiff(null, newTable)) + continue + } + val diff = TableDiff(oldTable, newTable) + if (diff.wasChanged) { + changedTables.add(diff) + } else { + sameTables.add(TableDiff(null, newTable)) + } + } + removedTables.addAll(oldTableMap.values) + + val newViewMap = old.views.associateByTo(HashMap()) { it.name.toLowerCase(Locale.getDefault()) } + for (newView in new.views) { + val oldView = newViewMap.remove(newView.name.toLowerCase(Locale.getDefault())) + if (oldView == null) { + addedViews.add(ViewDiff(null, newView)) continue } - val diff = TableDiff(table1, table2) + val diff = ViewDiff(oldView, newView) if (diff.wasChanged) { - changed.add(diff) + changedViews.add(diff) } else { - same.add(TableDiff(null, table2)) + sameViews.add(ViewDiff(null, newView)) } } - removed.addAll(tables1Map.values) + removedViews.addAll(newViewMap.values) } } diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/TableDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/TableDiff.kt index 98e03ef..5e63d32 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/TableDiff.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/TableDiff.kt @@ -6,12 +6,13 @@ import dev.matrix.roomigrant.compiler.data.Table * @author matrixdev */ @Suppress("CanBeParameter", "MemberVisibilityCanBePrivate") -class TableDiff(val table1: Table?, val table2: Table) { - val fieldsDiff = FieldsDiff(table1, table2) - val indicesDiff = IndicesDiff(table1, table2) - val nameChanged = table1?.name != table2.name - val primaryKeyChanged = table1?.primaryKey != table2.primaryKey +class TableDiff(val old: Table?, val new: Table) { + val fieldsDiff = FieldsDiff(old, new) + val indicesDiff = IndicesDiff(old, new) + val nameChanged = old?.name != new.name + val primaryKeyChanged = old?.primaryKey != new.primaryKey val wasChanged: Boolean get() = primaryKeyChanged || nameChanged || fieldsDiff.wasChanged || indicesDiff.wasChanged } + diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/ViewDiff.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/ViewDiff.kt new file mode 100644 index 0000000..1a43a86 --- /dev/null +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/diff/ViewDiff.kt @@ -0,0 +1,12 @@ +package dev.matrix.roomigrant.compiler.diff + +import dev.matrix.roomigrant.compiler.data.View + +@Suppress("MemberVisibilityCanBePrivate") +class ViewDiff(val old: View?, val new: View) { + val nameChanged = old?.name != new.name + val sqlChanged = old?.createSqlTemplate != new.createSqlTemplate + + val wasChanged: Boolean + get() = sqlChanged || nameChanged +} diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/10.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/10.json new file mode 100644 index 0000000..584173c --- /dev/null +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/10.json @@ -0,0 +1,98 @@ +{ + "formatVersion": 1, + "database": { + "version": 10, + "identityHash": "77a619dcd14b7b6d0ae1d91133e1e272", + "entities": [ + { + "tableName": "Object1Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `intValRenamed` INTEGER NOT NULL, `stringValRenamed` TEXT NOT NULL, `nullIntVal` INTEGER, `nullStringVal` TEXT NOT NULL, `stringValIndexed` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "intValRenamed", + "columnName": "intValRenamed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stringValRenamed", + "columnName": "stringValRenamed", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nullIntVal", + "columnName": "nullIntVal", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nullStringVal", + "columnName": "nullStringVal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stringValIndexed", + "columnName": "stringValIndexed", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Object1Dbo_stringValIndexed", + "unique": false, + "columnNames": [ + "stringValIndexed" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Object1Dbo_stringValIndexed` ON `${TABLE_NAME}` (`stringValIndexed`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Object2Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [ + { + "viewName": "Object1DboView", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT item.id FROM Object1Dbo item" + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '77a619dcd14b7b6d0ae1d91133e1e272')" + ] + } +} \ No newline at end of file diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/11.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/11.json new file mode 100644 index 0000000..ee752a2 --- /dev/null +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/11.json @@ -0,0 +1,98 @@ +{ + "formatVersion": 1, + "database": { + "version": 11, + "identityHash": "77a619dcd14b7b6d0ae1d91133e1e272", + "entities": [ + { + "tableName": "Object1Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `intValRenamed` INTEGER NOT NULL, `stringValRenamed` TEXT NOT NULL, `nullIntVal` INTEGER, `nullStringVal` TEXT NOT NULL, `stringValIndexed` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "intValRenamed", + "columnName": "intValRenamed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stringValRenamed", + "columnName": "stringValRenamed", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nullIntVal", + "columnName": "nullIntVal", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nullStringVal", + "columnName": "nullStringVal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stringValIndexed", + "columnName": "stringValIndexed", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Object1Dbo_stringValIndexed", + "unique": false, + "columnNames": [ + "stringValIndexed" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Object1Dbo_stringValIndexed` ON `${TABLE_NAME}` (`stringValIndexed`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Object2Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [ + { + "viewName": "ObjectDboView", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT item.id FROM Object1Dbo item" + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '77a619dcd14b7b6d0ae1d91133e1e272')" + ] + } +} \ No newline at end of file diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/12.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/12.json new file mode 100644 index 0000000..d2637b5 --- /dev/null +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/12.json @@ -0,0 +1,98 @@ +{ + "formatVersion": 1, + "database": { + "version": 12, + "identityHash": "e400ad01c0593cfd61a02409485a28e1", + "entities": [ + { + "tableName": "Object1Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `intValRenamed` INTEGER NOT NULL, `stringValRenamed` TEXT NOT NULL, `nullIntVal` INTEGER, `nullStringVal` TEXT NOT NULL, `stringValIndexed` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "intValRenamed", + "columnName": "intValRenamed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stringValRenamed", + "columnName": "stringValRenamed", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nullIntVal", + "columnName": "nullIntVal", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nullStringVal", + "columnName": "nullStringVal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stringValIndexed", + "columnName": "stringValIndexed", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Object1Dbo_stringValIndexed", + "unique": false, + "columnNames": [ + "stringValIndexed" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Object1Dbo_stringValIndexed` ON `${TABLE_NAME}` (`stringValIndexed`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Object2Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [ + { + "viewName": "ObjectDboView", + "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT item.id AS oneId, (SELECT id FROM Object2Dbo WHERE id = item.id) AS twoId FROM Object1Dbo item" + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e400ad01c0593cfd61a02409485a28e1')" + ] + } +} \ No newline at end of file diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/7.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/7.json index b5176d9..9ace082 100644 --- a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/7.json +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/7.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 7, - "identityHash": "9c9e7b939a63314be53d822150843e7d", + "identityHash": "de427762e78df16b8955744c12f675fb", "entities": [ { "tableName": "Object1Dbo", @@ -64,7 +64,7 @@ "foreignKeys": [] }, { - "tableName": "Object2DBO", + "tableName": "Object2Dbo", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", "fields": [ { @@ -87,7 +87,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9c9e7b939a63314be53d822150843e7d')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'de427762e78df16b8955744c12f675fb')" ] } } \ No newline at end of file diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/8.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/8.json new file mode 100644 index 0000000..d820d8d --- /dev/null +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/8.json @@ -0,0 +1,93 @@ +{ + "formatVersion": 1, + "database": { + "version": 8, + "identityHash": "9c9e7b939a63314be53d822150843e7d", + "entities": [ + { + "tableName": "Object1Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `intValRenamed` INTEGER NOT NULL, `stringValRenamed` TEXT NOT NULL, `nullIntVal` INTEGER, `nullStringVal` TEXT NOT NULL, `stringValIndexed` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "intValRenamed", + "columnName": "intValRenamed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stringValRenamed", + "columnName": "stringValRenamed", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nullIntVal", + "columnName": "nullIntVal", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nullStringVal", + "columnName": "nullStringVal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stringValIndexed", + "columnName": "stringValIndexed", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Object1Dbo_stringValIndexed", + "unique": false, + "columnNames": [ + "stringValIndexed" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Object1Dbo_stringValIndexed` ON `${TABLE_NAME}` (`stringValIndexed`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Object2DBO", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9c9e7b939a63314be53d822150843e7d')" + ] + } +} \ No newline at end of file diff --git a/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/9.json b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/9.json new file mode 100644 index 0000000..24742c6 --- /dev/null +++ b/RoomigrantTest/schemas/dev.matrix.roomigrant.test.Database/9.json @@ -0,0 +1,93 @@ +{ + "formatVersion": 1, + "database": { + "version": 9, + "identityHash": "de427762e78df16b8955744c12f675fb", + "entities": [ + { + "tableName": "Object1Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `intValRenamed` INTEGER NOT NULL, `stringValRenamed` TEXT NOT NULL, `nullIntVal` INTEGER, `nullStringVal` TEXT NOT NULL, `stringValIndexed` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "intValRenamed", + "columnName": "intValRenamed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stringValRenamed", + "columnName": "stringValRenamed", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "nullIntVal", + "columnName": "nullIntVal", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nullStringVal", + "columnName": "nullStringVal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stringValIndexed", + "columnName": "stringValIndexed", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Object1Dbo_stringValIndexed", + "unique": false, + "columnNames": [ + "stringValIndexed" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Object1Dbo_stringValIndexed` ON `${TABLE_NAME}` (`stringValIndexed`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Object2Dbo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'de427762e78df16b8955744c12f675fb')" + ] + } +} \ No newline at end of file diff --git a/RoomigrantTest/src/androidTest/java/dev/matrix/roomigrant/test/DatabaseTest.kt b/RoomigrantTest/src/androidTest/java/dev/matrix/roomigrant/test/DatabaseTest.kt index 879f94e..d2a0b1b 100644 --- a/RoomigrantTest/src/androidTest/java/dev/matrix/roomigrant/test/DatabaseTest.kt +++ b/RoomigrantTest/src/androidTest/java/dev/matrix/roomigrant/test/DatabaseTest.kt @@ -21,7 +21,7 @@ class DatabaseTest { val db = migrationHelper.createDatabase(name, 1).let { migrationHelper.runMigrationsAndValidate( name, - 7, + 12, true, *Database_Migrations.build() ) diff --git a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Database.kt b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Database.kt index 3945844..40dc84a 100644 --- a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Database.kt +++ b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Database.kt @@ -7,7 +7,11 @@ import dev.matrix.roomigrant.GenerateRoomMigrations /** * @author matrixdev */ -@Database(version = 7, entities = [Object1Dbo::class, Object2Dbo::class]) +@Database( + version = 12, + entities = [Object1Dbo::class, Object2Dbo::class], + views = [ObjectDboView::class] +) @GenerateRoomMigrations(Rules::class) abstract class Database : RoomDatabase() { abstract val object1Dao: Object1Dao diff --git a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object1Dbo.kt b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object1Dbo.kt index b03681d..3ad8ec0 100644 --- a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object1Dbo.kt +++ b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object1Dbo.kt @@ -25,3 +25,4 @@ class Object1Dbo { var stringValIndexed: String = "" } + diff --git a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object2Dbo.kt b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object2Dbo.kt index 8879567..e77520f 100644 --- a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object2Dbo.kt +++ b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Object2Dbo.kt @@ -1,5 +1,6 @@ package dev.matrix.roomigrant.test +import androidx.room.DatabaseView import androidx.room.Entity import androidx.room.PrimaryKey @@ -7,5 +8,6 @@ import androidx.room.PrimaryKey /** * @author matrixdev */ -@Entity(tableName = "Object2DBO") +@Entity data class Object2Dbo(@PrimaryKey var id: String = "") + diff --git a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/ObjectDboView.kt b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/ObjectDboView.kt new file mode 100644 index 0000000..4153085 --- /dev/null +++ b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/ObjectDboView.kt @@ -0,0 +1,9 @@ +package dev.matrix.roomigrant.test + +import androidx.room.DatabaseView + +@DatabaseView("SELECT item.id AS oneId, (SELECT id FROM Object2Dbo WHERE id = item.id) AS twoId FROM Object1Dbo item") +data class ObjectDboView( + val oneId: Int, + val twoId: Int +)