Skip to content

Instantly share code, notes, and snippets.

@tateisu
Created February 4, 2023 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tateisu/2c80cdbb22b34b08ee1a9a0deab77cf8 to your computer and use it in GitHub Desktop.
Save tateisu/2c80cdbb22b34b08ee1a9a0deab77cf8 to your computer and use it in GitHub Desktop.
Roomのスキーマ差異例外のダンプを比較するスクリプト
import java.io.File
fun splitTableInfo(src: String): List<String> {
val lines = ArrayList<String>()
val after = src.replace("""([\w_]+=Column\{[^}]+\}|Index\{[^}]+\}),? ?""".toRegex()) {
lines.add(it.groupValues[1])
""
}
lines.add(" :$after")
return lines.sorted()
}
fun String.fix() =
this.replace("""(type)=(\S+)""".toRegex()) {
"${it.groupValues[1]}=${it.groupValues[2].uppercase()}"
}
fun compareLines(lName: String, l: List<String>?, rName: String, r: List<String>?) {
println("${lName}.size=${l?.size}, ${rName}.size=${r?.size}")
var i = 0
while (true) {
val lLine = l?.elementAtOrNull(i)?.fix()
val rLine = r?.elementAtOrNull(i)?.fix()
++i
if (lLine == null && rLine == null) break
if (lLine == rLine) {
if (lLine?.contains("TableInfo") == true) {
println("[$i] $lLine")
}
continue
}
if (lLine != null) println("[$i]${lName} $lLine")
if (rLine != null) println("[$i]${rName} $rLine")
if (lLine != null && rLine != null && lLine != rLine) {
println("line is not same")
}
}
}
fun main() {
var target = ""
val map = HashMap<String, List<String>>()
val lines = File("error.txt").readText()
.split("""[\x0d\x0a]+""".toRegex())
.mapNotNull {
it.replace("""\A\s+""".toRegex(), "")
.replace("""\s+\z""".toRegex(), "")
.takeIf { l -> l.isNotBlank() }
}
for (line in lines) {
when (line) {
"Expected:" -> target = "e"
"Found:" -> target = "f"
else -> {
map[target] = splitTableInfo(line)
if (map.containsKey("e") && map.containsKey("f")) break
}
}
}
compareLines(
"Expect", map["e"],
"Actual", map["f"],
)
}
@tateisu
Copy link
Author

tateisu commented Feb 4, 2023

比較結果の例

Expect.size=7, Actual.size=7
[1]  :TableInfo{name='content_warning', columns={}, foreignKeys=[], indices=[]}
[7]Expect time_save=Column{name='time_save', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}
[7]Actual time_save=Column{name='time_save', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}
line is not same

@tateisu
Copy link
Author

tateisu commented Feb 4, 2023

Room側のカラム定義をNullableにして、非null値を読みたい場合のプロパティを別途定義すると先に進める

class ContentWarning(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = BaseColumns._ID) var idNullable: Long? = 0L,
    @ColumnInfo(name = COL_STATUS_URI) var uri: String = "",
    @ColumnInfo(name = COL_SHOWN) var shown: Int = 0,
    @ColumnInfo(name = COL_TIME_SAVE) var timeSaveNullable: Long? = 0,
) {
    val id get() = idNullable!!
    val timeSave get() = timeSaveNullable!!

@tateisu
Copy link
Author

tateisu commented Feb 4, 2023

スキーマ差異例外でadb logに出る内容の例

Expected:
TableInfo{name='content_warning', columns={time_save=Column{name='time_save', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, su=Column{name='su', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='undefined'}, sh=Column{name='sh', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[Index{name='content_warning_time_save', unique=false, columns=[time_save], orders=[ASC]'}, Index{name='content_warning_status_uri', unique=true, columns=[su], orders=[ASC]'}]}
Found:
TableInfo{name='content_warning', columns={_id=Column{name='_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='undefined'}, sh=Column{name='sh', type='integer', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, su=Column{name='su', type='text', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, time_save=Column{name='time_save', type='integer', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='0'}}, foreignKeys=[], indices=[Index{name='content_warning_time_save', unique=false, columns=[time_save], orders=[ASC]'}, Index{name='content_warning_status_uri', unique=true, columns=[su], orders=[ASC]'}]}

こんなん人力で読んでたらハゲるわ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment