@@ -3,14 +3,17 @@ package dev.matrix.roomigrant.compiler
3
3
import com.squareup.kotlinpoet.*
4
4
import dev.matrix.roomigrant.compiler.data.Scheme
5
5
import dev.matrix.roomigrant.compiler.rules.Rules
6
+ import dev.matrix.roomigrant.model.IndexInfo
7
+ import dev.matrix.roomigrant.model.SchemeInfo
8
+ import dev.matrix.roomigrant.model.TableInfo
6
9
import javax.annotation.processing.ProcessingEnvironment
7
10
import javax.lang.model.element.TypeElement
8
11
import javax.tools.StandardLocation
9
12
10
13
/* *
11
14
* @author matrixdev
12
15
*/
13
- @Suppress(" UNCHECKED_CAST" , " MemberVisibilityCanBePrivate" )
16
+ @Suppress(" UNCHECKED_CAST" , " MemberVisibilityCanBePrivate" , " FunctionName " )
14
17
class Database (val environment : ProcessingEnvironment , element : TypeElement ) {
15
18
16
19
val migrationType = ClassName (" android.arch.persistence.room.migration" , " Migration" )
@@ -23,37 +26,85 @@ class Database(val environment: ProcessingEnvironment, element: TypeElement) {
23
26
val migrationListClassName = ClassName (packageName, " ${elementClassName} _Migrations" )
24
27
25
28
val rules = Rules (this , element)
29
+ val schemes = ArrayList <Scheme >()
26
30
val migrations = ArrayList <Migration >()
27
31
32
+ fun addScheme (scheme : Scheme ) {
33
+ schemes.add(scheme)
34
+ }
35
+
28
36
fun addMigration (database1 : Scheme , database2 : Scheme ): Migration {
29
37
return Migration (this , database1, database2).also { migrations.add(it) }
30
38
}
31
39
32
40
fun generate () {
33
- // migration class
34
41
val typeSpec = TypeSpec .objectBuilder(migrationListClassName)
42
+ .addProperties(generate_rules())
43
+ .addFunction(generate_build())
44
+ .addFunction(generate_buildScheme())
35
45
36
- // "rules" fields
37
- for (holder in rules.getProvidersFields()) {
38
- typeSpec.addProperty(holder.propertySpec)
39
- }
46
+ val fileSpec = FileSpec .builder(packageName, migrationListClassName.simpleName())
47
+ .addType(typeSpec.build())
48
+ .build()
40
49
41
- // "build" function
50
+ environment.filer.createResource(StandardLocation .SOURCE_OUTPUT , packageName, " ${migrationListClassName.simpleName()} .kt" )
51
+ .openWriter()
52
+ .use { fileSpec.writeTo(it) }
53
+ }
54
+
55
+ private fun generate_rules () = rules.getProvidersFields().map {
56
+ PropertySpec .builder(it.name, it.type)
57
+ .initializer(" %T()" , it.type)
58
+ .build()
59
+ }
60
+
61
+ private fun generate_build (): FunSpec {
42
62
val funcSpec = FunSpec .builder(" build" ).addStatement(" val list = %T()" , migrationListType)
43
63
for (migration in migrations) {
44
64
funcSpec.addStatement(" list.add(%T)" , migration.className)
45
65
}
46
66
funcSpec.returns(migrationArrayType).addStatement(" return list.toTypedArray()" )
47
- typeSpec.addFunction(funcSpec.build())
67
+ return funcSpec.build()
68
+ }
48
69
49
- // writing to file
50
- val fileSpec = FileSpec .builder(packageName, migrationListClassName.simpleName())
51
- .addType(typeSpec.build())
52
- .build()
70
+ private fun generate_buildScheme (): FunSpec {
71
+ val code = FunSpec .builder(" buildScheme" )
72
+ .returns(ParameterizedTypeName .get(Map ::class , Int ::class , SchemeInfo ::class ))
53
73
54
- environment.filer.createResource(StandardLocation .SOURCE_OUTPUT , packageName, " ${migrationListClassName.simpleName()} .kt" )
55
- .openWriter()
56
- .use { fileSpec.writeTo(it) }
74
+ var varIndex = 0
75
+ fun generateVarName () = " var${++ varIndex} "
76
+
77
+ val schemesVar = generateVarName()
78
+ val schemesType = ParameterizedTypeName .get(HashMap ::class , Int ::class , SchemeInfo ::class )
79
+ code.addStatement(" val %L = %T()" , schemesVar, schemesType)
80
+
81
+ for (scheme in schemes) {
82
+ val tablesVar = generateVarName()
83
+ val tablesType = ParameterizedTypeName .get(HashMap ::class , String ::class , TableInfo ::class )
84
+ code.addStatement(" val %L = %T()" , tablesVar, tablesType)
85
+
86
+ val schemeVar = generateVarName()
87
+ code.addStatement(" val %L = %T(%L, %L)" , schemeVar, SchemeInfo ::class , scheme.version, tablesVar)
88
+ code.addStatement(" %L.put(%L, %L)" , schemesVar, scheme.version, schemeVar)
89
+
90
+ for (table in scheme.tables) {
91
+ val indicesVar = generateVarName()
92
+ val indicesType = ParameterizedTypeName .get(HashMap ::class , String ::class , IndexInfo ::class )
93
+ code.addStatement(" val %L = %T()" , indicesVar, indicesType)
94
+
95
+ val tableVar = generateVarName()
96
+ code.addStatement(" val %L = %T(%L, %S, %S, %L)" , tableVar, TableInfo ::class , schemeVar, table.name, table.createSql(), indicesVar)
97
+ code.addStatement(" %L.put(%S, %L)" , tablesVar, table.name, tableVar)
98
+
99
+ for (index in table.indices) {
100
+ code.addStatement(" %L.put(%S, %T(%L, %S, %S))" , indicesVar, index.name, IndexInfo ::class , tableVar, index.name, index.createSql(table.name))
101
+ }
102
+ }
103
+ }
104
+
105
+ code.addStatement(" return %L" , schemesVar)
106
+
107
+ return code.build()
57
108
}
58
109
59
110
}
0 commit comments