diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Database.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Database.kt index 75564ad..f82700f 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Database.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Database.kt @@ -1,12 +1,12 @@ package dev.matrix.roomigrant.compiler import com.squareup.kotlinpoet.* +import dev.matrix.roomigrant.AfterMigrationRule +import dev.matrix.roomigrant.BeforeMigrationRule import dev.matrix.roomigrant.FieldMigrationRule import dev.matrix.roomigrant.GenerateRoomMigrations import dev.matrix.roomigrant.compiler.data.Scheme -import dev.matrix.roomigrant.compiler.rules.FieldRule -import dev.matrix.roomigrant.compiler.rules.FieldRules -import dev.matrix.roomigrant.compiler.rules.RulesHolder +import dev.matrix.roomigrant.compiler.rules.* import javax.annotation.processing.ProcessingEnvironment import javax.lang.model.element.ElementKind import javax.lang.model.element.TypeElement @@ -17,7 +17,7 @@ import javax.tools.StandardLocation /** * @author matrixdev */ -@Suppress("UNCHECKED_CAST") +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") class Database(val environment: ProcessingEnvironment, element: TypeElement) { val migrationType = ClassName("android.arch.persistence.room.migration", "Migration") @@ -29,8 +29,8 @@ class Database(val environment: ProcessingEnvironment, element: TypeElement) { val elementClassName = element.asClassName().simpleName() val migrationListClassName = ClassName(packageName, "${elementClassName}_Migrations") + val rules = Rules() val migrations = ArrayList() - val fieldRules = FieldRules() val rulesHolderList = ArrayList() init { @@ -48,7 +48,17 @@ class Database(val environment: ProcessingEnvironment, element: TypeElement) { method.getAnnotation(FieldMigrationRule::class.java)?.also { val rule = FieldRule(this, holder, method.simpleName.toString()) - fieldRules.put(it.version1, it.version2, it.table, it.field, rule) + rules.putFieldRule(it.version1, it.version2, it.table, it.field, rule) + } + + method.getAnnotation(BeforeMigrationRule::class.java)?.also { + val rule = LifecycleRule(this, holder, method.simpleName.toString()) + rules.putBeforeRule(it.version1, it.version2, rule) + } + + method.getAnnotation(AfterMigrationRule::class.java)?.also { + val rule = LifecycleRule(this, holder, method.simpleName.toString()) + rules.putAfterRule(it.version1, it.version2, rule) } } 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 c33b99b..a0ea339 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/Migration.kt @@ -34,8 +34,16 @@ class Migration( funcSpecBuilder.addModifiers(KModifier.OVERRIDE) funcSpecBuilder.addParameter(databaseArgName, state.sqLiteDatabaseType) + state.rules.getBeforeRule(scheme1.version, scheme2.version)?.also { + funcSpecBuilder.addCode(it.getInvokeCode(databaseArgName)) + } + migrate() + state.rules.getAfterRule(scheme1.version, scheme2.version)?.also { + funcSpecBuilder.addCode(it.getInvokeCode(databaseArgName)) + } + typeSpec = TypeSpec.objectBuilder(className) .superclass(state.migrationType) .addSuperclassConstructorParameter("%L, %L", scheme1.version, scheme2.version) @@ -88,19 +96,19 @@ class Migration( val fields = LinkedHashMap() for (it in tableDiff.fieldsDiff.same) { val rule = getFieldRule(table2, it.field2) - fields[it.field2.name] = rule?.invokeCodeWrapped ?: it.copySql + fields[it.field2.name] = rule?.inStringTemplate ?: it.copySql } for (it in tableDiff.fieldsDiff.added) { val rule = getFieldRule(table2, it) - fields[it.name] = rule?.invokeCodeWrapped ?: it.defaultSqlValue + fields[it.name] = rule?.inStringTemplate ?: it.defaultSqlValue } for (it in tableDiff.fieldsDiff.affinityChanged) { val rule = getFieldRule(table2, it.field2) - fields[it.field2.name] = rule?.invokeCodeWrapped ?: it.castSql + fields[it.field2.name] = rule?.inStringTemplate ?: it.castSql } for (it in tableDiff.fieldsDiff.nullabilityChanged) { val rule = getFieldRule(table2, it.field2) - fields[it.field2.name] = rule?.invokeCodeWrapped ?: it.toNotNullableSql + fields[it.field2.name] = rule?.inStringTemplate ?: it.toNotNullableSql } val sb = StringBuilder() @@ -138,7 +146,7 @@ class Migration( } private fun getFieldRule(table: Table, field: Field): FieldRule? { - return state.fieldRules.get(scheme1.version, scheme2.version, table.name, field.name) + return state.rules.getFieldRule(scheme1.version, scheme2.version, table.name, field.name) } private fun execSql(query: String) { diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRule.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRule.kt index 94a0a35..0c54af3 100644 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRule.kt +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRule.kt @@ -12,6 +12,6 @@ data class FieldRule( val methodName: String) { val invokeCode = CodeBlock.of("%T.%L.%L()", state.migrationListClassName, holder.name, methodName) - val invokeCodeWrapped = "\${$invokeCode}" + val inStringTemplate = "\${$invokeCode}" -} \ No newline at end of file +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRules.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRules.kt deleted file mode 100644 index 0a91a84..0000000 --- a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/FieldRules.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.matrix.roomigrant.compiler.rules - -/** - * @author matrixdev - */ -class FieldRules { - - private val map = HashMap() - - fun get(version1: Int, version2: Int, table: String, field: String): FieldRule? { - return map[pack(version1, version2, table, field)] - } - - fun put(version1: Int, version2: Int, table: String, field: String, rule: FieldRule) { - map[pack(version1, version2, table, field)] = rule - } - - private fun pack(version1: Int, version2: Int, table: String, field: String) = - "$version1-$version2-$table-$field" - -} \ No newline at end of file diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/LifecycleRule.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/LifecycleRule.kt new file mode 100644 index 0000000..317b015 --- /dev/null +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/LifecycleRule.kt @@ -0,0 +1,16 @@ +package dev.matrix.roomigrant.compiler.rules + +import dev.matrix.roomigrant.compiler.Database +import com.squareup.kotlinpoet.CodeBlock + +/** + * @author matrixdev + */ +data class LifecycleRule( + val state: Database, + val holder: RulesHolder, + val methodName: String) { + + fun getInvokeCode(databaseArgName: String) = CodeBlock.of("%T.%L.%L($databaseArgName)\n", state.migrationListClassName, holder.name, methodName) + +} diff --git a/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/Rules.kt b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/Rules.kt new file mode 100644 index 0000000..7b07e9c --- /dev/null +++ b/RoomigrantCompiler/src/main/java/dev/matrix/roomigrant/compiler/rules/Rules.kt @@ -0,0 +1,42 @@ +package dev.matrix.roomigrant.compiler.rules + +/** + * @author matrixdev + */ +class Rules { + + private val fieldRules = HashMap() + private val beforeRules = HashMap() + private val afterRules = HashMap() + + fun getFieldRule(version1: Int, version2: Int, table: String, field: String): FieldRule? { + return fieldRules[packFieldRuleKey(version1, version2, table, field)] + } + + fun putFieldRule(version1: Int, version2: Int, table: String, field: String, rule: FieldRule) { + fieldRules[packFieldRuleKey(version1, version2, table, field)] = rule + } + + fun getBeforeRule(version1: Int, version2: Int): LifecycleRule? { + return beforeRules[packLifecycleRuleKey(version1, version2)] + } + + fun putBeforeRule(version1: Int, version2: Int, rule: LifecycleRule) { + beforeRules[packLifecycleRuleKey(version1, version2)] = rule + } + + fun getAfterRule(version1: Int, version2: Int): LifecycleRule? { + return afterRules[packLifecycleRuleKey(version1, version2)] + } + + fun putAfterRule(version1: Int, version2: Int, rule: LifecycleRule) { + afterRules[packLifecycleRuleKey(version1, version2)] = rule + } + + private fun packLifecycleRuleKey(version1: Int, version2: Int) = + "$version1-$version2" + + private fun packFieldRuleKey(version1: Int, version2: Int, table: String, field: String) = + "$version1-$version2-$table-$field" + +} diff --git a/RoomigrantLib/src/main/java/dev/matrix/roomigrant/AfterMigrationRule.kt b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/AfterMigrationRule.kt new file mode 100644 index 0000000..2993fe8 --- /dev/null +++ b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/AfterMigrationRule.kt @@ -0,0 +1,10 @@ +package dev.matrix.roomigrant + +/** + * @author matrixdev + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +annotation class AfterMigrationRule( + val version1: Int, + val version2: Int) diff --git a/RoomigrantLib/src/main/java/dev/matrix/roomigrant/BeforeMigrationRule.kt b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/BeforeMigrationRule.kt new file mode 100644 index 0000000..52dbe25 --- /dev/null +++ b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/BeforeMigrationRule.kt @@ -0,0 +1,10 @@ +package dev.matrix.roomigrant + +/** + * @author matrixdev + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +annotation class BeforeMigrationRule( + val version1: Int, + val version2: Int) diff --git a/RoomigrantLib/src/main/java/dev/matrix/roomigrant/FieldMigrationRule.kt b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/FieldMigrationRule.kt index 0959cc9..ef64342 100644 --- a/RoomigrantLib/src/main/java/dev/matrix/roomigrant/FieldMigrationRule.kt +++ b/RoomigrantLib/src/main/java/dev/matrix/roomigrant/FieldMigrationRule.kt @@ -9,4 +9,4 @@ annotation class FieldMigrationRule( val version1: Int, val version2: Int, val table: String, - val field: String) \ No newline at end of file + val field: String) diff --git a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Rules.kt b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Rules.kt index 0137ad6..3ab8123 100644 --- a/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Rules.kt +++ b/RoomigrantTest/src/main/java/dev/matrix/roomigrant/test/Rules.kt @@ -1,10 +1,14 @@ package dev.matrix.roomigrant.test +import android.arch.persistence.db.SupportSQLiteDatabase +import dev.matrix.roomigrant.AfterMigrationRule +import dev.matrix.roomigrant.BeforeMigrationRule import dev.matrix.roomigrant.FieldMigrationRule /** * @author matrixdev */ +@Suppress("FunctionName") class Rules { @FieldMigrationRule(version1 = 3, version2 = 4, table = "Object1Dbo", field = "intValRenamed") @@ -17,4 +21,15 @@ class Rules { return "`Object1Dbo`.`stringVal`" } -} \ No newline at end of file + @BeforeMigrationRule(version1 = 1, version2 = 2) + fun migrate_1_2_before(db: SupportSQLiteDatabase) { + val cursor = db.query("pragma table_info(Object1Dbo)") + assert(cursor.count == 1) + } + + @AfterMigrationRule(version1 = 1, version2 = 2) + fun migrate_1_2_after(db: SupportSQLiteDatabase) { + val cursor = db.query("pragma table_info(Object1Dbo)") + assert(cursor.count == 3) + } +} diff --git a/build.gradle b/build.gradle index 7a72c6d..db03782 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' + classpath 'com.android.tools.build:gradle:3.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cdf0b84..eee3586 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jul 15 21:42:25 EEST 2018 +#Tue Dec 18 12:36:59 EET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip