本文已参与「新人创作礼」活动,一起开启掘金创作之路。
从1.0之前的版本升级
如果您仍然使用SQLDelight 0.6, 那么首先升级到0.7, 这样就可以继续使用SupportSQLite工件了
从 0.7 升级Gradle插件到 0.7.1. 这将升级 arch.persistence.db 依赖到 1.1.1, 却不会影响sqldelight的使用.
从 0.7.1 升级Gradle插件到 0.7.2. 这将把运行时的包从com.squareup.sqldelight修改成com.squareup.sqldelight.prerelease, 所以需要在代码中自行修改引用.
从 0.7.2 升级Gradle插件到 0.9.0. 这将升级可传递依赖项和生成的代码, 以使用AndroidX, 这是SQLDelight的一项要求. 这应该在你升级自己的项目到AndroidX的同时完成, 并且不能各自独立完成, 因为SQLDelight会生成引用了android support/AndroidX的代码.
要不然 在升级到 0.9.9之前, 从 0.7.2 升级Gradle插件到 0.9.0. 这将升级到AndroidX, 却没有修改 sqldelight的包名成com.squareup.sqldelight.prerelease
假定在 SQLDelight 0.9, 有这个User.sq文件:
CREATE TABLE user (
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL
);
insertDefaultData:
INSERT INTO user
VALUES (1, 'Alec');
users:
SELECT *
FROM user;
names:
SELECT name
FROM user;
insertUser:
INSERT INTO user
VALUES (?, ?);
这将生成UserModel类, 且该类有检索的方法.
从build目录下复制*Model.java文件并粘贴到src/main/java目录下.
从 0.9 升级Gradle插件到 1.0.0-rc4. 注意此时构建会失败, 因为模型代码有引用到旧SQLDelight运行时的未定义代码(比如SqlDelightStatement).要添回这个引用的话, 需要添加implementation com.squareup.sqldelight:runtime:0.9.0.
此时构建应该正在工作了, 但是.sq文件的修改并不会反射进*Model.java文件. 如果此时事件并没有正确工作的话, 请提交issue!
修改SupportSQLiteOpenHelper.Callback来调用现在生成的Database, 它将持有为SQLDelight 1.0生成的代码, 开始:
//Before
@Override void onCreate(SupportSQLiteDatabase db) {
db.execSql(UserModel.CREATE_TABLE);
db.execSql(UserModel.INSERTDEFAULTDATA);
// Other create table/initialization
}
在SQLDelight 1.0, .sq文件中所有未标识的语句(包括CREATE语句)将会在onCreate期间运行, 所以我们能够从上面的代码中移除insertDefaultData标识:
User.sq
...
--insertDefaultData:
INSERT INTO user
VALUES (1, 'Alec');
...
现在你的SupportSQLiteOpenHelper.Callback应该在create中调用Database:
@Override void onCreate(SupportSQLiteDatabase db) {
SqlDriver driver = AndroidSqliteDriver(db)
Database.Schema.create(driver)
}
如果你把迁移放入.sqm的话, 你也能做相同的操作, 但这不是升级的必要部分.
这时候事件应该依然工作正常.
后来在代码添加来创建Database, 作为图谱/单例模型/whevs的一部分:
@Provides @Singleton static SupportSQLiteOpenHelper provideDatabaseHelper(
@App Context context) {
SupportSQLiteOpenHelper.Configuration config = SupportSQLiteOpenHelper.Configuration.builder(context)
.name(DATABASE_NAME)
.callback(new MyDatabaseCallback())
.build();
return new FrameworkSQLiteOpenHelperFactory().create(config);
}
@Provides @Singleton static Database provideDatabase(
SupportSQLiteOpenHelper helper) {
return new Database(new AndroidSqliteDriver(helper));
}
如果你也在用SQL Brite, 请确保创建BriteDatabase的时候, 要使用跟创建Database时用的SupportSQLiteOpenHelper相同.
事件应该依然在工作.
接下来假设你正在使用SQL Brite从数据库获取响应式回调, 但是只使用SQLDelight的升级应该是相似的.
可变检索能够通过使用Database单独转化:
之前:
private val insertUser: UserModel.InsertUser by lazy {
UserModel.InsertUser(datbaseOpenHelper.writableDatabase)
}
insertUser.bind(2, "Jake")
insertUser.executeInsert()
之后:
database.userQueries.insertUser(2, "Jake")
你不再需要"Factory"类型执行检索, 所需要的只是检索包裹器.
之前:
val query = User.FACTORY.users()
val usersObservable = briteDatabase.createQuery(query.tables, query.statement, query.args)
.mapToList(User.FACTORY.usersMapper()::map)
之后:
val usersObservable = database.userQueries.users()
.asObservable(Schedulers.io()) // The scheduler to run the query on.
.mapToList()
如果你依然想要使用自定义类型, 请将自定义类型以参数的形式传递给检索.
val myUsersObservable = database.userQueries.users(::MyUser)
.asObservable(Schedulers.io())
.mapToList()
一旦你不再引用UserModel.java, 一定要删除整个类. 为每一个*Model.java文件重复这个操作直到升级完成!