简体   繁体   中英

How to manually invoke CREATE TABLE when using Room?

Given this custom SQLiteOpenHelper in Java:

public class ExamplesOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "app.db";

    private static final String CREATE_TABLE_STATEMENT =
            "CREATE TABLE examples (_id INTEGER PRIMARY KEY, NAME TEXT);";

    public ExamplesOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_STATEMENT);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS examples");
        onCreate(db);
    }
}

I can reference the CREATE_TABLE_STATEMENT in an database migration aka. onUpgrade() without duplicating the SQL code.

I would like to implement the same with Kotlin and Room as shown here:

@Database(
        entities = [
            (Example::class)
        ],
        version = 2
)
abstract class ExamplesDatabase : RoomDatabase() {

    companion object {

        const val NAME = "examples"

        @Volatile
        private var INSTANCE: ExamplesDatabase? = null

        @JvmStatic
        fun getInstance(context: Context): ExamplesDatabase =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: buildDatabase(context).also {
                        INSTANCE = it
                    }
                }

        private fun buildDatabase(context: Context) =
                Room.databaseBuilder(
                        context.applicationContext,
                        ExamplesDatabase::class.java,
                        NAME)
                        .addMigrations(MIGRATION_1_2)
                        .build()

        private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(db: SupportSQLiteDatabase) {
                // How to invoke CREATE TABLE here?
            }
        }

    }

}

This time the actual table definition is infered from the Example model. How can I infer the CREATE_TABLE_STATEMENT from Room so I can use it in an migration? I want to avoid writing the statement manually and thereby defining it twice : once in the model, one in the SQL statement.

No, I don't think there is a way to do that. See the official tutorial .

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");
    }
};

It seems that you have to write it yourself.

您可以从类“ExamplesDatabase_Impl.java”中找到create table SQL,没有CREATE_TABLE_STATEMENT定义,只有硬代码。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM