Search code examples
androidsqlkotlinandroid-roomdatabase-migration

Room Database Migration - Bitmap


I am using the Room database, I updated my model. That's why I'm doing the migration so that the existing data is not deleted. I am trying to add a bitmap in SQL code while migrating, but I am getting an error. How can I add bitmap with SQL code?

Model:

@Entity(tableName = "person_table")
data class PersonModel(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val name: String,
    val surname: String,
    val profilePicture: Bitmap
)

Database:

@Database(entities = [PersonModel::class], version = 2, exportSchema = true)
@TypeConverters(Converter::class)
abstract class PersonDatabase : RoomDatabase() {
    abstract fun personDao(): PersonDao

    companion object {

        @Volatile
        private var INSTANCE: PersonDatabase? = null

        fun getDatabase(context: Context): PersonDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    PersonDatabase::class.java,
                    "PersonDatabase"
                ).addMigrations(MIGRATION_1_2)
                    .build()
                INSTANCE = instance
                instance
            }
        }

        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                    "ALTER TABLE person_table ADD COLUMN profilePicture BITMAP"
                )
            }
        }
    }
}

Converter:

class Converter {

    @TypeConverter
    fun fromBitmap(bitmap: Bitmap): ByteArray {
        val outputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
        return outputStream.toByteArray()
    }

    @TypeConverter
    fun toBitmap(byteArray: ByteArray): Bitmap {
        return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
    }

}

Solution

  • Room doesn't support bitmap but support BLOB type so you can use like this

    @ColumnInfo(typeAffinity = ColumnInfo.BLOB)
    val profilePicture: ByteArray? = null
    

    and add extension to convert bitmap to byte array

    fun Bitmap.toByteArray(quality: Int = 50): ByteArray {
        val stream = ByteArrayOutputStream()
        compress(Bitmap.CompressFormat.JPEG, quality, stream)
        return stream.toByteArray()
    }