Skip to content

Upgrading from Versions before 1.0

If you're still on SQLDelight 0.6 doing the upgrade to 0.7 first so you stay on the SupportSQLite artifact will likely be easiest

Upgrade the gradle plugin from 0.7 to 0.7.1. This will upgrade the arch.persistence.db dependency to 1.1.1, but should have no effect on your usage of sqldelight.

Upgrade the gradle plugin from 0.7.1 to 0.7.2. This changes the runtime package from com.squareup.sqldelight to com.squareup.sqldelight.prerelease, so you will need to change references in your own code.

Upgrade the gradle plugin from 0.7.2 to 0.9.0. This upgrades the transitive dependencies and generated code to instead use AndroidX, which is a requirement of SQLDelight. This should be done at the same time as you upgrading your own project to AndroidX, and cannot be done separately since SQLDelight generates code which references android support/AndroidX.

ALTERNATIVELY Upgrade the gradle plugin from 0.7 to 0.8.0 before then upgrading to 0.9.0. This upgrades to AndroidX without changing the sqldelight package name to com.squareup.sqldelight.prerelease

Suppose on SQLDelight 0.9 you have this User.sq file:

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 (?, ?);

This will generate the UserModel class with methods for your queries.

Copy and paste all *Model.java files out of the build directory and into your src/main/java folder.

Upgrade the gradle plugin from 0.9 to 1.0.0-rc4. Note your build will fail at this point because of the model code having undefined references to the old SQL Delight runtime (like SqlDelightStatement). To add these back in add an implementation dependency on com.squareup.sqldelight:runtime:0.9.0.

At this point your build should still be working, but changes to .sq files will not be reflected in your *Model.java files. If things aren't working at this point, please file an issue!

Begin by modifying your SupportSQLiteOpenHelper.Callback to call into the now generated Database which holds generated code for SQL Delight 1.0:

//Before
@Override void onCreate(SupportSQLiteDatabase db) {
  db.execSql(UserModel.CREATE_TABLE);
  db.execSql(UserModel.INSERTDEFAULTDATA);
  // Other create table/initialization
}

In SQL Delight 1.0 all unlabeled statements in .sq files (including CREATE statements) will be run during onCreate, so we can remove the insertDefaultData identifier from above:

User.sq

...

--insertDefaultData:
INSERT INTO user
VALUES (1, 'Alec');

...

and now your SupportSQLiteOpenHelper.Callback should call into the Database for create

@Override void onCreate(SupportSQLiteDatabase db) {
  SqlDriver driver = AndroidSqliteDriver(db)
  Database.Schema.create(driver)
}

You can do the same for your migrations if you place them in .sqm files, but thats not necessary part of the upgrade.

At this point things should still work normally.

Next add in the code to create your Database as part of an object graph/singleton pattern/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));
}

If you're also using SQL Brite make sure you create a BriteDatabase with the same SupportSQLiteOpenHelper that's being used to create the Database.

Things should still be working.

The following assume you're using SQL Brite to get reactive callbacks from the database, but upgrades using only SQL Delight will be similar.

Mutating queries can be converted individually by using the Database:

before:

private val insertUser: UserModel.InsertUser by lazy {
  UserModel.InsertUser(datbaseOpenHelper.writableDatabase)
}

insertUser.bind(2, "Jake")
insertUser.executeInsert()

after:

database.userQueries.insertUser(2, "Jake")

You no longer need a "Factory" type to perform queries, the query wrapper is all that is needed.

before:

val query = User.FACTORY.users()
val usersObservable = briteDatabase.createQuery(query.tables, query.statement, query.args)
  .mapToList(User.FACTORY.usersMapper()::map)

after:

val usersObservable = database.userQueries.users()
  .asObservable(Schedulers.io()) // The scheduler to run the query on.
  .mapToList()

If you still want to use a custom type, pass it as a parameter to the query.

val myUsersObservable = database.userQueries.users(::MyUser)
  .asObservable(Schedulers.io())
  .mapToList()

Once you no longer have references to UserModel.java, delete the whole class. Repeat for each of your *Model.java files until upgrading is complete!