Application was always picking first participant when tapping on avatars in conversations. It was also using first participant for MMS notifications. This stores sender's phone number in the database, so it can be used to look up correct participant in the list of participants. If matching on number fails, matching on name is attempted. If both of these fail, it falls back to previous behavior, which is just picking the first participant. This may also be connected to #32, but I am not sure, since this should just be related to behavior when tapping on avatars. Mixing up avatars in the conversation should be a different issue. This closes #433, closes #500, closes #384
119 lines
5.8 KiB
Kotlin
119 lines
5.8 KiB
Kotlin
package com.simplemobiletools.smsmessenger.databases
|
|
|
|
import android.content.Context
|
|
import androidx.room.Database
|
|
import androidx.room.Room
|
|
import androidx.room.RoomDatabase
|
|
import androidx.room.TypeConverters
|
|
import androidx.room.migration.Migration
|
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
|
import com.simplemobiletools.smsmessenger.helpers.Converters
|
|
import com.simplemobiletools.smsmessenger.interfaces.AttachmentsDao
|
|
import com.simplemobiletools.smsmessenger.interfaces.ConversationsDao
|
|
import com.simplemobiletools.smsmessenger.interfaces.MessageAttachmentsDao
|
|
import com.simplemobiletools.smsmessenger.interfaces.MessagesDao
|
|
import com.simplemobiletools.smsmessenger.models.Attachment
|
|
import com.simplemobiletools.smsmessenger.models.Conversation
|
|
import com.simplemobiletools.smsmessenger.models.Message
|
|
import com.simplemobiletools.smsmessenger.models.MessageAttachment
|
|
|
|
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 7)
|
|
@TypeConverters(Converters::class)
|
|
abstract class MessagesDatabase : RoomDatabase() {
|
|
|
|
abstract fun ConversationsDao(): ConversationsDao
|
|
|
|
abstract fun AttachmentsDao(): AttachmentsDao
|
|
|
|
abstract fun MessageAttachmentsDao(): MessageAttachmentsDao
|
|
|
|
abstract fun MessagesDao(): MessagesDao
|
|
|
|
companion object {
|
|
private var db: MessagesDatabase? = null
|
|
|
|
fun getInstance(context: Context): MessagesDatabase {
|
|
if (db == null) {
|
|
synchronized(MessagesDatabase::class) {
|
|
if (db == null) {
|
|
db = Room.databaseBuilder(context.applicationContext, MessagesDatabase::class.java, "conversations.db")
|
|
.fallbackToDestructiveMigration()
|
|
.addMigrations(MIGRATION_1_2)
|
|
.addMigrations(MIGRATION_2_3)
|
|
.addMigrations(MIGRATION_3_4)
|
|
.addMigrations(MIGRATION_4_5)
|
|
.addMigrations(MIGRATION_5_6)
|
|
.addMigrations(MIGRATION_6_7)
|
|
.build()
|
|
}
|
|
}
|
|
}
|
|
return db!!
|
|
}
|
|
|
|
private val MIGRATION_1_2 = object : Migration(1, 2) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("CREATE TABLE IF NOT EXISTS `messages` (`id` INTEGER PRIMARY KEY NOT NULL, `body` TEXT NOT NULL, `type` INTEGER NOT NULL, `participants` TEXT NOT NULL, `date` INTEGER NOT NULL, `read` INTEGER NOT NULL, `thread_id` INTEGER NOT NULL, `is_mms` INTEGER NOT NULL, `attachment` TEXT, `sender_name` TEXT NOT NULL, `sender_photo_uri` TEXT NOT NULL, `subscription_id` INTEGER NOT NULL)")
|
|
|
|
execSQL("CREATE TABLE IF NOT EXISTS `message_attachments` (`id` INTEGER PRIMARY KEY NOT NULL, `text` TEXT NOT NULL, `attachments` TEXT NOT NULL)")
|
|
|
|
execSQL("CREATE TABLE IF NOT EXISTS `attachments` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message_id` INTEGER NOT NULL, `uri_string` TEXT NOT NULL, `mimetype` TEXT NOT NULL, `width` INTEGER NOT NULL, `height` INTEGER NOT NULL, `filename` TEXT NOT NULL)")
|
|
execSQL("CREATE UNIQUE INDEX `index_attachments_message_id` ON `attachments` (`message_id`)")
|
|
}
|
|
}
|
|
}
|
|
|
|
private val MIGRATION_2_3 = object : Migration(2, 3) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("CREATE TABLE conversations_new (`thread_id` INTEGER NOT NULL PRIMARY KEY, `snippet` TEXT NOT NULL, `date` INTEGER NOT NULL, `read` INTEGER NOT NULL, `title` TEXT NOT NULL, `photo_uri` TEXT NOT NULL, `is_group_conversation` INTEGER NOT NULL, `phone_number` TEXT NOT NULL)")
|
|
|
|
execSQL(
|
|
"INSERT OR IGNORE INTO conversations_new (thread_id, snippet, date, read, title, photo_uri, is_group_conversation, phone_number) " +
|
|
"SELECT thread_id, snippet, date, read, title, photo_uri, is_group_conversation, phone_number FROM conversations"
|
|
)
|
|
|
|
execSQL("DROP TABLE conversations")
|
|
|
|
execSQL("ALTER TABLE conversations_new RENAME TO conversations")
|
|
|
|
execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_conversations_id` ON `conversations` (`thread_id`)")
|
|
}
|
|
}
|
|
}
|
|
|
|
private val MIGRATION_3_4 = object : Migration(3, 4) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("ALTER TABLE messages ADD COLUMN status INTEGER NOT NULL DEFAULT -1")
|
|
}
|
|
}
|
|
}
|
|
|
|
private val MIGRATION_4_5 = object : Migration(4, 5) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("ALTER TABLE messages ADD COLUMN is_scheduled INTEGER NOT NULL DEFAULT 0")
|
|
execSQL("ALTER TABLE conversations ADD COLUMN is_scheduled INTEGER NOT NULL DEFAULT 0")
|
|
}
|
|
}
|
|
}
|
|
|
|
private val MIGRATION_5_6 = object : Migration(5, 6) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("ALTER TABLE conversations ADD COLUMN uses_custom_title INTEGER NOT NULL DEFAULT 0")
|
|
}
|
|
}
|
|
}
|
|
|
|
private val MIGRATION_6_7 = object : Migration(6, 7) {
|
|
override fun migrate(database: SupportSQLiteDatabase) {
|
|
database.apply {
|
|
execSQL("ALTER TABLE messages ADD COLUMN sender_phone_number TEXT NOT NULL DEFAULT ''")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|