Search code examples
android-studiokotlinmigrationandroid-room

Drop column Room migration android


I have a table Server

@Entity(tableName = "servers")
data class ServerDto(

    @PrimaryKey
    @ColumnInfo(name = "server_id")
    var serverId: Long,

    @ColumnInfo(name = "address", defaultValue = "")
    var serverAddress: String,

    @ColumnInfo(name = "description", defaultValue = "")
    var serverDescription: String,

    @ColumnInfo(name = "file_segment")
    var fileSegment: Int

) : Serializable

and a table accounts

@Entity(tableName = "accounts", primaryKeys = ["server_id", "account_id"])
data class AccountDto(

    @ColumnInfo(name = "server_id")
    val serverId: Long,

    @ColumnInfo(name = "account_id")
    val accountId: Int,

  @ColumnInfo(name = "username", defaultValue = "")
    val username: String,

    @ColumnInfo(name = "password", defaultValue = "")
    val password: String,

    @ColumnInfo(name = "first_name", defaultValue = "")
    var firstname: String,

    @ColumnInfo(name = "last_name", defaultValue = "")
    var lastname: String,

    @ColumnInfo(name = "email", defaultValue = "")
    var email: String,

    @ColumnInfo(name = "active")
    var active: Int

) : Serializable

I want to transfer 2 columns (username, password) from accounts to server and then remove them from accounts. I wrote the Migrations but i see that Android Studio does not allow to write DROP COLUMN since it underlines it with red. What is wrong with that??

override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE servers ADD COLUMN username VARCHAR")
        database.execSQL("ALTER TABLE servers ADD COLUMN password VARCHAR")
        database.execSQL("UPDATE servers SET username = (SELECT a.username FROM accounts a where a.server_id = servers.server_id and a.active = 1)")
        database.execSQL("UPDATE servers SET password = (SELECT a.password FROM accounts a where a.server_id = servers.server_id and a.active = 1)")
        database.execSQL("ALTER TABLE accounts ***DROP*** COLUMN username")
        database.execSQL("ALTER TABLE accounts ***DROP*** COLUMN password")
    }

Solution

  • SQLite doesn't support column deletion straight away. You will have to do migration steps as follows: Source: https://www.sqlite.org/faq.html#q11

    CREATE TABLE accounts_backup(serverId VARCHAR, accountId VARCHAR, firstname VARCHAR, lastname VARCHAR, email VARCHAR, active VARCHAR);
    
    INSERT INTO accounts_backup SELECT serverId, accountId, firstname, lastname, email, active FROM accounts;
    
    DROP TABLE accounts;
    
    CREATE TABLE accounts(serverId VARCHAR, accountId VARCHAR, firstname VARCHAR, lastname VARCHAR, email VARCHAR, active VARCHAR);
    
    INSERT INTO accounts SELECT serverId, accountId, firstname, lastname, email, active FROM accounts_backup;
    
    DROP TABLE accounts_backup;