Android SQLDelight (七) 从 Room 迁移的改造点

文章目录

    继续将原有的 Compose 项目重写为 XML View,本来不想折腾,心想要不直接沿用原来的 Room 代码,但是看了 DAO 和 Repository 这种风格的代码,还是忍不了。

    既然没有退路了,就得保证对历史数据的兼容。

    数据库名称

    注意,用 SQLDelight 指定数据库名称时,不要加 .db 后缀。否则跟之前 Room 生成的文件名不一致。

    -  val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database.db")
    +  val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database")
    

    Version Error

    SQLDelight 不像 Room 可以通过注解参数指定数据库版本号。所以在手机上测试升级时,会报一个运行时错误,直接导致 app 崩溃:

    android.database.sqlite.SQLiteException: Can’t downgrade database from version 5 to 1

    之前的 Room db version 为 5,看来 SQLDelight 默认为 1。

    @Database(entities = [Item::class], version = 5, exportSchema = false)
    @TypeConverters(Converters::class)
    abstract class ItemDatabase : RoomDatabase() {
        abstract fun itemDao(): ItemDao
    
    	// ...
    }
    

    如何设置 SQLDelight 数据库版本号

    下面是一个可行的方案:

    在与 data 的同级目录,创建一个 migrations 目录,然后创建 4 个 sqm migration 文件。
    可以参考 Room 之前的 migration 操作生成每个文件的内容,
    但我的情况特殊,第五版是我的第一个 release 版本,所以直接创建了 4 个空的 sqm 文件。

    app/src/main/sqldelight/com/sunzhongwei/someapp/
    ├── data
    │   └── Item.sq
    └── migrations
        ├── 1.sqm
        ├── 2.sqm
        ├── 3.sqm
        └── 4.sqm
    

    SQLDelight 的数据库版本号,由最大的 sqm 文件名决定,即,N.sqm 代表当前版本号为 N + 1。

    例如:

    有 4 个 .sqm 文件,代表当前 database 的版本号是 5。

    打印版本号

    println("database version is: " + Database.Schema.version)
    val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database")
    

    database version is: 5

    注意:

    不能直接修改 Database.Schema.version,因为 version 是 val 类型的,不可修改。

    探索更多关于 SQLDelight

    📖 Android Room 替代品 SQLDelight 中文入门教程

    参考

    • https://medium.com/xorum-io/migration-from-room-to-sqldelight-28d6f4aaf31e
    • https://cashapp.github.io/sqldelight/2.0.0-alpha05/android_sqlite/migrations/

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式