使用 Kotlin 将日期字符串迁移到 Android 房间中的 Int

Migration of a Date String to an Int in Android Room with Kotlin

我需要在 Android 9.0+ 上使用 Kotlin 1.4.32 中的 Room 2.3 迁移我的数据库。在我的初始数据库中,我的日期是一个字符串(即 "2021-06-03T22:54:15.406-07:00[America/Los_Angeles]"),我想迁移它迁移期间的 to 和 Int(即 toEpochSecond)。看来我应该能够使用 SupportSQLiteDatabase.query 中的游标来遍历我的数据并进行转换,但是当我执行查询时,我的游标计数为 -1。

这是我的迁移:

val Migration_7_8 = object : Migration(7, 8) {
    override fun migrate(database: SupportSQLiteDatabase)
    {
        database.execSQL("ALTER TABLE logEntryTable ADD COLUMN dateTime INTEGER NOT NULL DEFAULT 0" )

        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryId TO id")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryAction TO 'action'")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryTime TO time")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryLatitude TO latitude")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryLongitude TO longitude")

        val cursor = database.query(SimpleSQLiteQuery("SELECT * FROM logEntryTable"))
        val idColumnIndex = cursor.getColumnIndex("id")
        val timeColumnIndex = cursor.getColumnIndex("time")

        while(!cursor.isAfterLast)
        {
            val timeStr = cursor.getString(3)
            val id = cursor.getInt(idColumnIndex)

            val time: ZonedDateTime = ZonedDateTime.parse(timeStr)

            val contentValues = ContentValues()
            contentValues.put("time", time.toEpochSecond())
            database.update("logEntryTable", SQLiteDatabase.CONFLICT_NONE, contentValues, "id=:id", arrayOf(id))

            cursor.moveToNext()
        }
    }
}

这是我迁移前的数据库:

所以事实证明(正如 Zain 在评论中指出的那样)唯一的问题是我显然必须调用 cursor.moveToNext() 来初始化游标(即移动到第一行)在我的 while 循环中使用它之前:

val Migration_7_8 = object : Migration(7, 8) {
    override fun migrate(database: SupportSQLiteDatabase)
    {
        database.execSQL("ALTER TABLE logEntryTable ADD COLUMN dateTime INTEGER NOT NULL DEFAULT 0" )

        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryId TO id")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryAction TO 'action'")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryTime TO time")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryLatitude TO latitude")
        database.execSQL("ALTER TABLE logEntryTable RENAME COLUMN logEntryLongitude TO longitude")

        val cursor = database.query(SimpleSQLiteQuery("SELECT * FROM logEntryTable"))
        val idColumnIndex = cursor.getColumnIndex("id")
        val timeColumnIndex = cursor.getColumnIndex("time")



        cursor.moveToNext()  // <======================  HERE



        while(!cursor.isAfterLast)
        {
            val timeStr = cursor.getString(3)
            val id = cursor.getInt(idColumnIndex)

            val time: ZonedDateTime = ZonedDateTime.parse(timeStr)

            val contentValues = ContentValues()
            contentValues.put("time", time.toEpochSecond())
            database.update("logEntryTable", SQLiteDatabase.CONFLICT_NONE, contentValues, "id=:id", arrayOf(id))

            cursor.moveToNext()
        }
    }
}

因此,由于光标最初没有指向任何位置 (-1),因此您需要在使用它之前将其移动到某个有效位置

要将其移动到第一个位置,您可以在 while 循环之前调用 moveToNext()