Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 578
JJD Avatar asked Jan 23 '18 23:01

JJD


People also ask

How do I create a table for my database?

To create a table for your database, follow these steps: Step 1: Add the createTable Change Type to your changeset with the needed attribute s as it is shown in the examples.

How do I create a table in a changeset?

To create a table for your database, follow these steps: Step 1: Add the createTable Change Type to your changeset with the needed attribute s as it is shown in the examples. Step 2: Deploy your changeset by running the update command.

What is the use of CreateTable change type?

The createTable Change Type creates a table. You can typically use the createTable Change Type when you want to create a table in your changelog file and then deploy it to your database. It can include columns and another values listed in this documentation.

How to create a table in a changeLog File?

You can typically use the createTable Change Type when you want to create a table in your changelog file and then deploy it to your database. It can include columns and another values listed in this documentation.


2 Answers

You can find create table SQL from class "ExamplesDatabase_Impl.java", there is no CREATE_TABLE_STATEMENT define, only hard code.

like image 168
sunwei Avatar answered Oct 11 '22 23:10

sunwei


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.

like image 30
Joshua Avatar answered Oct 12 '22 00:10

Joshua